diff --git a/Makefile.common b/Makefile.common
index e53c3b7c23..0b2889f0b2 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -177,7 +177,6 @@ OBJ += frontend/frontend_driver.o \
        $(LIBRETRO_COMM_DIR)/streams/interface_stream.o \
        $(LIBRETRO_COMM_DIR)/streams/memory_stream.o \
        $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.o \
-       $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation_cdrom.o \
        $(LIBRETRO_COMM_DIR)/media/media_detect_cd.o \
        $(LIBRETRO_COMM_DIR)/lists/string_list.o \
        $(LIBRETRO_COMM_DIR)/string/stdstring.o \
@@ -1668,7 +1667,8 @@ ifeq ($(HAVE_CDROM), 1)
    endif
 
    DEFINES += -DHAVE_CDROM
-   OBJ += $(LIBRETRO_COMM_DIR)/cdrom/cdrom.o
+   OBJ += $(LIBRETRO_COMM_DIR)/cdrom/cdrom.o \
+       $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation_cdrom.o
 endif
 
 ifeq ($(HAVE_RTGA), 1)
diff --git a/cheevos-new/cheevos.c b/cheevos-new/cheevos.c
index 927ce8735a..caf85fbc94 100644
--- a/cheevos-new/cheevos.c
+++ b/cheevos-new/cheevos.c
@@ -1118,8 +1118,6 @@ typedef struct
    const char *path;
    const char *ext;
    intfstream_t *stream;
-   intfstream_t *cdrom_stream;
-   intfstream_t *cdrom_track_stream;
    rcheevos_cheevo_t *cheevo;
    settings_t *settings;
    struct http_connection_t *conn;
@@ -1148,8 +1146,7 @@ enum
    RCHEEVOS_HTTP_GET     = -13,
    RCHEEVOS_DEACTIVATE   = -14,
    RCHEEVOS_PLAYING      = -15,
-   RCHEEVOS_DELAY        = -16,
-   RCHEEVOS_PSX_MD5      = -17
+   RCHEEVOS_DELAY        = -16
 };
 
 static int rcheevos_iterate(rcheevos_coro_t* coro)
@@ -1158,14 +1155,8 @@ static int rcheevos_iterate(rcheevos_coro_t* coro)
    const int lynx_header_len = 0x40;
    ssize_t num_read = 0;
    size_t to_read   = 4096;
-   uint8_t *ptr     = NULL;
+   uint8_t *buffer  = NULL;
    const char *end  = NULL;
-   const char *ext  = NULL;
-   size_t exe_name_size = 0;
-   char exe_name_buffer[32];
-   char *exe_name   = NULL;
-   char *scan       = NULL;
-   char buffer[2048];
 
    static const uint32_t genesis_exts[] =
    {
@@ -1201,24 +1192,12 @@ static int rcheevos_iterate(rcheevos_coro_t* coro)
       0
    };
 
-   static const uint32_t psx_exts[] =
-   {
-      0x0b886782U, /* cue */
-      0x0b88899aU, /* m3u */
-      /*0x0b88af0bU,* toc */
-      /*0x0b88652fU,* ccd */
-      /*0x0b889c67U,* pbp */
-      0x0b8865d4U, /* chd */
-      0
-   };
-
    static rcheevos_finder_t finders[] =
    {
       {RCHEEVOS_SNES_MD5,    "SNES (discards header)",            snes_exts},
       {RCHEEVOS_GENESIS_MD5, "Genesis (6Mb padding)",             genesis_exts},
-      {RCHEEVOS_LYNX_MD5,    "Atari Lynx (discards header)",      lynx_exts},
+      {RCHEEVOS_LYNX_MD5,    "Atari Lynx (discards header)", lynx_exts},
       {RCHEEVOS_NES_MD5,     "NES (discards header)",             NULL},
-      {RCHEEVOS_PSX_MD5,     "Playstation (main executable)",     psx_exts},
       {RCHEEVOS_GENERIC_MD5, "Generic (plain content)",           NULL},
       {RCHEEVOS_FILENAME_MD5, "Generic (filename)",               NULL}
    };
@@ -1264,13 +1243,14 @@ static int rcheevos_iterate(rcheevos_coro_t* coro)
 
          for (;;)
          {
-            ptr      = (uint8_t*)coro->data + coro->len;
+            buffer   = (uint8_t*)coro->data + coro->len;
             to_read  = 4096;
 
             if (to_read > coro->count)
                to_read = coro->count;
 
-            num_read = intfstream_read(coro->stream, (void*)ptr, to_read);
+            num_read = intfstream_read(coro->stream,
+                  (void*)buffer, to_read);
 
             if (num_read <= 0)
                break;
@@ -1565,186 +1545,6 @@ found:
       MD5_Final(coro->hash, &coro->md5);
       CORO_GOTO(RCHEEVOS_GET_GAMEID);
 
-      /**************************************************************************
-       * Info   Tries to identify a Playstation game
-         * Input  CHEEVOS_VAR_INFO the content info
-         * Output CHEEVOS_VAR_GAMEID the Retro Achievements game ID, or 0 if not found
-         *************************************************************************/
-   CORO_SUB(RCHEEVOS_PSX_MD5)
-   {
-      ext = path_get_extension(coro->path);
-
-      MD5_Init(&coro->md5);
-
-      /* if we're looking at an m3u file, get the first disc from the playlist */
-      if (string_is_equal_noncase(ext, "m3u"))
-      {
-         coro->cdrom_stream = intfstream_open_file(coro->path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
-         if (coro->cdrom_stream)
-         {
-            char disc_path[PATH_MAX_LENGTH];
-            char* tmp;
-
-            intfstream_read(coro->cdrom_stream, buffer, sizeof(buffer));
-            intfstream_close(coro->cdrom_stream);
-            CHEEVOS_FREE(coro->cdrom_stream);
-            coro->cdrom_stream = NULL;
-
-            tmp = buffer;
-            while (*tmp && *tmp != '\n')
-               ++tmp;
-            if (tmp > buffer && tmp[-1] == '\r')
-               --tmp;
-            *tmp = '\0';
-
-            fill_pathname_basedir(disc_path, coro->path, sizeof(disc_path));
-            strlcat(disc_path, buffer, sizeof(disc_path));
-
-            free((void*)coro->path);
-            coro->path = strdup(disc_path);
-            ext = path_get_extension(coro->path);
-         }
-      }
-
-      if (string_is_equal_noncase(ext, "chd"))
-      {
-         coro->cdrom_track_stream = intfstream_open_chd_track(coro->path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE, 1);
-      }
-      else
-      {
-         coro->cdrom_stream = intfstream_open_file(coro->path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
-         if (!coro->cdrom_stream)
-            CORO_STOP();
-
-         coro->cdrom_track_stream = intfstream_open_file_child(coro->cdrom_stream, "TRACK 01");
-      }
-
-      if (coro->cdrom_track_stream)
-      {
-         coro->stream = intfstream_open_file_child(coro->cdrom_track_stream, "SYSTEM.CNF");
-         if (coro->stream)
-         {
-            intfstream_read(coro->stream, buffer, sizeof(buffer));
-            intfstream_close(coro->stream);
-            CHEEVOS_FREE(coro->stream);
-            coro->stream = NULL;
-
-            for (scan = buffer; scan < &buffer[sizeof(buffer)] && *scan; ++scan)
-            {
-               if (strncmp(scan, "BOOT", 4) == 0)
-               {
-                  exe_name = scan + 4;
-                  while (isspace(*exe_name))
-                     ++exe_name;
-                  if (*exe_name == '=')
-                  {
-                     ++exe_name;
-                     while (isspace(*exe_name))
-                        ++exe_name;
-
-                     if (strncmp(exe_name, "cdrom:", 6) == 0)
-                        exe_name += 6;
-                     if (*exe_name == '\\')
-                        ++exe_name;
-                     break;
-                  }
-               }
-
-               while (*scan && *scan != '\n')
-                  ++scan;
-            }
-
-            if (exe_name)
-            {
-               scan = exe_name;
-               while (*scan != '\n' && *scan != ';' && *scan != ' ')
-                  ++scan;
-               *scan = '\0';
-
-               exe_name_size = scan - exe_name;
-               if (exe_name_size < sizeof(exe_name_buffer))
-               {
-                  strcpy(exe_name_buffer, exe_name);
-                  coro->stream = intfstream_open_file_child(coro->cdrom_track_stream, exe_name);
-               }
-
-               if (coro->stream)
-               {
-                  intfstream_read(coro->stream, buffer, sizeof(buffer));
-
-                  /* the PSX-E header specifies the executable size as a 4-byte value 28 bytes into the header, which doesn't
-                   * include the header itself. We want to include the header in the hash, so append another 2048 to that value.
-                   * ASSERT: this results in the same value as coro->stream->file.fp->size */
-                  coro->count = 2048 + (((uint8_t)buffer[28 + 3] << 24) | ((uint8_t)buffer[28 + 2] << 16) |
-                                        ((uint8_t)buffer[28 + 1] << 8) | (uint8_t)buffer[28]);
-
-                  if (coro->count < CHEEVOS_MB(16)) /* sanity check */
-                  {
-                     /* there's also a few games that are use a singular engine and only differ via their data files.
-                      * luckily, they have unique serial numbers, and use the serial number as the boot file in the
-                      * standard way. include the boot executable name in the hash */
-                     coro->count += exe_name_size;
-
-                     free(coro->data);
-                     coro->data = (uint8_t*)malloc(coro->count);
-                     memcpy(coro->data, exe_name_buffer, exe_name_size);
-                     coro->len = exe_name_size;
-
-                     do
-                     {
-                        to_read = coro->count - coro->len;
-                        if (to_read > sizeof(buffer))
-                           to_read = sizeof(buffer);
-
-                        memcpy((uint8_t*)coro->data + coro->len, buffer, to_read);
-                        coro->len += to_read;
-
-                        if (coro->len == coro->count)
-                           break;
-
-                        CORO_YIELD();
-
-                        intfstream_read(coro->stream, buffer, sizeof(buffer));
-                     } while (true);
-
-                     CORO_GOSUB(RCHEEVOS_EVAL_MD5);
-                     MD5_Final(coro->hash, &coro->md5);
-
-                     intfstream_close(coro->stream);
-                     CHEEVOS_FREE(coro->stream);
-
-                     intfstream_close(coro->cdrom_track_stream);
-                     CHEEVOS_FREE(coro->cdrom_track_stream);
-
-                     if (coro->cdrom_stream)
-                     {
-                        intfstream_close(coro->cdrom_stream);
-                        CHEEVOS_FREE(coro->cdrom_stream);
-                     }
-
-                     CORO_GOTO(RCHEEVOS_GET_GAMEID);
-                  }
-               }
-            }
-
-            intfstream_close(coro->stream);
-            CHEEVOS_FREE(coro->stream);
-         }
-
-         intfstream_close(coro->cdrom_track_stream);
-         CHEEVOS_FREE(coro->cdrom_track_stream);
-      }
-
-      if (coro->cdrom_stream)
-      {
-         intfstream_close(coro->cdrom_stream);
-         CHEEVOS_FREE(coro->cdrom_stream);
-      }
-
-      coro->gameid = 0;
-      CORO_RET();
-   }
-
       /**************************************************************************
        * Info   Tries to identify a "generic" game
          * Input  CHEEVOS_VAR_INFO the content info
@@ -1840,11 +1640,6 @@ found:
 
       {
          int size;
-
-         CHEEVOS_LOG(RCHEEVOS_TAG "checking hash %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-            coro->hash[ 0], coro->hash[ 1], coro->hash[ 2], coro->hash[ 3], coro->hash[ 4], coro->hash[ 5], coro->hash[ 6], coro->hash[ 7],
-            coro->hash[ 8], coro->hash[ 9], coro->hash[10], coro->hash[11], coro->hash[12], coro->hash[13], coro->hash[14], coro->hash[15]);
-
          size = rc_url_get_gameid(coro->url, sizeof(coro->url), coro->hash);
 
          if (size < 0)
diff --git a/cheevos-new/parser.c b/cheevos-new/parser.c
index b28ac7b20e..eed9a88ecb 100644
--- a/cheevos-new/parser.c
+++ b/cheevos-new/parser.c
@@ -550,8 +550,8 @@ Frees the patchdata
 void rcheevos_free_patchdata(rcheevos_rapatchdata_t* patchdata)
 {
    unsigned i = 0, count = 0;
-   rcheevos_racheevo_t* cheevo = NULL;
-   rcheevos_ralboard_t* lboard = NULL;
+   const rcheevos_racheevo_t* cheevo = NULL;
+   const rcheevos_ralboard_t* lboard = NULL;
 
    cheevo = patchdata->core;
 
diff --git a/cheevos-new/util.h b/cheevos-new/util.h
index fbd882b66a..1794ef3ebb 100644
--- a/cheevos-new/util.h
+++ b/cheevos-new/util.h
@@ -32,12 +32,7 @@ End of setup
 *****************************************************************************/
 
 #define RCHEEVOS_TAG "[RCHEEVOS]: "
-
-#ifdef _DEBUG
-#define CHEEVOS_FREE(p) do { void* q = (void*)p; p = NULL; if (q != NULL) free(q); } while (0)
-#else
 #define CHEEVOS_FREE(p) do { void* q = (void*)p; if (q != NULL) free(q); } while (0)
-#endif
 
 #ifdef CHEEVOS_VERBOSE
 
diff --git a/griffin/griffin.c b/griffin/griffin.c
index 40e59a643a..dd834caebd 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -973,11 +973,11 @@ FILE
 #include "../libretro-common/streams/memory_stream.c"
 #ifndef __WINRT__
 #include "../libretro-common/vfs/vfs_implementation.c"
-#include "../libretro-common/vfs/vfs_implementation_cdrom.c"
 #endif
 
 #ifdef HAVE_CDROM
 #include "../libretro-common/cdrom/cdrom.c"
+#include "../libretro-common/vfs/vfs_implementation_cdrom.c"
 #include "../libretro-common/media/media_detect_cd.c"
 #endif
 
diff --git a/libretro-common/cdrom/cdrom.c b/libretro-common/cdrom/cdrom.c
index 1909fb6556..cb5ff8c110 100644
--- a/libretro-common/cdrom/cdrom.c
+++ b/libretro-common/cdrom/cdrom.c
@@ -301,7 +301,7 @@ static int cdrom_send_command_win32(const libretro_vfs_implementation_file *stre
 
    memcpy(sptd.s.Cdb, cmd, cmd_len);
 
-   ioctl_rv = DeviceIoControl(stream->parent ? stream->parent->fh : stream->fh, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd,
+   ioctl_rv = DeviceIoControl(stream->fh, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd,
       sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL);
 
 #ifdef CDROM_DEBUG
@@ -313,8 +313,7 @@ static int cdrom_send_command_win32(const libretro_vfs_implementation_file *stre
    if (cmd[0] == 0xB9)
    {
       double time_taken = (double)(((clock() - t) * 1000) / CLOCKS_PER_SEC);
-      printf("time taken %f ms for DT received length %ld of %" PRId64 " for %02d:%02d:%02d to %02d:%02d:%02d%s req %d cur %d cur_lba %d\n",
-         time_taken, sptd.s.DataTransferLength, len, cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], extra, lba_req, lba_cur, stream->track ? stream->track->cur_lba : -1);
+      printf("time taken %f ms for DT received length %ld of %" PRId64 " for %02d:%02d:%02d to %02d:%02d:%02d%s req %d cur %d cur_lba %d\n", time_taken, sptd.s.DataTransferLength, len, cmd[3], cmd[4], cmd[5], cmd[6], cmd[7], cmd[8], extra, lba_req, lba_cur, stream->cdrom.cur_lba);
       fflush(stdout);
    }
 
@@ -360,7 +359,7 @@ static int cdrom_send_command_linux(const libretro_vfs_implementation_file *stre
    sgio.mx_sb_len = sense_len;
    sgio.timeout = 5000;
 
-   rv = ioctl(fileno(stream->parent ? stream->parent->fp : stream->fp), SG_IO, &sgio);
+   rv = ioctl(fileno(stream->fp), SG_IO, &sgio);
 
    if (rv == -1 || sgio.info & SG_INFO_CHECK)
       return 1;
@@ -443,7 +442,7 @@ static int cdrom_send_command(libretro_vfs_implementation_file *stream, CDROM_CM
 
          lba_req = cdrom_msf_to_lba(cmd[3], cmd[4], cmd[5]);
 
-         if (lba_req == stream->track->last_frame_lba)
+         if (stream->cdrom.last_frame_valid && lba_req == stream->cdrom.last_frame_lba)
          {
             /* use cached frame */
             cached_read = true;
@@ -452,7 +451,7 @@ static int cdrom_send_command(libretro_vfs_implementation_file *stream, CDROM_CM
             fflush(stdout);
 #endif
             /* assumes request_len is always equal to the size of last_frame */
-            memcpy(xfer_buf_pos, stream->track->last_frame, sizeof(stream->track->last_frame));
+            memcpy(xfer_buf_pos, stream->cdrom.last_frame, sizeof(stream->cdrom.last_frame));
          }
 
       }
@@ -498,20 +497,18 @@ retry:
             memcpy((char*)buf + copied_bytes, xfer_buf_pos + skip, copy_len);
             copied_bytes += copy_len;
 
-            if (stream->track)
+            if (read_cd && !cached_read && request_len >= 2352)
             {
-               if (read_cd && !cached_read && request_len >= 2352)
-               {
-                  unsigned frame_end = cdrom_msf_to_lba(cmd[6], cmd[7], cmd[8]);
+               unsigned frame_end = cdrom_msf_to_lba(cmd[6], cmd[7], cmd[8]);
 
-                  /* cache the last received frame */
-                  memcpy(stream->track->last_frame, xfer_buf_pos, sizeof(stream->track->last_frame));
-                  /* the ending frame is never actually read, so what we really just read is the one right before that */
-                  stream->track->last_frame_lba = frame_end - 1;
-               }
-               else
-                  stream->track->last_frame_lba = (unsigned)-1;
+               /* cache the last received frame */
+               memcpy(stream->cdrom.last_frame, xfer_buf_pos, sizeof(stream->cdrom.last_frame));
+               stream->cdrom.last_frame_valid = true;
+               /* the ending frame is never actually read, so what we really just read is the one right before that */
+               stream->cdrom.last_frame_lba = frame_end - 1;
             }
+            else
+               stream->cdrom.last_frame_valid = false;
 
 #if 0
             printf("Frame %d, adding %" PRId64 " to buf_pos, is now %" PRId64 ". skip is %" PRId64 "\n", i, request_len, (xfer_buf_pos + request_len) - xfer_buf, skip);
@@ -1234,7 +1231,7 @@ int cdrom_read(libretro_vfs_implementation_file *stream, cdrom_group_timeouts_t
 
    if (rv)
    {
-      stream->track->last_frame_lba = (unsigned)-1;
+      stream->cdrom.last_frame_valid = false;
       return 1;
    }
 
@@ -1431,7 +1428,7 @@ struct string_list* cdrom_get_available_drives(void)
    for (i = 0; i < sizeof(DWORD) * 8; i++)
    {
       char path[] = {"a:\\"};
-      char cdrom_path[] = {"cdrom://a:/drive.cue"};
+      char cdrom_path[] = {"cdrom://a:/drive-track01.bin"};
 
       path[0] += i;
       cdrom_path[8] += i;
@@ -1447,16 +1444,16 @@ struct string_list* cdrom_get_available_drives(void)
          char drive_model[32] = {0};
          char drive_string[33] = {0};
          union string_list_elem_attr attr = {0};
-         RFILE *cdrom_file = filestream_open(cdrom_path, RETRO_VFS_FILE_ACCESS_READ, 0);
+         RFILE *file = filestream_open(cdrom_path, RETRO_VFS_FILE_ACCESS_READ, 0);
+         libretro_vfs_implementation_file *stream;
          bool is_cdrom = false;
 
-         if (cdrom_file)
-         {
-            libretro_vfs_implementation_file* stream = filestream_get_vfs_handle(cdrom_file);
-            cdrom_get_inquiry(stream, drive_model, sizeof(drive_model), &is_cdrom);
+         if (!file)
+            continue;
 
-            filestream_close(cdrom_file);
-         }
+         stream = filestream_get_vfs_handle(file);
+         cdrom_get_inquiry(stream, drive_model, sizeof(drive_model), &is_cdrom);
+         filestream_close(file);
 
          if (!is_cdrom)
             continue;
diff --git a/libretro-common/formats/libchdr/libchdr_chd.c b/libretro-common/formats/libchdr/libchdr_chd.c
index fd48b9e87d..3e3de49c26 100644
--- a/libretro-common/formats/libchdr/libchdr_chd.c
+++ b/libretro-common/formats/libchdr/libchdr_chd.c
@@ -1037,10 +1037,6 @@ void chd_close(chd_file *chd)
 		for (i = 0 ; i < 4 ; i++)
       {
          void* codec = NULL;
-
-         if (!chd->codecintf[i])
-            continue;
-
          switch (chd->codecintf[i]->compression)
          {
             case CHD_CODEC_CD_LZMA:
diff --git a/libretro-common/include/streams/chd_stream.h b/libretro-common/include/streams/chd_stream.h
index 7fde65b386..246a2dcfc9 100644
--- a/libretro-common/include/streams/chd_stream.h
+++ b/libretro-common/include/streams/chd_stream.h
@@ -45,28 +45,16 @@ void chdstream_close(chdstream_t *stream);
 
 ssize_t chdstream_read(chdstream_t *stream, void *data, size_t bytes);
 
-ssize_t chdstream_read_file(chdstream_t *stream, int64_t file_start, void *data, size_t bytes);
-
 int chdstream_getc(chdstream_t *stream);
 
-int chdstream_getc_file(chdstream_t *stream, int64_t file_start);
-
 char *chdstream_gets(chdstream_t *stream, char *buffer, size_t len);
 
-char *chdstream_gets_file(chdstream_t *stream, int64_t file_start, char *buffer, size_t len);
-
 uint64_t chdstream_tell(chdstream_t *stream);
 
-uint64_t chdstream_tell_file(chdstream_t *stream, int64_t file_start);
-
 void chdstream_rewind(chdstream_t *stream);
 
-void chdstream_rewind_file(chdstream_t *stream, int64_t file_start);
-
 int64_t chdstream_seek(chdstream_t *stream, int64_t offset, int whence);
 
-int64_t chdstream_seek_file(chdstream_t* stream, const char* filename);
-
 ssize_t chdstream_get_size(chdstream_t *stream);
 
 RETRO_END_DECLS
diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h
index 64b7afbb25..0cfadad83c 100644
--- a/libretro-common/include/streams/file_stream.h
+++ b/libretro-common/include/streams/file_stream.h
@@ -63,8 +63,6 @@ int64_t filestream_truncate(RFILE *stream, int64_t length);
  **/
 RFILE* filestream_open(const char *path, unsigned mode, unsigned hints);
 
-RFILE* filestream_open_child(RFILE *stream, const char* path);
-
 int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position);
 
 int64_t filestream_read(RFILE *stream, void *data, int64_t len);
diff --git a/libretro-common/include/streams/interface_stream.h b/libretro-common/include/streams/interface_stream.h
index aeec984272..ec480c6624 100644
--- a/libretro-common/include/streams/interface_stream.h
+++ b/libretro-common/include/streams/interface_stream.h
@@ -36,8 +36,7 @@ enum intfstream_type
 {
    INTFSTREAM_FILE = 0,
    INTFSTREAM_MEMORY,
-   INTFSTREAM_CHD,
-   INTFSTREAM_CHD_FILE
+   INTFSTREAM_CHD
 };
 
 typedef struct intfstream_internal intfstream_internal_t, intfstream_t;
@@ -98,9 +97,6 @@ int intfstream_flush(intfstream_internal_t *intf);
 intfstream_t* intfstream_open_file(const char *path,
       unsigned mode, unsigned hints);
 
-intfstream_t* intfstream_open_file_child(intfstream_internal_t *intf,
-      const char* path);
-
 intfstream_t *intfstream_open_memory(void *data,
       unsigned mode, unsigned hints, uint64_t size);
 
diff --git a/libretro-common/include/vfs/vfs.h b/libretro-common/include/vfs/vfs.h
index 2f24597c82..b876f438b6 100644
--- a/libretro-common/include/vfs/vfs.h
+++ b/libretro-common/include/vfs/vfs.h
@@ -38,40 +38,28 @@ RETRO_BEGIN_DECLS
 typedef void* HANDLE;
 #endif
 
+#ifdef HAVE_CDROM
 typedef struct
 {
-   char* cue_buf;
+   char *cue_buf;
    size_t cue_len;
-   size_t cue_pos;
-   char drive;
-} vfs_cdrom_t;
-
-typedef struct
-{
    int64_t byte_pos;
-   unsigned cur_lba;
-   unsigned char cur_track;
+   char drive;
    unsigned char cur_min;
    unsigned char cur_sec;
    unsigned char cur_frame;
-
-   unsigned sector_size;
-   unsigned char sector_header_size;
-   unsigned char mode;
-
+   unsigned char cur_track;
+   unsigned cur_lba;
    unsigned last_frame_lba;
    unsigned char last_frame[2352];
-} vfs_cdrom_track_t;
+   bool last_frame_valid;
+} vfs_cdrom_t;
+#endif
 
 enum vfs_scheme
 {
    VFS_SCHEME_NONE = 0,
-   VFS_SCHEME_CDROM,
-   VFS_SCHEME_CDROM_TRACK,
-   VFS_SCHEME_CDROM_FILE,
-   VFS_SCHEME_CUE,
-   VFS_SCHEME_CUE_BIN,
-   VFS_SCHEME_CUE_BIN_FILE
+   VFS_SCHEME_CDROM
 };
 
 #ifndef __WINRT__
@@ -93,18 +81,10 @@ struct libretro_vfs_implementation_file
    uint64_t mappos;
    uint64_t mapsize;
    uint8_t *mapped;
-
-#ifdef VFS_FRONTEND
-   struct retro_vfs_file_handle* parent;
-#else
-   struct libretro_vfs_implementation_file* parent;
-#endif
-   uint64_t parent_offset;
-
    enum vfs_scheme scheme;
-
+#ifdef HAVE_CDROM
    vfs_cdrom_t cdrom;
-   vfs_cdrom_track_t* track;
+#endif
 };
 #endif
 
diff --git a/libretro-common/include/vfs/vfs_implementation_cdrom.h b/libretro-common/include/vfs/vfs_implementation_cdrom.h
index 43d1ace50e..3996fbe877 100644
--- a/libretro-common/include/vfs/vfs_implementation_cdrom.h
+++ b/libretro-common/include/vfs/vfs_implementation_cdrom.h
@@ -24,16 +24,13 @@
 #define __LIBRETRO_SDK_VFS_IMPLEMENTATION_CDROM_H
 
 #include <vfs/vfs.h>
-
-#ifdef HAVE_CDROM
 #include <cdrom/cdrom.h>
-#endif
 
 RETRO_BEGIN_DECLS
 
 int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int64_t offset, int whence);
 
-bool retro_vfs_file_open_cdrom(
+void retro_vfs_file_open_cdrom(
       libretro_vfs_implementation_file *stream,
       const char *path, unsigned mode, unsigned hints);
 
@@ -46,30 +43,9 @@ int64_t retro_vfs_file_read_cdrom(libretro_vfs_implementation_file *stream,
 
 int retro_vfs_file_error_cdrom(libretro_vfs_implementation_file *stream);
 
-#ifdef HAVE_CDROM
 const cdrom_toc_t* retro_vfs_file_get_cdrom_toc(void);
-#endif
 
-libretro_vfs_implementation_file* retro_vfs_file_open_cdrom_track(
-      libretro_vfs_implementation_file* stream, const char* track);
-
-int retro_vfs_file_close_cdrom_track(libretro_vfs_implementation_file *stream);
-
-int64_t retro_vfs_file_seek_cdrom_track(libretro_vfs_implementation_file *stream, int64_t offset, int whence);
-
-int64_t retro_vfs_file_read_cdrom_track(libretro_vfs_implementation_file *stream, void *s, uint64_t len);
-
-int64_t retro_vfs_file_tell_cdrom_track(libretro_vfs_implementation_file *stream);
-
-
-libretro_vfs_implementation_file* retro_vfs_file_open_cdrom_file(
-      libretro_vfs_implementation_file* stream, const char* path);
-
-int64_t retro_vfs_file_seek_cdrom_file(libretro_vfs_implementation_file *stream, int64_t offset, int whence);
-
-int64_t retro_vfs_file_read_cdrom_file(libretro_vfs_implementation_file *stream, void *s, uint64_t len);
-
-int64_t retro_vfs_file_tell_cdrom_file(libretro_vfs_implementation_file *stream);
+const vfs_cdrom_t* retro_vfs_file_get_cdrom_position(const libretro_vfs_implementation_file *stream);
 
 RETRO_END_DECLS
 
diff --git a/libretro-common/media/media_detect_cd.c b/libretro-common/media/media_detect_cd.c
index 8d06d59dfa..9faa747a5a 100644
--- a/libretro-common/media/media_detect_cd.c
+++ b/libretro-common/media/media_detect_cd.c
@@ -26,6 +26,8 @@
 #include <file/file_path.h>
 #include <retro_miscellaneous.h>
 
+/*#define MEDIA_CUE_PARSE_DEBUG*/
+
 static void media_zero_trailing_spaces(char *buf, size_t len)
 {
    int i;
@@ -63,6 +65,203 @@ static bool media_skip_spaces(const char **buf, size_t len)
    return false;
 }
 
+/* Fill in "info" with detected CD info. Use this when you have a cue file and want it parsed to find the first data track and any pregap info. */
+bool media_detect_cd_info_cue(const char *path, media_detect_cd_info_t *info)
+{
+   RFILE *file = NULL;
+   char *line = NULL;
+   char track_path[PATH_MAX_LENGTH] = {0};
+   char track_abs_path[PATH_MAX_LENGTH] = {0};
+   char track_mode[11] = {0};
+   bool found_file = false;
+   bool found_track = false;
+   unsigned first_data_track = 0;
+   uint64_t data_track_pregap_bytes = 0;
+
+   if (string_is_empty(path) || !info)
+      return false;
+
+   file = filestream_open(path, RETRO_VFS_FILE_ACCESS_READ, 0);
+
+   if (!file)
+   {
+      printf("[MEDIA] Could not open cue path for reading: %s\n", path);
+      fflush(stdout);
+      return false;
+   }
+
+   while (!filestream_eof(file) && (line = filestream_getline(file)))
+   {
+      size_t len = 0;
+      const char *command = NULL;
+
+      if (string_is_empty(line))
+      {
+         free(line);
+         continue;
+      }
+
+      len = strlen(line);
+
+      command = line;
+
+      media_skip_spaces(&command, len);
+
+      if (!found_file && !strncasecmp(command, "FILE", 4))
+      {
+         const char *file = command + 4;
+         media_skip_spaces(&file, len - 4);
+
+         if (!string_is_empty(file))
+         {
+            const char *file_end = NULL;
+            size_t file_len = 0;
+            bool quoted = false;
+
+            if (file[0] == '"')
+            {
+               quoted = true;
+               file++;
+            }
+
+            if (quoted)
+               file_end = strchr(file, '\"');
+            else
+               file_end = strchr(file, ' ');
+
+            if (file_end)
+            {
+               file_len = file_end - file;
+               memcpy(track_path, file, file_len);
+               found_file = true;
+#ifdef MEDIA_CUE_PARSE_DEBUG
+               printf("Found file: %s\n", track_path);
+               fflush(stdout);
+#endif
+            }
+         }
+      }
+      else if (found_file && !found_track && !strncasecmp(command, "TRACK", 5))
+      {
+         const char *track = command + 5;
+         media_skip_spaces(&track, len - 5);
+
+         if (!string_is_empty(track))
+         {
+            unsigned track_number = 0;
+            sscanf(track, "%d", &track_number);
+#ifdef MEDIA_CUE_PARSE_DEBUG
+            printf("Found track: %d\n", track_number);
+            fflush(stdout);
+#endif
+            track++;
+
+            if (track[0] && track[0] != ' ' && track[0] != '\t')
+               track++;
+
+            if (!string_is_empty(track))
+            {
+               media_skip_spaces(&track, strlen(track));
+#ifdef MEDIA_CUE_PARSE_DEBUG
+               printf("Found track type: %s\n", track);
+               fflush(stdout);
+#endif
+               if (!strncasecmp(track, "MODE", 4))
+               {
+                  first_data_track = track_number;
+                  found_track = true;
+                  strlcpy(track_mode, track, sizeof(track_mode));
+               }
+               else
+                  found_file = false;
+            }
+         }
+      }
+      else if (found_file && found_track && first_data_track && !strncasecmp(command, "INDEX", 5))
+      {
+         const char *index = command + 5;
+         media_skip_spaces(&index, len - 5);
+
+         if (!string_is_empty(index))
+         {
+            unsigned index_number = 0;
+            sscanf(index, "%d", &index_number);
+
+            if (index_number == 1)
+            {
+               const char *pregap = index + 1;
+
+               if (pregap[0] && pregap[0] != ' ' && pregap[0] != '\t')
+                  pregap++;
+
+               if (!string_is_empty(pregap))
+               {
+                  media_skip_spaces(&pregap, strlen(pregap));
+                  found_file = false;
+                  found_track = false;
+
+                  if (first_data_track && !string_is_empty(track_mode))
+                  {
+                     unsigned track_sector_size = 0;
+                     unsigned track_mode_number = 0;
+
+                     if (strlen(track_mode) == 10)
+                     {
+                        sscanf(track_mode, "MODE%d/%d", &track_mode_number, &track_sector_size);
+#ifdef MEDIA_CUE_PARSE_DEBUG
+                        printf("Found track mode %d with sector size %d\n", track_mode_number, track_sector_size);
+                        fflush(stdout);
+#endif
+                        if ((track_mode_number == 1 || track_mode_number == 2) && track_sector_size)
+                        {
+                           unsigned min = 0;
+                           unsigned sec = 0;
+                           unsigned frame = 0;
+                           sscanf(pregap, "%02d:%02d:%02d", &min, &sec, &frame);
+
+                           if (min || sec || frame || strstr(pregap, "00:00:00"))
+                           {
+                              data_track_pregap_bytes = ((min * 60 + sec) * 75 + frame) * track_sector_size;
+#ifdef MEDIA_CUE_PARSE_DEBUG
+                              printf("Found pregap of %02d:%02d:%02d (bytes: %" PRIu64 ")\n", min, sec, frame, data_track_pregap_bytes);
+                              fflush(stdout);
+#endif
+                              break;
+                           }
+                        }
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      free(line);
+   }
+
+   filestream_close(file);
+
+   if (!string_is_empty(track_path))
+   {
+      if (strstr(track_path, "/") || strstr(track_path, "\\"))
+      {
+         printf("using path %s\n", track_path);
+         fflush(stdout);
+         return media_detect_cd_info(track_path, data_track_pregap_bytes, info);
+      }
+      else
+      {
+         fill_pathname_basedir(track_abs_path, path, sizeof(track_abs_path));
+         strlcat(track_abs_path, track_path, sizeof(track_abs_path));
+         printf("using abs path %s\n", track_abs_path);
+         fflush(stdout);
+         return media_detect_cd_info(track_abs_path, data_track_pregap_bytes, info);
+      }
+   }
+
+   return true;
+}
+
 /* Fill in "info" with detected CD info. Use this when you want to open a specific track file directly, and the pregap is known. */
 bool media_detect_cd_info(const char *path, uint64_t pregap_bytes, media_detect_cd_info_t *info)
 {
diff --git a/libretro-common/streams/chd_stream.c b/libretro-common/streams/chd_stream.c
index af0dbe070d..97d3eb4699 100644
--- a/libretro-common/streams/chd_stream.c
+++ b/libretro-common/streams/chd_stream.c
@@ -43,8 +43,6 @@ struct chdstream
    uint32_t frame_size;
    /* Offset of data within frame */
    uint32_t frame_offset;
-   /* Size of frame header */
-   uint32_t frame_header_size;
    /* Number of frames per hunk */
    uint32_t frames_per_hunk;
    /* First frame of track in chd */
@@ -362,62 +360,11 @@ ssize_t chdstream_read(chdstream_t *stream, void *data, size_t bytes)
    return bytes;
 }
 
-ssize_t chdstream_read_file(chdstream_t *stream, int64_t file_start, void *data, size_t bytes)
-{
-   uint8_t buffer[SECTOR_SIZE];
-   int64_t file_frame = (stream->offset - file_start) / stream->frame_size;
-   int64_t file_frame_offset = (stream->offset - file_start) - (file_frame * stream->frame_size) - stream->frame_header_size;
-   ssize_t bytes_read = 0;
-
-   if (file_frame_offset >= stream->frame_header_size + 2048)
-   {
-      ++file_frame;
-      file_frame_offset = -1;
-   }
-   if (file_frame_offset < 0)
-   {
-      stream->offset = file_start + (file_frame * stream->frame_size) + stream->frame_header_size;
-      file_frame_offset = 0;
-   }
-
-   do
-   {
-      const int64_t remaining = 2048 - file_frame_offset;
-      if (bytes < remaining)
-      {
-         if (bytes > 0)
-         {
-            chdstream_read(stream, data, bytes);
-            bytes_read += bytes;
-         }
-         return bytes_read;
-      }
-
-      chdstream_read(stream, data, remaining);
-      bytes_read += remaining;
-      bytes -= remaining;
-
-      ++file_frame;
-      stream->offset = file_start + (file_frame * stream->frame_size) + stream->frame_header_size;
-      file_frame_offset = 0;
-   } while (true);
-}
-
 int chdstream_getc(chdstream_t *stream)
 {
    char c = 0;
 
-   if (chdstream_read(stream, &c, sizeof(c)) != sizeof(c))
-      return EOF;
-
-   return c;
-}
-
-int chdstream_getc_file(chdstream_t *stream, int64_t file_start)
-{
-   char c = 0;
-
-   if (chdstream_read_file(stream, file_start, &c, sizeof(c)) != sizeof(c))
+   if (chdstream_read(stream, &c, sizeof(c) != sizeof(c)))
       return EOF;
 
    return c;
@@ -438,43 +385,16 @@ char *chdstream_gets(chdstream_t *stream, char *buffer, size_t len)
    return buffer;
 }
 
-char *chdstream_gets_file(chdstream_t *stream, int64_t file_start, char *buffer, size_t len)
-{
-   int c;
-
-   size_t offset = 0;
-
-   while (offset < len && (c = chdstream_getc_file(stream, file_start)) != EOF)
-      buffer[offset++] = c;
-
-   if (offset < len)
-      buffer[offset] = '\0';
-
-   return buffer;
-}
-
 uint64_t chdstream_tell(chdstream_t *stream)
 {
    return stream->offset;
 }
 
-uint64_t chdstream_tell_file(chdstream_t *stream, int64_t file_start)
-{
-   const int64_t file_frame = (stream->offset - file_start) / stream->frame_size;
-   const int64_t file_frame_offset = (stream->offset - file_start) - (file_frame * stream->frame_size) - stream->frame_header_size;
-   return (file_frame * 2048) + file_frame_offset;
-}
-
 void chdstream_rewind(chdstream_t *stream)
 {
    stream->offset = 0;
 }
 
-void chdstream_rewind_file(chdstream_t *stream, int64_t file_start)
-{
-   stream->offset = file_start;
-}
-
 int64_t chdstream_seek(chdstream_t *stream, int64_t offset, int whence)
 {
    int64_t new_offset;
@@ -504,74 +424,6 @@ int64_t chdstream_seek(chdstream_t *stream, int64_t offset, int whence)
    return 0;
 }
 
-int64_t chdstream_seek_file(chdstream_t* stream, const char* path)
-{
-   uint8_t buffer[SECTOR_SIZE], *tmp;
-   int sector, path_length;
-
-   const char* slash = strrchr(path, '\\');
-   if (slash)
-   {
-      /* navigate the path to the directory record for the file */
-      const int dir_length = (int)(slash - path);
-      memcpy(buffer, path, dir_length);
-      buffer[dir_length] = '\0';
-
-      if (chdstream_seek_file(stream, (const char*)buffer) < 0)
-         return -1;
-
-      path += dir_length + 1;
-   }
-   else
-   {
-      /* The boot record or primary volume descriptor is always at sector 16 and will contain a "CD001" marker */
-      chdstream_seek(stream, 16 * stream->frame_size, SEEK_SET);
-      chdstream_read(stream, buffer, sizeof(buffer));
-
-      if (stream->frame_header_size == 0)
-      {
-         if (memcmp(&buffer[25], "CD001", 5) == 0)
-            stream->frame_header_size = 24;
-         else
-            stream->frame_header_size = 16;
-      }
-
-      /* the directory_record starts at 156 bytes into the sector.
-       * the sector containing the table of contents is a 3 byte value that is 2 bytes into the directory_record. */
-      {
-         const int offset = stream->frame_header_size + 156 + 2;
-         sector = buffer[offset] | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16);
-      }
-      chdstream_seek(stream, sector * stream->frame_size, SEEK_SET);
-   }
-
-   /* process the table of contents */
-   chdstream_read(stream, buffer, sizeof(buffer));
-
-   path_length = strlen(path);
-   tmp = buffer + stream->frame_header_size;
-   while (tmp < buffer + sizeof(buffer))
-   {
-      /* the first byte of the record is the length of the record - if 0, we reached the end of the data */
-      if (!*tmp)
-         break;
-
-      /* filename is 33 bytes into the record and the format is "FILENAME;version" or "DIRECTORY" */
-      if ((tmp[33 + path_length] == ';' || tmp[33 + path_length] == '\0') &&
-         strncasecmp((const char*)(tmp + 33), path, path_length) == 0)
-      {
-         /* the file contents are in the sector identified in bytes 2-4 of the record */
-         sector = tmp[2] | (tmp[3] << 8) | (tmp[4] << 16);
-         return chdstream_seek(stream, sector * stream->frame_size, SEEK_SET);
-      }
-
-      /* the first byte of the record is the length of the record */
-      tmp += tmp[0];
-   }
-
-   return -1;
-}
-
 ssize_t chdstream_get_size(chdstream_t *stream)
 {
   return stream->track_end;
diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c
index bbf892858d..e3e4590752 100644
--- a/libretro-common/streams/file_stream.c
+++ b/libretro-common/streams/file_stream.c
@@ -34,7 +34,6 @@
 #include <streams/file_stream.h>
 #define VFS_FRONTEND
 #include <vfs/vfs_implementation.h>
-#include <vfs/vfs_implementation_cdrom.h>
 
 static const int64_t vfs_error_return_value      = -1;
 
@@ -177,37 +176,6 @@ RFILE* filestream_open(const char *path, unsigned mode, unsigned hints)
    return output;
 }
 
-RFILE* filestream_open_child(RFILE *stream, const char* path)
-{
-   struct retro_vfs_file_handle  *fp = NULL;
-   RFILE* output                     = NULL;
-
-   switch (stream->hfile->scheme)
-   {
-      case VFS_SCHEME_CDROM:
-      case VFS_SCHEME_CUE:
-         fp = retro_vfs_file_open_cdrom_track(stream->hfile, path);
-         break;
-
-      case VFS_SCHEME_CDROM_TRACK:
-      case VFS_SCHEME_CUE_BIN:
-         fp = retro_vfs_file_open_cdrom_file(stream->hfile, path);
-         break;
-
-      default:
-         return NULL;
-   }
-
-   if (!fp)
-      return NULL;
-
-   output             = (RFILE*)malloc(sizeof(RFILE));
-   output->error_flag = false;
-   output->eof_flag   = false;
-   output->hfile      = fp;
-   return output;
-}
-
 char* filestream_gets(RFILE *stream, char *s, size_t len)
 {
    int c   = 0;
diff --git a/libretro-common/streams/interface_stream.c b/libretro-common/streams/interface_stream.c
index d6a85c738b..0207823ce2 100644
--- a/libretro-common/streams/interface_stream.c
+++ b/libretro-common/streams/interface_stream.c
@@ -52,7 +52,6 @@ struct intfstream_internal
    struct
    {
       int32_t track;
-      int32_t file_start;
       chdstream_t *fp;
    } chd;
 #endif
@@ -69,12 +68,12 @@ int64_t intfstream_get_size(intfstream_internal_t *intf)
          return filestream_get_size(intf->file.fp);
       case INTFSTREAM_MEMORY:
          return intf->memory.buf.size;
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
-         return chdstream_get_size(intf->chd.fp);
+#ifdef HAVE_CHD
+        return chdstream_get_size(intf->chd.fp);
+#else
+        break;
 #endif
-      default:
-         break;
    }
 
    return 0;
@@ -96,11 +95,9 @@ bool intfstream_resize(intfstream_internal_t *intf, intfstream_info_t *info)
          memstream_set_buffer(intf->memory.buf.data,
                intf->memory.buf.size);
          break;
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
-         break;
+#ifdef HAVE_CHD
 #endif
-      default:
          break;
    }
 
@@ -125,15 +122,15 @@ bool intfstream_open(intfstream_internal_t *intf, const char *path,
          if (!intf->memory.fp)
             return false;
          break;
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          intf->chd.fp = chdstream_open(path, intf->chd.track);
          if (!intf->chd.fp)
             return false;
          break;
-#endif
-      default:
+#else
          return false;
+#endif
    }
 
    return true;
@@ -152,8 +149,6 @@ int intfstream_flush(intfstream_internal_t *intf)
       case INTFSTREAM_CHD:
          /* Should we stub this for these interfaces? */
          break;
-      default:
-         break;
    }
 
    return 0;
@@ -174,17 +169,12 @@ int intfstream_close(intfstream_internal_t *intf)
          if (intf->memory.fp)
             memstream_close(intf->memory.fp);
          return 0;
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          if (intf->chd.fp)
             chdstream_close(intf->chd.fp);
-         return 0;
-      case INTFSTREAM_CHD_FILE:
-         /* handle owned by INTFSTREAM_CHD */
-         return 0;
 #endif
-      default:
-         break;
+         return 0;
    }
 
    return -1;
@@ -212,13 +202,13 @@ void *intfstream_init(intfstream_info_t *info)
          if (!intfstream_resize(intf, info))
             goto error;
          break;
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          intf->chd.track = info->chd.track;
          break;
-#endif
-      default:
+#else
          goto error;
+#endif
    }
 
    return intf;
@@ -256,12 +246,12 @@ int64_t intfstream_seek(intfstream_internal_t *intf, int64_t offset, int whence)
          }
       case INTFSTREAM_MEMORY:
          return (int64_t)memstream_seek(intf->memory.fp, offset, whence);
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          return (int64_t)chdstream_seek(intf->chd.fp, offset, whence);
-#endif
-      default:
+#else
          break;
+#endif
    }
 
    return -1;
@@ -278,14 +268,12 @@ int64_t intfstream_read(intfstream_internal_t *intf, void *s, uint64_t len)
          return filestream_read(intf->file.fp, s, len);
       case INTFSTREAM_MEMORY:
          return memstream_read(intf->memory.fp, s, len);
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          return chdstream_read(intf->chd.fp, s, len);
-      case INTFSTREAM_CHD_FILE:
-         return chdstream_read_file(intf->chd.fp, intf->chd.file_start, s, len);
-#endif
-      default:
+#else
          break;
+#endif
    }
 
    return -1;
@@ -304,7 +292,6 @@ int64_t intfstream_write(intfstream_internal_t *intf,
       case INTFSTREAM_MEMORY:
          return memstream_write(intf->memory.fp, s, len);
       case INTFSTREAM_CHD:
-      case INTFSTREAM_CHD_FILE:
          return -1;
    }
 
@@ -325,14 +312,12 @@ char *intfstream_gets(intfstream_internal_t *intf,
       case INTFSTREAM_MEMORY:
          return memstream_gets(intf->memory.fp,
                buffer, (size_t)len);
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          return chdstream_gets(intf->chd.fp, buffer, len);
-      case INTFSTREAM_CHD_FILE:
-         return chdstream_gets_file(intf->chd.fp, intf->chd.file_start, buffer, len);
-#endif
-      default:
+#else
          break;
+#endif
    }
 
    return NULL;
@@ -349,14 +334,12 @@ int intfstream_getc(intfstream_internal_t *intf)
          return filestream_getc(intf->file.fp);
       case INTFSTREAM_MEMORY:
          return memstream_getc(intf->memory.fp);
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          return chdstream_getc(intf->chd.fp);
-      case INTFSTREAM_CHD_FILE:
-         return chdstream_getc_file(intf->chd.fp, intf->chd.file_start);
-#endif
-      default:
+#else
          break;
+#endif
    }
 
    return -1;
@@ -373,14 +356,12 @@ int64_t intfstream_tell(intfstream_internal_t *intf)
          return (int64_t)filestream_tell(intf->file.fp);
       case INTFSTREAM_MEMORY:
          return (int64_t)memstream_pos(intf->memory.fp);
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          return (int64_t)chdstream_tell(intf->chd.fp);
-      case INTFSTREAM_CHD_FILE:
-         return (int64_t)chdstream_tell_file(intf->chd.fp, intf->chd.file_start);
-#endif
-      default:
+#else
          break;
+#endif
    }
 
    return -1;
@@ -396,15 +377,10 @@ void intfstream_rewind(intfstream_internal_t *intf)
       case INTFSTREAM_MEMORY:
          memstream_rewind(intf->memory.fp);
          break;
-#ifdef HAVE_CHD
       case INTFSTREAM_CHD:
+#ifdef HAVE_CHD
          chdstream_rewind(intf->chd.fp);
-         break;
-      case INTFSTREAM_CHD_FILE:
-         chdstream_rewind_file(intf->chd.fp, intf->chd.file_start);
-         break;
 #endif
-      default:
          break;
    }
 }
@@ -422,7 +398,7 @@ void intfstream_putc(intfstream_internal_t *intf, int c)
       case INTFSTREAM_MEMORY:
          memstream_putc(intf->memory.fp, c);
          break;
-      default:
+      case INTFSTREAM_CHD:
          break;
    }
 }
@@ -453,55 +429,6 @@ error:
    return NULL;
 }
 
-intfstream_t* intfstream_open_file_child(intfstream_internal_t* intf, const char* path)
-{
-   intfstream_info_t info;
-   intfstream_t *fd = NULL;
-
-   if (!intf)
-      return NULL;
-
-   info.type        = INTFSTREAM_FILE;
-   fd               = (intfstream_t*)intfstream_init(&info);
-
-   if (!fd)
-      return NULL;
-
-   switch (intf->type)
-   {
-      case INTFSTREAM_FILE:
-         fd->file.fp = filestream_open_child(intf->file.fp, path);
-         break;
-      case INTFSTREAM_MEMORY:
-         break;
-#ifdef HAVE_CHD
-      case INTFSTREAM_CHD:
-         if (chdstream_seek_file(intf->chd.fp, path) < 0)
-            goto error;
-
-         fd->type = INTFSTREAM_CHD_FILE;
-         fd->chd.fp = intf->chd.fp;
-         fd->chd.file_start = chdstream_tell(intf->chd.fp);
-         return fd;
-#endif
-      default:
-         goto error;
-   }
-
-   if (!fd->file.fp)
-      goto error;
-
-   return fd;
-
-error:
-   if (fd)
-   {
-      intfstream_close(fd);
-      free(fd);
-   }
-   return NULL;
-}
-
 intfstream_t *intfstream_open_memory(void *data,
       unsigned mode, unsigned hints, uint64_t size)
 {
diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c
index 535501aeb4..d92566e0f0 100644
--- a/libretro-common/vfs/vfs_implementation.c
+++ b/libretro-common/vfs/vfs_implementation.c
@@ -179,13 +179,16 @@
 #endif
 
 #include <vfs/vfs_implementation.h>
-#include <vfs/vfs_implementation_cdrom.h>
 #include <libretro.h>
 #include <memmap.h>
 #include <encodings/utf.h>
 #include <compat/fopen_utf8.h>
 #include <file/file_path.h>
 
+#ifdef HAVE_CDROM
+#include <vfs/vfs_implementation_cdrom.h>
+#endif
+
 #define RFILE_HINT_UNBUFFERED (1 << 8)
 
 int64_t retro_vfs_file_seek_internal(libretro_vfs_implementation_file *stream, int64_t offset, int whence)
@@ -195,25 +198,10 @@ int64_t retro_vfs_file_seek_internal(libretro_vfs_implementation_file *stream, i
 
    if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
    {
-      switch (stream->scheme)
-      {
 #ifdef HAVE_CDROM
-         case VFS_SCHEME_CDROM:
-            return retro_vfs_file_seek_cdrom(stream, offset, whence);
-         case VFS_SCHEME_CDROM_TRACK:
-            return retro_vfs_file_seek_cdrom_track(stream, offset, whence);
-         case VFS_SCHEME_CDROM_FILE:
-            return retro_vfs_file_seek_cdrom_file(stream, offset, whence);
+      if (stream->scheme == VFS_SCHEME_CDROM)
+         return retro_vfs_file_seek_cdrom(stream, offset, whence);
 #endif
-         case VFS_SCHEME_CUE:
-            break;
-         case VFS_SCHEME_CUE_BIN:
-            return retro_vfs_file_seek_cdrom_track(stream, offset, whence);
-         case VFS_SCHEME_CUE_BIN_FILE:
-            return retro_vfs_file_seek_cdrom_file(stream, offset, whence);
-         default:
-            break;
-      }
 /* VC2005 and up have a special 64-bit fseek */
 #ifdef ATLEAST_VC2005
       return _fseeki64(stream->fp, offset, whence);
@@ -415,28 +403,28 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(
       }
       stream->fd = fd;
 #else
+      FILE *fp;
 #ifdef HAVE_CDROM
       if (stream->scheme == VFS_SCHEME_CDROM)
       {
-         if (!retro_vfs_file_open_cdrom(stream, path, mode, hints))
+         retro_vfs_file_open_cdrom(stream, path, mode, hints);
+#if defined(_WIN32) && !defined(_XBOX)
+         if (!stream->fh)
             goto error;
+#else
+         if (!stream->fp)
+            goto error;
+#endif
       }
       else
 #endif
       {
-         FILE *fp;
-         const char* ext;
-
          fp = (FILE*)fopen_utf8(path, mode_str);
 
          if (!fp)
             goto error;
 
          stream->fp  = fp;
-
-         ext = path_get_extension(path);
-         if (string_is_equal_case_insensitive(ext, "cue"))
-            stream->scheme = VFS_SCHEME_CUE;
       }
       /* Regarding setvbuf:
        *
@@ -449,17 +437,11 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(
        */
       /* TODO: this is only useful for a few platforms, find which and add ifdef */
 #if !defined(PS2) && !defined(PSP)
-      switch (stream->scheme)
+      if (stream->scheme != VFS_SCHEME_CDROM)
       {
-         case VFS_SCHEME_CDROM:
-         case VFS_SCHEME_CDROM_FILE:
-         case VFS_SCHEME_CDROM_TRACK:
-            break;
-         default:
-            stream->buf = (char*)calloc(1, 0x4000);
-            if (stream->fp)
-               setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000);
-            break;
+         stream->buf = (char*)calloc(1, 0x4000);
+         if (stream->fp)
+            setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000);
       }
 #endif
 #endif
@@ -509,6 +491,18 @@ libretro_vfs_implementation_file *retro_vfs_file_open_impl(
    stream->size = orbisLseek(stream->fd, 0, SEEK_END);
    orbisLseek(stream->fd, 0, SEEK_SET);
 #else
+#ifdef HAVE_CDROM
+   if (stream->scheme == VFS_SCHEME_CDROM)
+   {
+      retro_vfs_file_seek_cdrom(stream, 0, SEEK_SET);
+      retro_vfs_file_seek_cdrom(stream, 0, SEEK_END);
+
+      stream->size = retro_vfs_file_tell_impl(stream);
+
+      retro_vfs_file_seek_cdrom(stream, 0, SEEK_SET);
+   }
+   else
+#endif
    {
       retro_vfs_file_seek_internal(stream, 0, SEEK_SET);
       retro_vfs_file_seek_internal(stream, 0, SEEK_END);
@@ -530,27 +524,13 @@ int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream)
    if (!stream)
       return -1;
 
-   switch (stream->scheme)
-   {
 #ifdef HAVE_CDROM
-      case VFS_SCHEME_CDROM:
-         retro_vfs_file_close_cdrom(stream);
-         goto end;
-
-      case VFS_SCHEME_CDROM_TRACK:
-         retro_vfs_file_close_cdrom_track(stream);
-         goto end;
-
-      case VFS_SCHEME_CDROM_FILE:
-         break;
-#endif
-
-      case VFS_SCHEME_CUE_BIN:
-         retro_vfs_file_close_cdrom_track(stream);
-         goto end;
-      default:
-         break;
+   if (stream->scheme == VFS_SCHEME_CDROM)
+   {
+      retro_vfs_file_close_cdrom(stream);
+      goto end;
    }
+#endif
 
    if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
    {
@@ -576,9 +556,8 @@ int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream)
       close(stream->fd);
 #endif
    }
-
-end:
 #ifdef HAVE_CDROM
+end:
    if (stream->cdrom.cue_buf)
       free(stream->cdrom.cue_buf);
 #endif
@@ -637,23 +616,10 @@ int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream)
 
    if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
    {
-      switch (stream->scheme)
-      {
 #ifdef HAVE_CDROM
-         case VFS_SCHEME_CDROM:
-            return retro_vfs_file_tell_cdrom(stream);
-         case VFS_SCHEME_CDROM_TRACK:
-            return retro_vfs_file_tell_cdrom_track(stream);
-         case VFS_SCHEME_CDROM_FILE:
-            return retro_vfs_file_tell_cdrom_file(stream);
+      if (stream->scheme == VFS_SCHEME_CDROM)
+         return retro_vfs_file_tell_cdrom(stream);
 #endif
-         case VFS_SCHEME_CUE_BIN:
-            return retro_vfs_file_tell_cdrom_track(stream);
-         case VFS_SCHEME_CUE_BIN_FILE:
-            return retro_vfs_file_tell_cdrom_file(stream);
-         default:
-            break;
-      }
 #ifdef ORBIS
       {
          int64_t ret = orbisLseek(stream->fd, 0, SEEK_CUR);
@@ -710,25 +676,10 @@ int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream,
 
    if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0)
    {
-      switch (stream->scheme)
-      {
 #ifdef HAVE_CDROM
-         case VFS_SCHEME_CDROM:
-            return retro_vfs_file_read_cdrom(stream, s, len);
-         case VFS_SCHEME_CDROM_TRACK:
-            return retro_vfs_file_read_cdrom_track(stream, s, len);
-         case VFS_SCHEME_CDROM_FILE:
-            return retro_vfs_file_read_cdrom_file(stream, s, len);
+      if (stream->scheme == VFS_SCHEME_CDROM)
+         return retro_vfs_file_read_cdrom(stream, s, len);
 #endif
-         case VFS_SCHEME_CUE:
-            break;
-         case VFS_SCHEME_CUE_BIN:
-            return retro_vfs_file_read_cdrom_track(stream, s, len);
-         case VFS_SCHEME_CUE_BIN_FILE:
-            return retro_vfs_file_read_cdrom_file(stream, s, len);
-         default:
-            break;
-      }
 #ifdef ORBIS
       if (orbisRead(stream->fd, s, (size_t)len) < 0)
          return -1;
diff --git a/libretro-common/vfs/vfs_implementation_cdrom.c b/libretro-common/vfs/vfs_implementation_cdrom.c
index c1cd6cc29e..537dc7acac 100644
--- a/libretro-common/vfs/vfs_implementation_cdrom.c
+++ b/libretro-common/vfs/vfs_implementation_cdrom.c
@@ -21,695 +21,370 @@
 */
 
 #include <vfs/vfs_implementation.h>
-#include <vfs/vfs_implementation_cdrom.h>
 #include <file/file_path.h>
 #include <compat/fopen_utf8.h>
 #include <string/stdstring.h>
-#include <retro_miscellaneous.h>
-
-#ifdef HAVE_CDROM
 #include <cdrom/cdrom.h>
-#endif
 
 #if defined(_WIN32) && !defined(_XBOX)
 #include <windows.h>
 #endif
 
-/*#define CDROM_CUE_PARSE_DEBUG*/
-
-#ifdef HAVE_CDROM
 static cdrom_toc_t vfs_cdrom_toc = {0};
 
 const cdrom_toc_t* retro_vfs_file_get_cdrom_toc(void)
 {
    return &vfs_cdrom_toc;
 }
-#endif
 
-static void retro_vfs_file_seek_cdrom_track_sector(libretro_vfs_implementation_file* stream, unsigned sector)
+int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int64_t offset, int whence)
 {
-   retro_vfs_file_seek_cdrom_track(stream, sector * stream->track->sector_size, SEEK_SET);
-}
-
-static unsigned char retro_vs_file_get_sector_header_size(libretro_vfs_implementation_file* track_stream)
-{
-   unsigned char buffer[32];
-   unsigned char sector_header_size = 0;
-
-   if (!track_stream || !track_stream->track)
-      return 0;
-
-   /* MODE information is normally found in the CUE sheet, but we can try to determine it from the raw data.
-    *
-    *   MODE1/2048 - CDROM Mode1 Data (cooked) [no header, no footer]
-    *   MODE1/2352 - CDROM Mode1 Data (raw)    [16 byte header, 288 byte footer]
-    *   MODE2/2336 - CDROM-XA Mode2 Data       [8 byte header, 280 byte footer]
-    *   MODE2/2352 - CDROM-XA Mode2 Data       [24 byte header, 280 byte footer]
-    *
-    * Note that MODE is actually a property on each sector and can change between 1 and 2 depending on how much error
-    * correction the author desired. To support that, the data format must be "/2352" to include the full header and
-    * data without error correction information, at which point the CUE sheet information becomes just a hint.
-    * For simplicitly, we currently only handle "/2352" modes
-    */
-
-   /* The boot record or primary volume descriptor is always at sector 16 and will contain a "CD001" marker */
-   retro_vfs_file_seek_cdrom_track_sector(track_stream, 16);
-   if (retro_vfs_file_read_cdrom_track(track_stream, buffer, sizeof(buffer)) == 0)
-      return 0;
-
-   /* ISO-9660 says the first twelve bytes of a sector should be the sync pattern 00 FF FF FF FF FF FF FF FF FF FF 00
-    * if it's not, then assume the track is audio data and has no header or MODE2/2336 which we don't support */
-   if (buffer[0] == 0 && buffer[1] == 0xFF && buffer[2] == 0xFF && buffer[3] == 0xFF &&
-      buffer[4] == 0xFF && buffer[5] == 0xFF && buffer[6] == 0xFF && buffer[7] == 0xFF &&
-      buffer[8] == 0xFF && buffer[9] == 0xFF && buffer[10] == 0xFF && buffer[11] == 0)
-   {
-      /* after the 12 byte sync pattern is three bytes identifying the sector and then one byte for the mode (total 16 bytes) */
-      sector_header_size = 16;
-      track_stream->track->mode = buffer[15];
-
-      /* if this is a CDROM-XA data source, the "CD001" tag will be offset by an additional 8 bytes */
-      if (buffer[25] == 0x43 && buffer[26] == 0x44 &&
-         buffer[27] == 0x30 && buffer[28] == 0x30 && buffer[29] == 0x31)
-      {
-         sector_header_size = 24;
-      }
-   }
-
-   return sector_header_size;
-}
-
-#ifdef HAVE_CDROM
-
-static bool retro_vfs_file_open_cdrom_handle(libretro_vfs_implementation_file* stream, const char* path, char drive)
-{
-#ifdef CDROM_DEBUG
-   printf("[CDROM] Open: Path %s\n", path);
-   fflush(stdout);
-#endif
-
-#if defined(__linux__) && !defined(ANDROID)
-   char cdrom_path[] = "/dev/sg1";
-   cdrom_path[7] = drive;
-
-   stream->fp = (FILE*)fopen_utf8(cdrom_path, "r+b");
-
-   if (!stream->fp)
-      return false;
-#elif defined(_WIN32) && !defined(_XBOX)
-   char cdrom_path[] = "\\\\.\\D:";
-   cdrom_path[4] = drive;
-
-   stream->fh = CreateFile(cdrom_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-
-   if (stream->fh == INVALID_HANDLE_VALUE)
-   {
-      stream->fh = NULL;
-      return false;
-   }
-#endif
-
-   stream->orig_path = strdup(path);
-
-   cdrom_write_cue(stream, &stream->cdrom.cue_buf, &stream->cdrom.cue_len, stream->cdrom.drive, &vfs_cdrom_toc.num_tracks, &vfs_cdrom_toc);
-   cdrom_get_timeouts(stream, &vfs_cdrom_toc.timeouts);
-
-   return true;
-}
-
-#endif
-
-bool retro_vfs_file_open_cdrom(
-   libretro_vfs_implementation_file* stream,
-   const char* path, unsigned mode, unsigned hints)
-{
-   size_t path_len = strlen(path);
-   const char* ext = path_get_extension(path);
+   const char *ext = path_get_extension(stream->orig_path);
 
    if (string_is_equal_noncase(ext, "cue"))
    {
-      stream->cdrom.drive = '\0';
-
-#ifdef HAVE_CDROM
-#if defined(__linux__) && !defined(ANDROID)
-      if (path_len >= strlen("drive1.cue"))
+      switch (whence)
       {
-         if (!memcmp(path, "drive", strlen("drive")))
-         {
-            if (path[5] >= '0' && path[5] <= '9')
-            {
-               stream->cdrom.drive = path[5];
-               vfs_cdrom_toc.drive = stream->cdrom.drive;
-
-               return retro_vfs_file_open_cdrom_handle(stream, path, stream->cdrom.drive);
-            }
-         }
+         case SEEK_SET:
+            stream->cdrom.byte_pos = offset;
+            break;
+         case SEEK_CUR:
+            stream->cdrom.byte_pos += offset;
+            break;
+         case SEEK_END:
+            stream->cdrom.byte_pos = (stream->cdrom.cue_len - 1) + offset;
+            break;
       }
-#elif defined(_WIN32) && !defined(_XBOX)
-      if (path_len >= strlen("d:/drive.cue"))
-      {
-         if (!memcmp(path + 1, ":/drive", strlen(":/drive")))
-         {
-            if ((path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z'))
-            {
-               stream->cdrom.drive = path[0];
-               vfs_cdrom_toc.drive = stream->cdrom.drive;
 
-               return retro_vfs_file_open_cdrom_handle(stream, path, stream->cdrom.drive);
-            }
-         }
-      }
+#ifdef CDROM_DEBUG
+      printf("[CDROM] Seek: Path %s Offset %" PRIu64 " is now at %" PRIu64 "\n", stream->orig_path, offset, stream->cdrom.byte_pos);
+      fflush(stdout);
 #endif
-#endif
-
-      stream->fp = (FILE*)fopen_utf8(path, "r+b");
-      if (stream->fp)
-      {
-         stream->scheme = VFS_SCHEME_CUE;
-         return true;
-      }
    }
-#ifdef HAVE_CDROM
    else if (string_is_equal_noncase(ext, "bin"))
    {
-      unsigned track = 0;
+      int lba = (offset / 2352);
+      unsigned char min = 0;
+      unsigned char sec = 0;
+      unsigned char frame = 0;
+      const char *seek_type = "SEEK_SET";
 
-#if defined(__linux__) && !defined(ANDROID)
-      if (path_len >= strlen("drive1-track01.bin"))
+      (void)seek_type;
+
+      switch (whence)
       {
-         if (!memcmp(path, "drive", strlen("drive")))
+         case SEEK_CUR:
          {
-            if (!memcmp(path + 6, "-track", strlen("-track")))
-               sscanf(path + 12, "%02u", (unsigned*)& track);
+            unsigned new_lba;
 
-            stream->cdrom.drive = path[5];
-            if (!retro_vfs_file_open_cdrom_handle(stream, path, stream->cdrom.drive))
-               return false;
+            stream->cdrom.byte_pos += offset;
+            new_lba = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352);
+            seek_type = "SEEK_CUR";
+
+            cdrom_lba_to_msf(new_lba, &min, &sec, &frame);
+
+            break;
+         }
+         case SEEK_END:
+         {
+            ssize_t pregap_lba_len = (vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].audio ? 0 : (vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba_start));
+            ssize_t lba_len = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_size - pregap_lba_len;
+
+            cdrom_lba_to_msf(lba_len + lba, &min, &sec, &frame);
+
+            stream->cdrom.byte_pos = lba_len * 2352;
+            seek_type = "SEEK_END";
+
+            break;
+         }
+         case SEEK_SET:
+         default:
+         {
+            seek_type = "SEEK_SET";
+            stream->cdrom.byte_pos = offset;
+            cdrom_lba_to_msf(vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352), &min, &sec, &frame);
+            break;
          }
       }
-#elif defined(_WIN32) && !defined(_XBOX)
-      if (path_len >= strlen("d:/drive-track01.bin"))
-      {
-         if (!memcmp(path + 1, ":/drive-track", strlen(":/drive-track")))
-         {
-            sscanf(path + 14, "%02u", (unsigned*)& track);
 
-            stream->cdrom.drive = path[0];
-            vfs_cdrom_toc.drive = stream->cdrom.drive;
+      stream->cdrom.cur_min = min;
+      stream->cdrom.cur_sec = sec;
+      stream->cdrom.cur_frame = frame;
+      stream->cdrom.cur_lba = cdrom_msf_to_lba(min, sec, frame);
 
-            if (!retro_vfs_file_open_cdrom_handle(stream, path, stream->cdrom.drive))
-               return false;
-         }
-      }
-#endif
-
-      if (track)
-      {
 #ifdef CDROM_DEBUG
-         printf("[CDROM] Opening track %u\n", track);
-         fflush(stdout);
+      printf("[CDROM] Seek %s: Path %s Offset %" PRIu64 " is now at %" PRIu64 " (MSF %02u:%02u:%02u) (LBA %u)...\n", seek_type, stream->orig_path, offset, stream->cdrom.byte_pos, (unsigned)stream->cdrom.cur_min, (unsigned)stream->cdrom.cur_sec, (unsigned)stream->cdrom.cur_frame, stream->cdrom.cur_lba);
+      fflush(stdout);
 #endif
+   }
+   else
+      return -1;
 
-         if (track > vfs_cdrom_toc.num_tracks)
-            track = 1;
+   return 0;
+}
 
-         stream->scheme = VFS_SCHEME_CDROM_TRACK;
-         stream->parent = stream;
-         stream->size = vfs_cdrom_toc.track[track - 1].track_bytes;
-         stream->track = (vfs_cdrom_track_t*)calloc(1, sizeof(*stream->track));
-         stream->track->sector_size = 2352;
-         stream->track->cur_track = track;
-         stream->track->cur_min = vfs_cdrom_toc.track[track - 1].min;
-         stream->track->cur_sec = vfs_cdrom_toc.track[track - 1].sec;
-         stream->track->cur_frame = vfs_cdrom_toc.track[track - 1].frame;
-         stream->track->cur_lba = cdrom_msf_to_lba(stream->track->cur_min, stream->track->cur_sec, stream->track->cur_frame);
-         stream->track->last_frame_lba = (unsigned)-1;
-         return true;
+void retro_vfs_file_open_cdrom(
+      libretro_vfs_implementation_file *stream,
+      const char *path, unsigned mode, unsigned hints)
+{
+#if defined(__linux__) && !defined(ANDROID)
+   char cdrom_path[] = "/dev/sg1";
+   size_t path_len = strlen(path);
+   const char *ext = path_get_extension(path);
+
+   stream->cdrom.cur_track = 1;
+
+   if (!string_is_equal_noncase(ext, "cue") && !string_is_equal_noncase(ext, "bin"))
+      return;
+
+   if (path_len >= strlen("drive1-track01.bin"))
+   {
+      if (!memcmp(path, "drive", strlen("drive")))
+      {
+         if (!memcmp(path + 6, "-track", strlen("-track")))
+         {
+            if (sscanf(path + 12, "%02u", (unsigned*)&stream->cdrom.cur_track))
+            {
+#ifdef CDROM_DEBUG
+               printf("[CDROM] Opening track %d\n", stream->cdrom.cur_track);
+               fflush(stdout);
+#endif
+            }
+         }
       }
    }
-#endif
 
-   return false;
+   if (path_len >= strlen("drive1.cue"))
+   {
+      if (!memcmp(path, "drive", strlen("drive")))
+      {
+         if (path[5] >= '0' && path[5] <= '9')
+         {
+            cdrom_path[7] = path[5];
+            stream->cdrom.drive = path[5];
+            vfs_cdrom_toc.drive = stream->cdrom.drive;
+         }
+      }
+   }
+
+#ifdef CDROM_DEBUG
+   printf("[CDROM] Open: Path %s URI %s\n", cdrom_path, path);
+   fflush(stdout);
+#endif
+   stream->fp = (FILE*)fopen_utf8(cdrom_path, "r+b");
+
+   if (!stream->fp)
+      return;
+
+   if (string_is_equal_noncase(ext, "cue"))
+   {
+      if (stream->cdrom.cue_buf)
+      {
+         free(stream->cdrom.cue_buf);
+         stream->cdrom.cue_buf = NULL;
+      }
+
+      cdrom_write_cue(stream, &stream->cdrom.cue_buf, &stream->cdrom.cue_len, stream->cdrom.drive, &vfs_cdrom_toc.num_tracks, &vfs_cdrom_toc);
+      cdrom_get_timeouts(stream, &vfs_cdrom_toc.timeouts);
+
+#ifdef CDROM_DEBUG
+      if (string_is_empty(stream->cdrom.cue_buf))
+      {
+         printf("[CDROM] Error writing cue sheet.\n");
+         fflush(stdout);
+      }
+      else
+      {
+         printf("[CDROM] CUE Sheet:\n%s\n", stream->cdrom.cue_buf);
+         fflush(stdout);
+      }
+#endif
+   }
+#endif
+#if defined(_WIN32) && !defined(_XBOX)
+   char cdrom_path[] = "\\\\.\\D:";
+   size_t path_len = strlen(path);
+   const char *ext = path_get_extension(path);
+
+   if (!string_is_equal_noncase(ext, "cue") && !string_is_equal_noncase(ext, "bin"))
+      return;
+
+   if (path_len >= strlen("d:/drive-track01.bin"))
+   {
+      if (!memcmp(path + 1, ":/drive-track", strlen(":/drive-track")))
+      {
+         if (sscanf(path + 14, "%02u", (unsigned*)&stream->cdrom.cur_track))
+         {
+#ifdef CDROM_DEBUG
+            printf("[CDROM] Opening track %d\n", stream->cdrom.cur_track);
+            fflush(stdout);
+#endif
+         }
+      }
+   }
+
+   if (path_len >= strlen("d:/drive.cue"))
+   {
+      if (!memcmp(path + 1, ":/drive", strlen(":/drive")))
+      {
+         if ((path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z'))
+         {
+            cdrom_path[4] = path[0];
+            stream->cdrom.drive = path[0];
+            vfs_cdrom_toc.drive = stream->cdrom.drive;
+         }
+      }
+   }
+
+#ifdef CDROM_DEBUG
+   printf("[CDROM] Open: Path %s URI %s\n", cdrom_path, path);
+   fflush(stdout);
+#endif
+   stream->fh = CreateFile(cdrom_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+   if (stream->fh == INVALID_HANDLE_VALUE)
+      return;
+
+   if (string_is_equal_noncase(ext, "cue"))
+   {
+      if (stream->cdrom.cue_buf)
+      {
+         free(stream->cdrom.cue_buf);
+         stream->cdrom.cue_buf = NULL;
+      }
+
+      cdrom_write_cue(stream, &stream->cdrom.cue_buf, &stream->cdrom.cue_len, stream->cdrom.drive, &vfs_cdrom_toc.num_tracks, &vfs_cdrom_toc);
+      cdrom_get_timeouts(stream, &vfs_cdrom_toc.timeouts);
+
+#ifdef CDROM_DEBUG
+      if (string_is_empty(stream->cdrom.cue_buf))
+      {
+         printf("[CDROM] Error writing cue sheet.\n");
+         fflush(stdout);
+      }
+      else
+      {
+         printf("[CDROM] CUE Sheet:\n%s\n", stream->cdrom.cue_buf);
+         fflush(stdout);
+      }
+#endif
+   }
+#endif
+   if (vfs_cdrom_toc.num_tracks > 1 && stream->cdrom.cur_track)
+   {
+      stream->cdrom.cur_min = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].min;
+      stream->cdrom.cur_sec = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].sec;
+      stream->cdrom.cur_frame = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].frame;
+      stream->cdrom.cur_lba = cdrom_msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame);
+   }
+   else
+   {
+      stream->cdrom.cur_min = vfs_cdrom_toc.track[0].min;
+      stream->cdrom.cur_sec = vfs_cdrom_toc.track[0].sec;
+      stream->cdrom.cur_frame = vfs_cdrom_toc.track[0].frame;
+      stream->cdrom.cur_lba = cdrom_msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame);
+   }
 }
 
 int retro_vfs_file_close_cdrom(libretro_vfs_implementation_file *stream)
 {
-#ifdef HAVE_CDROM
 #ifdef CDROM_DEBUG
    printf("[CDROM] Close: Path %s\n", stream->orig_path);
    fflush(stdout);
 #endif
 
 #if defined(_WIN32) && !defined(_XBOX)
-   if (stream->fh && !CloseHandle(stream->fh))
+   if (!stream->fh || !CloseHandle(stream->fh))
       return -1;
 #else
    if (!stream->fp || fclose(stream->fp))
       return -1;
 #endif
-#endif
-
-   return 0;
-}
-
-int64_t retro_vfs_file_seek_cdrom(libretro_vfs_implementation_file *stream, int64_t offset, int whence)
-{
-   switch (whence)
-   {
-      case SEEK_SET:
-         stream->cdrom.cue_pos = offset;
-         break;
-
-      case SEEK_CUR:
-         stream->cdrom.cue_pos += offset;
-         break;
-
-      case SEEK_END:
-         stream->cdrom.cue_pos = stream->cdrom.cue_len - offset;
-         break;
-   }
-
-   if (stream->cdrom.cue_pos > stream->cdrom.cue_len)
-      stream->cdrom.cue_pos = stream->cdrom.cue_len;
-   if (stream->cdrom.cue_pos < 0)
-      stream->cdrom.cue_pos = 0;
 
    return 0;
 }
 
 int64_t retro_vfs_file_tell_cdrom(libretro_vfs_implementation_file *stream)
 {
-   return stream->cdrom.cue_pos;
-}
-
-int64_t retro_vfs_file_read_cdrom(libretro_vfs_implementation_file* stream,
-   void* s, uint64_t len)
-{
-   size_t bytes_to_copy;
-
-   if (!stream->cdrom.cue_buf)
-      return 0;
-
-   bytes_to_copy = stream->cdrom.cue_len - stream->cdrom.cue_pos;
-   if (bytes_to_copy > len)
-       bytes_to_copy = len;
-   if (bytes_to_copy > 0)
-   {
-      memcpy(s, &stream->cdrom.cue_buf[stream->cdrom.cue_pos], bytes_to_copy);
-      stream->cdrom.cue_pos += bytes_to_copy;
-   }
-
-   return bytes_to_copy;
-}
-
-int retro_vfs_file_error_cdrom(libretro_vfs_implementation_file *stream)
-{
-   return 0;
-}
-
-static void retro_vfs_skip_spaces(const char **buf, size_t len)
-{
-   if (!buf || !*buf)
-      return;
-
-   while (len-- && (**buf == ' ' || **buf == '\t'))
-      ++(*buf);
-}
-
-static bool retro_vfs_file_get_cue_track_path(const char* cue_contents, const char* cue_path, unsigned track, char* track_path, size_t max_track_path, int* track_pregap_bytes, int* sector_size)
-{
-   const char *line = NULL;
-   const char* cue = cue_contents;
-   char current_track_path[PATH_MAX_LENGTH] = {0};
-   char track_mode[11] = {0};
-   bool found_file = false;
-   unsigned found_track = 0;
-
-   if (!cue_contents)
-      return false;
-
-   track_path[0] = '\0';
-
-   while (*cue)
-   {
-      size_t len = 0;
-
-      while (*cue && (*cue == ' ' || *cue == '\t'))
-         ++cue;
-      line = cue;
-      while (*cue && *cue != '\n')
-         ++cue;
-      len = cue - line;
-      if (*cue)
-         ++cue;
-      if (len == 0)
-         continue;
-
-      if (!found_file && !strncasecmp(line, "FILE", 4))
-      {
-         const char *file = line + 4;
-         retro_vfs_skip_spaces(&file, len - 4);
-
-         if (!string_is_empty(file))
-         {
-            const char *file_end = NULL;
-            size_t file_len = 0;
-            bool quoted = false;
-
-            if (file[0] == '"')
-            {
-               quoted = true;
-               file++;
-            }
-
-            if (quoted)
-               file_end = strchr(file, '\"');
-            else
-               file_end = strchr(file, ' ');
-
-            if (file_end)
-            {
-               file_len = file_end - file;
-               memcpy(current_track_path, file, file_len);
-               found_file = true;
-#ifdef CDROM_CUE_PARSE_DEBUG
-               printf("Found file: %s\n", current_track_path);
-               fflush(stdout);
-#endif
-            }
-         }
-      }
-      else if (found_file && !found_track && !strncasecmp(line, "TRACK", 5))
-      {
-         const char *track = line + 5;
-         retro_vfs_skip_spaces(&track, len - 5);
-
-         if (!string_is_empty(track))
-         {
-            unsigned track_number = 0;
-            sscanf(track, "%u", &track_number);
-#ifdef CDROM_CUE_PARSE_DEBUG
-            printf("Found track: %d\n", track_number);
-            fflush(stdout);
-#endif
-            track++;
-
-            if (track[0] && track[0] != ' ' && track[0] != '\t')
-               track++;
-
-            if (!string_is_empty(track))
-            {
-               retro_vfs_skip_spaces(&track, strlen(track));
-#ifdef CDROM_CUE_PARSE_DEBUG
-               printf("Found track type: %s\n", track);
-               fflush(stdout);
-#endif
-               if (!strncasecmp(track, "MODE", 4))
-               {
-                  found_track = track_number;
-                  strlcpy(track_mode, track, sizeof(track_mode));
-               }
-               else
-                  found_track = 0;
-            }
-         }
-      }
-      else if (found_file && found_track == track && !strncasecmp(line, "INDEX", 5))
-      {
-         const char *index = line + 5;
-         retro_vfs_skip_spaces(&index, len - 5);
-
-         if (!string_is_empty(index))
-         {
-            unsigned index_number = 0;
-            sscanf(index, "%u", &index_number);
-
-            if (index_number == 1)
-            {
-               const char *pregap = index + 1;
-               if (pregap[0] && pregap[0] != ' ' && pregap[0] != '\t')
-                  pregap++;
-
-               if (strstr(current_track_path, "/") || strstr(current_track_path, "\\"))
-               {
-                  strncpy(track_path, current_track_path, max_track_path);
-#ifdef CDROM_CUE_PARSE_DEBUG
-                  printf("using path %s\n", track_path);
-                  fflush(stdout);
-#endif
-               }
-               else
-               {
-                  fill_pathname_basedir(track_path, cue_path, max_track_path);
-                  strlcat(track_path, current_track_path, max_track_path);
-#ifdef CDROM_CUE_PARSE_DEBUG
-                  printf("using absolute path %s\n", track_path);
-                  fflush(stdout);
-#endif
-               }
-
-               if (!string_is_empty(pregap))
-               {
-                  retro_vfs_skip_spaces(&pregap, strlen(pregap));
-                  found_file = false;
-                  found_track = false;
-
-                  if (!string_is_empty(track_mode))
-                  {
-                     unsigned track_sector_size = 0;
-                     unsigned track_mode_number = 0;
-
-                     if (strlen(track_mode) == 10)
-                     {
-                        sscanf(track_mode, "MODE%u/%u", &track_mode_number, &track_sector_size);
-#ifdef CDROM_CUE_PARSE_DEBUG
-                        printf("Found track mode %d with sector size %d\n", track_mode_number, track_sector_size);
-                        fflush(stdout);
-#endif
-                        if ((track_mode_number == 1 || track_mode_number == 2) && track_sector_size)
-                        {
-                           unsigned min = 0;
-                           unsigned sec = 0;
-                           unsigned frame = 0;
-                           sscanf(pregap, "%02u:%02u:%02u", &min, &sec, &frame);
-
-                           if (min || sec || frame || strstr(pregap, "00:00:00"))
-                           {
-                              if (sector_size)
-                                 *sector_size = track_sector_size;
-                              if (track_pregap_bytes)
-                                 *track_pregap_bytes = ((min * 60 + sec) * 75 + frame) * track_sector_size;
-#ifdef CDROM_CUE_PARSE_DEBUG
-                              printf("Found pregap of %02u:%02u:%02u (bytes: %" PRIu64 ")\n", min, sec, frame, data_track_pregap_bytes);
-                              fflush(stdout);
-#endif
-                              break;
-                           }
-                        }
-                     }
-                  }
-               }
-            }
-         }
-      }
-   }
-
-   return !string_is_empty(track_path);
-}
-
-libretro_vfs_implementation_file* retro_vfs_file_open_cdrom_track(libretro_vfs_implementation_file* stream, const char* track)
-{
-   char track_path[PATH_MAX_LENGTH];
-   unsigned track_index = 0;
-
-   if (!stream->cdrom.cue_buf)
-   {
-      switch (stream->scheme)
-      {
-         case VFS_SCHEME_CUE:
-            stream->cdrom.cue_len = stream->size;
-            stream->cdrom.cue_buf = (char*)malloc(stream->size + 1);
-            if (stream->cdrom.cue_buf)
-            {
-               retro_vfs_file_seek_impl(stream, 0, RETRO_VFS_SEEK_POSITION_START);
-               retro_vfs_file_read_impl(stream, stream->cdrom.cue_buf, stream->cdrom.cue_len);
-               stream->cdrom.cue_buf[stream->cdrom.cue_len] = '\0';
-            }
-            break;
-
-#ifdef HAVE_CDROM
-         case VFS_SCHEME_CDROM:
-            cdrom_write_cue(stream, &stream->cdrom.cue_buf, &stream->cdrom.cue_len, stream->cdrom.drive, &vfs_cdrom_toc.num_tracks, &vfs_cdrom_toc);
-            cdrom_get_timeouts(stream, &vfs_cdrom_toc.timeouts);
-
-#ifdef CDROM_DEBUG
-            if (string_is_empty(stream->cdrom.cue_buf))
-            {
-               printf("[CDROM] Error writing cue sheet.\n");
-               fflush(stdout);
-            }
-            else
-            {
-               printf("[CDROM] CUE Sheet:\n%s\n", stream->cdrom.cue_buf);
-               fflush(stdout);
-            }
-#endif
-            break;
-#endif
-
-         default:
-            return NULL;
-      }
-
-      if (!stream->cdrom.cue_buf)
-         return NULL;
-   }
-
-   while (*track && (*track < '0' || *track > '9'))
-      ++track;
-
-   sscanf(track, "%u", &track_index);
-
-   if (track_index > 0)
-   {
-      int pregap_bytes = 0;
-      int sector_size = 2352;
-      if (retro_vfs_file_get_cue_track_path(stream->cdrom.cue_buf, stream->orig_path, track_index, track_path, PATH_MAX_LENGTH, &pregap_bytes, &sector_size))
-      {
-         libretro_vfs_implementation_file* track_stream;
-         if (stream->scheme == VFS_SCHEME_CDROM)
-         {
-#ifdef HAVE_CDROM
-            track_stream = (libretro_vfs_implementation_file*)calloc(1, sizeof(*stream));
-            track_stream->size = vfs_cdrom_toc.track[track_index - 1].track_bytes;
-#endif
-         }
-         else
-         {
-            track_stream = retro_vfs_file_open_impl(track_path, RETRO_VFS_FILE_ACCESS_READ, stream->hints);
-         }
-
-         if (track_stream)
-         {
-            track_stream->scheme = VFS_SCHEME_CDROM_TRACK;
-            track_stream->cdrom.drive = stream->cdrom.drive;
-            track_stream->parent = stream;
-            track_stream->parent_offset = pregap_bytes;
-
-            track_stream->track = (vfs_cdrom_track_t*)calloc(1, sizeof(*track_stream->track));
-            track_stream->track->cur_track = track_index;
-            track_stream->track->last_frame_lba = (unsigned)-1;
-            track_stream->track->sector_size = sector_size;
-            track_stream->track->sector_header_size = retro_vs_file_get_sector_header_size(track_stream);
-
-            return track_stream;
-         }
-      }
-   }
-
-   return NULL;
-}
-
-int retro_vfs_file_close_cdrom_track(libretro_vfs_implementation_file* stream)
-{
-   if (stream->track)
-      free(stream->track);
-
-   if (stream->parent == stream)
-      retro_vfs_file_close_cdrom(stream);
-
-   return 0;
-}
-
-int64_t retro_vfs_file_seek_cdrom_track(libretro_vfs_implementation_file* stream, int64_t offset, int whence)
-{
-   if (!stream->parent)
+   const char *ext = NULL;
+   if (!stream)
       return -1;
 
-   switch (whence)
+   ext = path_get_extension(stream->orig_path);
+
+   if (string_is_equal_noncase(ext, "cue"))
    {
-      case SEEK_SET:
-         stream->track->byte_pos = offset;
-         break;
-
-      case SEEK_CUR:
-         stream->track->byte_pos += offset;
-         break;
-
-      case SEEK_END:
-         stream->track->byte_pos = stream->size - offset;
-         break;
-   }
-
-   if (stream->track->byte_pos >= stream->size)
-      stream->track->byte_pos = stream->size - 1;
-   if (stream->track->byte_pos < 0)
-      stream->track->byte_pos = 0;
-
-   if (stream->parent->scheme == VFS_SCHEME_CUE)
-   {
-      int64_t rv;
-
-      /* temporarily change scheme to prevent infinite recusion */
-      stream->scheme = VFS_SCHEME_NONE;
-      rv = retro_vfs_file_seek_impl(stream, stream->track->byte_pos + stream->parent_offset, SEEK_SET);
-      stream->scheme = VFS_SCHEME_CUE_BIN;
-
-      if (rv >= 0)
-         stream->track->cur_lba = stream->track->byte_pos / stream->track->sector_size;
-
-      return rv;
-   }
-
-#ifdef HAVE_CDROM
-   stream->track->cur_lba = vfs_cdrom_toc.track[stream->track->cur_track - 1].lba + (stream->track->byte_pos / stream->track->sector_size);
-   cdrom_lba_to_msf(stream->track->cur_lba, &stream->track->cur_min, &stream->track->cur_sec, &stream->track->cur_frame);
-
 #ifdef CDROM_DEBUG
-   printf("[CDROM] Seek: Path %s Offset %" PRIu64 " is now at %" PRIu64 " (MSF %02u:%02u:%02u) (LBA %u)...\n",
-      stream->orig_path, offset, stream->track->byte_pos, (unsigned)stream->track->cur_min, (unsigned)stream->track->cur_sec, (unsigned)stream->track->cur_frame, stream->track->cur_lba);
-   fflush(stdout);
+      printf("[CDROM] (cue) Tell: Path %s Position %" PRIu64 "\n", stream->orig_path, stream->cdrom.byte_pos);
+      fflush(stdout);
 #endif
+      return stream->cdrom.byte_pos;
+   }
+   else if (string_is_equal_noncase(ext, "bin"))
+   {
+#ifdef CDROM_DEBUG
+      printf("[CDROM] (bin) Tell: Path %s Position %" PRId64 "\n", stream->orig_path, stream->cdrom.byte_pos);
+      fflush(stdout);
 #endif
+      return stream->cdrom.byte_pos;
+   }
 
-   return 0;
+   return -1;
 }
 
-static void retro_vfs_file_read_cdrom_track_sector(libretro_vfs_implementation_file* stream, void* s, uint64_t len)
+int64_t retro_vfs_file_read_cdrom(libretro_vfs_implementation_file *stream,
+      void *s, uint64_t len)
 {
-   if (stream->parent->scheme == VFS_SCHEME_CUE)
+   int rv;
+   const char *ext = path_get_extension(stream->orig_path);
+
+   if (string_is_equal_noncase(ext, "cue"))
    {
-      /* temporarily change the scheme to prevent recursion */
-      stream->scheme = VFS_SCHEME_NONE;
-      retro_vfs_file_read_impl(stream, s, len);
-      stream->scheme = VFS_SCHEME_CUE_BIN;
+      if ((int64_t)len < (int64_t)stream->cdrom.cue_len - stream->cdrom.byte_pos)
+      {
+#ifdef CDROM_DEBUG
+         printf("[CDROM] Read: Reading %" PRIu64 " bytes from cuesheet starting at %" PRIu64 "...\n", len, stream->cdrom.byte_pos);
+         fflush(stdout);
+#endif
+         memcpy(s, stream->cdrom.cue_buf + stream->cdrom.byte_pos, len);
+         stream->cdrom.byte_pos += len;
+
+         return len;
+      }
+      else
+      {
+#ifdef CDROM_DEBUG
+         printf("[CDROM] Read: Reading %" PRIu64 " bytes from cuesheet starting at %" PRIu64 " failed.\n", len, stream->cdrom.byte_pos);
+         fflush(stdout);
+#endif
+         return 0;
+      }
    }
-#ifdef HAVE_CDROM
-   else
+   else if (string_is_equal_noncase(ext, "bin"))
    {
-      int rv;
+      size_t skip = stream->cdrom.byte_pos % 2352;
       unsigned char min = 0;
       unsigned char sec = 0;
       unsigned char frame = 0;
       unsigned char rmin = 0;
       unsigned char rsec = 0;
       unsigned char rframe = 0;
-      uint64_t byte_pos = stream->track->cur_lba * stream->track->sector_size;
 
-      if (byte_pos >= vfs_cdrom_toc.track[stream->track->cur_track - 1].track_bytes)
-         return;
+      if (stream->cdrom.byte_pos >= vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes)
+         return 0;
 
-      if (byte_pos + len > vfs_cdrom_toc.track[stream->track->cur_track - 1].track_bytes)
-         len -= (byte_pos + len) - vfs_cdrom_toc.track[stream->track->cur_track - 1].track_bytes;
+      if (stream->cdrom.byte_pos + len > vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes)
+         len -= (stream->cdrom.byte_pos + len) - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].track_bytes;
 
-      cdrom_lba_to_msf(stream->track->cur_lba, &min, &sec, &frame);
-      cdrom_lba_to_msf(stream->track->cur_lba - vfs_cdrom_toc.track[stream->track->cur_track - 1].lba, &rmin, &rsec, &rframe);
+      cdrom_lba_to_msf(stream->cdrom.cur_lba, &min, &sec, &frame);
+      cdrom_lba_to_msf(stream->cdrom.cur_lba - vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba, &rmin, &rsec, &rframe);
 
 #ifdef CDROM_DEBUG
-      printf("[CDROM] Read: Reading %" PRIu64 " bytes from %s starting at byte offset %" PRIu64 " (rMSF %02u:%02u:%02u aMSF %02u:%02u:%02u) (LBA %u)...\n", len, stream->orig_path, byte_pos, (unsigned)rmin, (unsigned)rsec, (unsigned)rframe, (unsigned)min, (unsigned)sec, (unsigned)frame, stream->track->cur_lba);
+      printf("[CDROM] Read: Reading %" PRIu64 " bytes from %s starting at byte offset %" PRIu64 " (rMSF %02u:%02u:%02u aMSF %02u:%02u:%02u) (LBA %u) skip %" PRIu64 "...\n", len, stream->orig_path, stream->cdrom.byte_pos, (unsigned)rmin, (unsigned)rsec, (unsigned)rframe, (unsigned)min, (unsigned)sec, (unsigned)frame, stream->cdrom.cur_lba, skip);
       fflush(stdout);
 #endif
 
-      rv = cdrom_read(stream, &vfs_cdrom_toc.timeouts, min, sec, frame, s, (size_t)len, 0);
+      rv = cdrom_read(stream, &vfs_cdrom_toc.timeouts, min, sec, frame, s, (size_t)len, skip);
       /*rv = cdrom_read_lba(stream, stream->cdrom.cur_lba, s, (size_t)len, skip);*/
 
       if (rv)
@@ -718,256 +393,31 @@ static void retro_vfs_file_read_cdrom_track_sector(libretro_vfs_implementation_f
          printf("[CDROM] Failed to read %" PRIu64 " bytes from CD.\n", len);
          fflush(stdout);
 #endif
-      }
-   }
-#endif
-}
-
-int64_t retro_vfs_file_read_cdrom_track(libretro_vfs_implementation_file *stream, void *s, uint64_t len)
-{
-   uint64_t bytes_read = 0;
-
-   if (!stream->parent)
-      return -1;
-
-   if (stream->track->last_frame_lba == stream->track->cur_lba)
-   {
-      const int used = stream->track->byte_pos % stream->track->sector_size;
-      int remaining = stream->track->sector_size - used;
-      if (remaining > len)
-      {
-         memcpy(s, stream->track->last_frame + used, len);
-         stream->track->byte_pos += len;
-         return len;
+         return 0;
       }
 
-      memcpy(s, stream->track->last_frame + used, remaining);
-      s = (char*)s + remaining;
-      len -= remaining;
-      bytes_read += remaining;
+      stream->cdrom.byte_pos += len;
+      stream->cdrom.cur_lba = vfs_cdrom_toc.track[stream->cdrom.cur_track - 1].lba + (stream->cdrom.byte_pos / 2352);
 
-      stream->track->cur_lba++;
-      retro_vfs_file_seek_cdrom_track_sector(stream, stream->track->cur_lba);
-   }
-
-   while (len >= stream->track->sector_size)
-   {
-      retro_vfs_file_read_cdrom_track_sector(stream, s, stream->track->sector_size);
-      s = (char*)s + 2352;
-
-      stream->track->cur_lba++;
-
-      bytes_read += 2352;
-      len -= 2352;
-   }
-
-   stream->track->byte_pos = stream->track->cur_lba * stream->track->sector_size;
-
-   if (len > 0)
-   {
-      retro_vfs_file_read_cdrom_track_sector(stream, stream->track->last_frame, stream->track->sector_size);
-      memcpy(s, stream->track->last_frame, len);
-      bytes_read += len;
-
-      stream->track->byte_pos += len;
-      stream->track->last_frame_lba = stream->track->cur_lba;
-
-#ifdef HAVE_CDROM
-      cdrom_lba_to_msf(stream->track->cur_lba, &stream->track->cur_min, &stream->track->cur_sec, &stream->track->cur_frame);
-#endif
-   }
-
-   return bytes_read;
-}
-
-int64_t retro_vfs_file_tell_cdrom_track(libretro_vfs_implementation_file* stream)
-{
-   return stream->track->byte_pos;
-}
-
-static int retro_vfs_file_find_cdrom_file_sector(libretro_vfs_implementation_file* track_stream, const char* path, unsigned* file_size)
-{
-   uint8_t buffer[2352], *tmp;
-   int sector, path_length;
-
-   const char* slash = strrchr(path, '\\');
-   if (slash)
-   {
-      /* navigate the path to the directory record for the file */
-      const int dir_length = (int)(slash - path);
-      memcpy(buffer, path, dir_length);
-      buffer[dir_length] = '\0';
-
-      sector = retro_vfs_file_find_cdrom_file_sector(track_stream, (const char*)buffer, NULL);
-      if (sector < 0)
-         return sector;
-
-      path += dir_length + 1;
-   }
-   else
-   {
-      int offset;
-
-      /* find the cd information (always 16 frames in) */
-      retro_vfs_file_seek_cdrom_track_sector(track_stream, 16);
-      retro_vfs_file_read_cdrom_track(track_stream, buffer, sizeof(buffer));
-
-      /* the directory_record starts at 156 bytes into the sector.
-      * the sector containing the table of contents is a 3 byte value that is 2 bytes into the directory_record. */
-      offset = track_stream->track->sector_header_size + 156 + 2;
-      sector = buffer[offset] | (buffer[offset + 1] << 8) | (buffer[offset + 2] << 16);
-   }
-
-   /* process the table of contents */
-   retro_vfs_file_seek_cdrom_track_sector(track_stream, sector);
-   retro_vfs_file_read_cdrom_track(track_stream, buffer, sizeof(buffer));
-
-   path_length = strlen(path);
-   tmp = buffer + track_stream->track->sector_header_size;
-   while (tmp < buffer + sizeof(buffer))
-   {
-      /* the first byte of the record is the length of the record - if 0, we reached the end of the data */
-      if (!*tmp)
-         break;
-
-      /* filename is 33 bytes into the record and the format is "FILENAME;version" or "DIRECTORY" */
-      if ((tmp[33 + path_length] == ';' || tmp[33 + path_length] == '\0') &&
-         strncasecmp((const char*)(tmp + 33), path, path_length) == 0)
-      {
-         /* the file contents are in the sector identified in bytes 2-4 of the record */
-         sector = tmp[2] | (tmp[3] << 8) | (tmp[4] << 16);
-         retro_vfs_file_seek_cdrom_track_sector(track_stream, sector);
-
-         /* the file size is in bytes 10-13 of the record */
-         if (file_size)
-            *file_size = tmp[10] | (tmp[11] << 8) | (tmp[12] << 16) | (tmp[13] << 24);
+      cdrom_lba_to_msf(stream->cdrom.cur_lba, &stream->cdrom.cur_min, &stream->cdrom.cur_sec, &stream->cdrom.cur_frame);
 
 #ifdef CDROM_DEBUG
-         {
-            unsigned char min, sec, frame;
-            cdrom_lba_to_msf(sector, &min, &sec, &frame);
-            printf("[CDROM] found %s (MSF %02u:%02u:%02u) (LBA %u)\n", path, (unsigned)min, (unsigned)sec, (unsigned)frame, sector);
-            fflush(stdout);
-         }
+      printf("[CDROM] read %" PRIu64 " bytes, position is now: %" PRIu64 " (MSF %02u:%02u:%02u) (LBA %u)\n", len, stream->cdrom.byte_pos, (unsigned)stream->cdrom.cur_min, (unsigned)stream->cdrom.cur_sec, (unsigned)stream->cdrom.cur_frame, cdrom_msf_to_lba(stream->cdrom.cur_min, stream->cdrom.cur_sec, stream->cdrom.cur_frame));
+      fflush(stdout);
 #endif
 
-         return sector;
-      }
-
-      /* the first byte of the record is the length of the record */
-      tmp += tmp[0];
+      return len;
    }
 
-#ifdef CDROM_DEBUG
-   printf("[CDROM] did not find %s\n", path);
-   fflush(stdout);
-#endif
-
-   return -1;
+   return 0;
 }
 
-libretro_vfs_implementation_file* retro_vfs_file_open_cdrom_file(libretro_vfs_implementation_file* track_stream, const char* path)
+int retro_vfs_file_error_cdrom(libretro_vfs_implementation_file *stream)
 {
-   libretro_vfs_implementation_file* file_stream;
-   unsigned file_size = 0;
-
-   int sector = retro_vfs_file_find_cdrom_file_sector(track_stream, path, &file_size);
-   if (sector < 0)
-      return NULL;
-
-   file_stream = (libretro_vfs_implementation_file*)calloc(1, sizeof(*file_stream));
-   file_stream->scheme = (track_stream->scheme == VFS_SCHEME_CDROM_TRACK) ? VFS_SCHEME_CDROM_FILE : VFS_SCHEME_CUE_BIN_FILE;
-   file_stream->parent = track_stream;
-   file_stream->parent_offset = sector * 2352 + track_stream->track->sector_header_size;
-   file_stream->orig_path = strdup(path);
-   file_stream->size = file_size;
-
-   return file_stream;
+   return 0;
 }
 
-int64_t retro_vfs_file_tell_cdrom_file(libretro_vfs_implementation_file* stream)
+const vfs_cdrom_t* retro_vfs_file_get_cdrom_position(const libretro_vfs_implementation_file *stream)
 {
-   if (stream->parent != NULL && stream->parent->track)
-   {
-      const int64_t current_offset_raw = stream->parent->track->byte_pos - stream->parent_offset;
-      return (current_offset_raw / stream->parent->track->sector_size) * 2048 + (current_offset_raw % stream->parent->track->sector_size);
-   }
-
-   return -1;
-}
-
-int64_t retro_vfs_file_seek_cdrom_file(libretro_vfs_implementation_file* stream, int64_t offset, int whence)
-{
-   int64_t offset_raw;
-   switch (whence)
-   {
-      case SEEK_CUR:
-      {
-         const int64_t current_offset_raw = stream->parent->track->byte_pos - stream->parent_offset;
-         const int64_t current_offset = (current_offset_raw / stream->parent->track->sector_size) * 2048 + (current_offset_raw % stream->parent->track->sector_size);
-         offset = current_offset + offset;
-         break;
-      }
-
-      case SEEK_END:
-         offset = stream->size - offset;
-         break;
-   }
-
-   offset_raw = (offset / 2048) * stream->parent->track->sector_size + (offset % 2048);
-
-   return retro_vfs_file_seek_cdrom_track(stream->parent, offset_raw, SEEK_SET);
-}
-
-int64_t retro_vfs_file_read_cdrom_file(libretro_vfs_implementation_file* stream, void* s, uint64_t len)
-{
-   uint8_t buffer[2352];
-   int64_t bytes_read = 0;
-
-   if (!stream || !stream->parent || !stream->parent->track)
-      return 0;
-
-   if (stream->parent->track->last_frame_lba == stream->parent->track->cur_lba)
-   {
-      const int used = stream->parent->track->byte_pos % stream->parent->track->sector_size - stream->parent->track->sector_header_size;
-      int remaining = 2048 - used;
-      if (remaining > 0)
-      {
-         if (remaining > len)
-         {
-            retro_vfs_file_read_cdrom_track(stream->parent, s, len);
-            return len;
-         }
-
-         retro_vfs_file_read_cdrom_track(stream->parent, s, remaining);
-         s = (char*)s + remaining;
-         bytes_read += remaining;
-      }
-
-      stream->parent->track->cur_lba = stream->parent->track->last_frame_lba + 1;
-   }
-
-   while (len >= 2048)
-   {
-      retro_vfs_file_read_cdrom_track_sector(stream->parent, buffer, stream->parent->track->sector_size);
-      stream->parent->track->cur_lba++;
-
-      memcpy(s, buffer + stream->parent->track->sector_header_size, 2048);
-      s = (char*)s + 2048;
-      bytes_read += 2048;
-      len -= 2048;
-   }
-
-   stream->parent->track->byte_pos = stream->parent->track->cur_lba * stream->parent->track->sector_size;
-
-   if (len > 0)
-   {
-      retro_vfs_file_read_cdrom_track(stream->parent, buffer, len + stream->parent->track->sector_header_size);
-      memcpy(s, buffer + stream->parent->track->sector_header_size, len);
-
-      stream->parent->track->byte_pos += len;
-      bytes_read += len;
-   }
-
-   return bytes_read;
+   return &stream->cdrom;
 }