From 5c27083af6567030abd8dc38aeaa7103cfea372c Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 25 Nov 2024 21:23:28 +0100 Subject: [PATCH] CD-ROM interface API to get raw track data, IOCTL now actually provides it, and IOCTL is now actually instantiable, as well as cleaned up a bit. --- src/cdrom/cdrom.c | 133 ++++++- src/cdrom/cdrom_image.c | 31 +- src/cdrom/cdrom_image_backend.c | 1 - src/cdrom/cdrom_ioctl.c | 57 +-- src/include/86box/cdrom.h | 17 +- src/include/86box/cdrom_image_backend.h | 27 +- src/include/86box/plat_cdrom.h | 30 +- src/qt/dummy_cdrom_ioctl.c | 121 ++++--- src/qt/qt_settingsfloppycdrom.cpp | 2 +- src/qt/win_cdrom_ioctl.c | 442 +++++++++++++++--------- src/unix/dummy_cdrom_ioctl.c | 117 ++++--- 11 files changed, 671 insertions(+), 307 deletions(-) diff --git a/src/cdrom/cdrom.c b/src/cdrom/cdrom.c index ff83b0a07..0bdcb5fb8 100644 --- a/src/cdrom/cdrom.c +++ b/src/cdrom/cdrom.c @@ -1167,27 +1167,81 @@ read_toc_session(cdrom_t *dev, unsigned char *b, int msf) static int read_toc_raw(cdrom_t *dev, unsigned char *b) { - track_info_t ti; - int len = 4; - int first_track; - int last_track; - - cdrom_log("read_toc_raw(%08X, %08X)\n", dev, b); - - dev->ops->get_tracks(dev, &first_track, &last_track); + track_info_t ti; + raw_track_info_t rti[256] = { 0 }; + int num = 0; + int len = 4; + int first_track; + int last_track; /* Bytes 2 and 3 = Number of first and last sessions */ b[2] = b[3] = 1; - for (int i = 0; i <= last_track; i++) { - dev->ops->get_track_info(dev, i + 1, 0, &ti); + if (dev->ops->get_raw_track_info != NULL) { + cdrom_log("read_toc_raw(%08X, %08X): Raw tracks\n", dev, b); + pclog("read_toc_raw(%016" PRIXPTR ", %016" PRIXPTR "): Raw tracks\n", + (uintptr_t) dev, (uintptr_t) b); + + dev->ops->get_raw_track_info(dev, &num, (raw_track_info_t *) rti); + + if (num != 0) for (int i = 0; i < num; i++) { + b[len++] = rti[i].session; + b[len++] = rti[i].adr_ctl; + b[len++] = rti[i].tno; + b[len++] = rti[i].point; + b[len++] = rti[i].m; + b[len++] = rti[i].s; + b[len++] = rti[i].f; + b[len++] = rti[i].zero; + b[len++] = rti[i].pm; + b[len++] = rti[i].ps; + b[len++] = rti[i].pf; + } + } else { + cdrom_log("read_toc_raw(%08X, %08X): Cooked tracks\n", dev, b); + pclog("read_toc_raw(%016" PRIXPTR ", %016" PRIXPTR "): Cooked tracks\n", + (uintptr_t) dev, (uintptr_t) b); + + dev->ops->get_tracks(dev, &first_track, &last_track); + + dev->ops->get_track_info(dev, 1, 0, &ti); + + b[len++] = 1; /* Session number */ + b[len++] = ti.attr; /* Track ADR and Control */ + b[len++] = 0; /* TNO (always 0) */ + b[len++] = 0xA0; /* Point (for track points - track number) */ + /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = ti.number; /* First track number */ + b[len++] = 0; + b[len++] = 0; + + dev->ops->get_track_info(dev, last_track, 0, &ti); + + b[len++] = 1; /* Session number */ + b[len++] = ti.attr; /* Track ADR and Control */ + b[len++] = 0; /* TNO (always 0) */ + b[len++] = 0xA1; /* Point (for track points - track number) */ + /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = ti.number; /* First track number */ + b[len++] = 0; + b[len++] = 0; + + dev->ops->get_track_info(dev, last_track + 1, 0, &ti); cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); b[len++] = 1; /* Session number */ b[len++] = ti.attr; /* Track ADR and Control */ b[len++] = 0; /* TNO (always 0) */ - b[len++] = ti.number; /* Point (for track points - track number) */ + b[len++] = 0xA2; /* Point (for track points - track number) */ /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ b[len++] = 0; b[len++] = 0; @@ -1196,6 +1250,25 @@ read_toc_raw(cdrom_t *dev, unsigned char *b) b[len++] = ti.m; /* PM */ b[len++] = ti.s; /* PS */ b[len++] = ti.f; /* PF */ + + for (int i = 0; i < last_track; i++) { + dev->ops->get_track_info(dev, i + 1, 0, &ti); + + cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f); + + b[len++] = 1; /* Session number */ + b[len++] = ti.attr; /* Track ADR and Control */ + b[len++] = 0; /* TNO (always 0) */ + b[len++] = ti.number; /* Point (for track points - track number) */ + /* Yes, this is correct - MSF followed by PMSF, the actual position is in PMSF. */ + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = ti.m; /* PM */ + b[len++] = ti.s; /* PS */ + b[len++] = ti.f; /* PF */ + } } return len; @@ -1954,6 +2027,22 @@ cdrom_drive_reset(cdrom_t *dev) dev->get_channel = NULL; } +/* Will be removed later. */ +#ifdef ENABLE_CDROM_LOG +static void +cdrom_toc_dump(cdrom_t *dev) +{ + uint8_t b[65536] = { 0 }; + int len = cdrom_read_toc(dev, b, CD_TOC_RAW, 0, 0, 65536); + const char *fn2 = "d:\\86boxnew\\toc_cue.dmp"; + FILE * f = fopen(fn2, "wb"); + fwrite(b, 1, len, f); + fflush(f); + fclose(f); + pclog("Written TOC of %i bytes to %s\n", len, fn2); +} +#endif + void cdrom_hard_reset(void) { @@ -1994,6 +2083,10 @@ cdrom_hard_reset(void) cdrom_ioctl_open(dev, dev->image_path); else cdrom_image_open(dev, dev->image_path); + +#ifdef ENABLE_CDROM_LOG + cdrom_toc_dump(dev); +#endif } } } @@ -2095,15 +2188,13 @@ cdrom_reload(uint8_t id) strcpy(dev->image_path, dev->prev_image_path); #ifdef _WIN32 - if (strlen(dev->prev_image_path) > 0) { - if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) - dev->image_path[strlen(dev->image_path) - 1] = '\\'; - } + if ((strlen(dev->prev_image_path) > 0) && (strlen(dev->image_path) >= 1) && + (dev->image_path[strlen(dev->image_path) - 1] == '/')) + dev->image_path[strlen(dev->image_path) - 1] = '\\'; #else - if (strlen(dev->prev_image_path) > 0) { - if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\')) - dev->image_path[strlen(dev->image_path) - 1] = '/'; - } + if ((strlen(dev->prev_image_path) > 0) && (strlen(dev->image_path) >= 1) && + (dev->image_path[strlen(dev->image_path) - 1] == '\\')) + dev->image_path[strlen(dev->image_path) - 1] = '/'; #endif if ((strlen(dev->image_path) != 0) && (strstr(dev->image_path, "ioctl://") == dev->image_path)) @@ -2111,6 +2202,10 @@ cdrom_reload(uint8_t id) else cdrom_image_open(dev, dev->image_path); +#ifdef ENABLE_CDROM_LOG + cdrom_toc_dump(dev); +#endif + cdrom_insert(id); } diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 113d426c6..0ff914795 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -61,7 +61,7 @@ cdrom_image_log(const char *fmt, ...) static void image_get_tracks(cdrom_t *dev, int *first, int *last) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; TMSF tmsf; cdi_get_audio_tracks(img, first, last, &tmsf); @@ -70,7 +70,7 @@ image_get_tracks(cdrom_t *dev, int *first, int *last) static void image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; TMSF tmsf; cdi_get_audio_track_info(img, end, track, &ti->number, &tmsf, &ti->attr); @@ -83,7 +83,7 @@ image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti) static void image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; TMSF rel_pos; TMSF abs_pos; @@ -105,7 +105,7 @@ image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) static int image_get_capacity(cdrom_t *dev) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; int first_track; int last_track; int number; @@ -130,7 +130,7 @@ image_get_capacity(cdrom_t *dev) static int image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; uint8_t attr; TMSF tmsf; int m; @@ -162,7 +162,7 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) static int image_is_track_pre(cdrom_t *dev, uint32_t lba) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; int track; /* GetTrack requires LBA. */ @@ -177,7 +177,7 @@ image_is_track_pre(cdrom_t *dev, uint32_t lba) static int image_sector_size(struct cdrom *dev, uint32_t lba) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; return cdi_get_sector_size(img, lba); } @@ -185,7 +185,7 @@ image_sector_size(struct cdrom *dev, uint32_t lba) static int image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; switch (type) { case CD_READ_DATA: @@ -206,7 +206,7 @@ image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba) static int image_track_type(cdrom_t *dev, uint32_t lba) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; if (img) { if (image_is_track_audio(dev, lba, 0)) @@ -229,14 +229,14 @@ image_ext_medium_changed(cdrom_t *dev) static void image_exit(cdrom_t *dev) { - cd_img_t *img = (cd_img_t *) dev->image; + cd_img_t *img = (cd_img_t *) dev->local; cdrom_image_log("CDROM: image_exit(%s)\n", dev->image_path); dev->cd_status = CD_STATUS_EMPTY; if (img) { cdi_close(img); - dev->image = NULL; + dev->local = NULL; } dev->ops = NULL; @@ -245,6 +245,7 @@ image_exit(cdrom_t *dev) static const cdrom_ops_t cdrom_image_ops = { image_get_tracks, image_get_track_info, + NULL, image_get_subchannel, image_is_track_pre, image_sector_size, @@ -282,7 +283,7 @@ cdrom_image_open(cdrom_t *dev, const char *fn) return image_open_abort(dev); memset(img, 0, sizeof(cd_img_t)); - dev->image = img; + dev->local = img; /* Open the image. */ int i = cdi_set_device(img, fn); @@ -298,6 +299,12 @@ cdrom_image_open(cdrom_t *dev, const char *fn) dev->cd_buflen = 0; dev->cdrom_capacity = image_get_capacity(dev); cdrom_image_log("CD-ROM capacity: %i sectors (%" PRIi64 " bytes)\n", dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity) << 11ULL); + int cm, cs, cf; + cf = dev->cdrom_capacity % 75; + cs = (dev->cdrom_capacity / 75) % 60; + cm = (dev->cdrom_capacity / 75) / 60; + pclog("CD-ROM capacity: %i sectors (%" PRIi64 " bytes) (time: %02i:%02i:%02i)\n", + dev->cdrom_capacity, ((uint64_t) dev->cdrom_capacity - 150ULL) * 2352ULL, cm, cs, cf); /* Attach this handler to the drive. */ dev->ops = &cdrom_image_ops; diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index f1d5ed1f9..2578e9e33 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -1189,7 +1189,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile) /* Add lead out track. */ trk.number++; trk.track_number = 0xAA; - trk.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ trk.start = 0; trk.length = 0; trk.file = NULL; diff --git a/src/cdrom/cdrom_ioctl.c b/src/cdrom/cdrom_ioctl.c index 13df2d965..f25988bb9 100644 --- a/src/cdrom/cdrom_ioctl.c +++ b/src/cdrom/cdrom_ioctl.c @@ -28,9 +28,9 @@ #include <86box/config.h> #include <86box/path.h> #include <86box/plat.h> -#include <86box/plat_cdrom.h> #include <86box/scsi_device.h> #include <86box/cdrom.h> +#include <86box/plat_cdrom.h> #ifdef ENABLE_CDROM_IOCTL_LOG int cdrom_ioctl_do_log = ENABLE_CDROM_IOCTL_LOG; @@ -56,19 +56,19 @@ cdrom_ioctl_log(const char *fmt, ...) #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) static void -ioctl_get_tracks(UNUSED(cdrom_t *dev), int *first, int *last) +ioctl_get_tracks(cdrom_t *dev, int *first, int *last) { TMSF tmsf; - plat_cdrom_get_audio_tracks(first, last, &tmsf); + plat_cdrom_get_audio_tracks(dev->local, first, last, &tmsf); } static void -ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_info_t *ti) +ioctl_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti) { TMSF tmsf; - plat_cdrom_get_audio_track_info(end, track, &ti->number, &tmsf, &ti->attr); + plat_cdrom_get_audio_track_info(dev->local, end, track, &ti->number, &tmsf, &ti->attr); ti->m = tmsf.min; ti->s = tmsf.sec; @@ -76,13 +76,19 @@ ioctl_get_track_info(UNUSED(cdrom_t *dev), uint32_t track, int end, track_info_t } static void -ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) +ioctl_get_raw_track_info(cdrom_t *dev, int *num, raw_track_info_t *rti) +{ + plat_cdrom_get_raw_track_info(dev->local, num, rti); +} + +static void +ioctl_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) { TMSF rel_pos; TMSF abs_pos; if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) { - const uint32_t trk = plat_cdrom_get_track_start(lba, &subc->attr, &subc->track); + const uint32_t trk = plat_cdrom_get_track_start(dev->local, lba, &subc->attr, &subc->track); FRAMES_TO_MSF(lba + 150, &abs_pos.min, &abs_pos.sec, &abs_pos.fr); @@ -91,7 +97,7 @@ ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) subc->index = 1; } else - plat_cdrom_get_audio_sub(lba, &subc->attr, &subc->track, &subc->index, + plat_cdrom_get_audio_sub(dev->local, lba, &subc->attr, &subc->track, &subc->index, &rel_pos, &abs_pos); subc->abs_m = abs_pos.min; @@ -107,11 +113,11 @@ ioctl_get_subchannel(UNUSED(cdrom_t *dev), uint32_t lba, subchannel_t *subc) } static int -ioctl_get_capacity(UNUSED(cdrom_t *dev)) +ioctl_get_capacity(cdrom_t *dev) { int ret; - ret = plat_cdrom_get_last_block(); + ret = plat_cdrom_get_last_block(dev->local); cdrom_ioctl_log("GetCapacity=%x.\n", ret); return ret; } @@ -134,35 +140,35 @@ ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) } /* GetTrack requires LBA. */ - return plat_cdrom_is_track_audio(pos); + return plat_cdrom_is_track_audio(dev->local, pos); } static int -ioctl_is_track_pre(UNUSED(cdrom_t *dev), uint32_t lba) +ioctl_is_track_pre(cdrom_t *dev, uint32_t lba) { - return plat_cdrom_is_track_pre(lba); + return plat_cdrom_is_track_pre(dev->local, lba); } static int -ioctl_sector_size(UNUSED(cdrom_t *dev), uint32_t lba) +ioctl_sector_size(cdrom_t *dev, uint32_t lba) { cdrom_ioctl_log("LBA=%x.\n", lba); - return plat_cdrom_get_sector_size(lba); + return plat_cdrom_get_sector_size(dev->local, lba); } static int -ioctl_read_sector(UNUSED(cdrom_t *dev), int type, uint8_t *b, uint32_t lba) +ioctl_read_sector(cdrom_t *dev, int type, uint8_t *b, uint32_t lba) { switch (type) { case CD_READ_DATA: cdrom_ioctl_log("cdrom_ioctl_read_sector(): Data.\n"); - return plat_cdrom_read_sector(b, 0, lba); + return plat_cdrom_read_sector(dev->local, b, 0, lba); case CD_READ_AUDIO: cdrom_ioctl_log("cdrom_ioctl_read_sector(): Audio.\n"); - return plat_cdrom_read_sector(b, 1, lba); + return plat_cdrom_read_sector(dev->local, b, 1, lba); case CD_READ_RAW: cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n"); - return plat_cdrom_read_sector(b, 1, lba); + return plat_cdrom_read_sector(dev->local, b, 1, lba); default: cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n"); break; @@ -191,7 +197,7 @@ ioctl_ext_medium_changed(cdrom_t *dev) if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) ret = 0; else - ret = plat_cdrom_ext_medium_changed(); + ret = plat_cdrom_ext_medium_changed(dev->local); if (ret == 1) { dev->cd_status = CD_STATUS_STOPPED; @@ -208,7 +214,8 @@ ioctl_exit(cdrom_t *dev) cdrom_ioctl_log("CDROM: ioctl_exit(%s)\n", dev->image_path); dev->cd_status = CD_STATUS_EMPTY; - plat_cdrom_close(); + plat_cdrom_close(dev->local); + dev->local = NULL; dev->ops = NULL; } @@ -216,6 +223,7 @@ ioctl_exit(cdrom_t *dev) static const cdrom_ops_t cdrom_ioctl_ops = { ioctl_get_tracks, ioctl_get_track_info, + ioctl_get_raw_track_info, ioctl_get_subchannel, ioctl_is_track_pre, ioctl_sector_size, @@ -238,9 +246,10 @@ int cdrom_ioctl_open(cdrom_t *dev, const char *drv) { const char *actual_drv = &(drv[8]); + int local_size = plat_cdrom_get_local_size(); /* Make sure to not STRCPY if the two are pointing - at the same place. */ + at the same place. */ if (drv != dev->image_path) strcpy(dev->image_path, drv); @@ -248,7 +257,9 @@ cdrom_ioctl_open(cdrom_t *dev, const char *drv) if (strstr(drv, "ioctl://") != drv) return cdrom_ioctl_open_abort(dev); cdrom_ioctl_log("actual_drv = %s\n", actual_drv); - int i = plat_cdrom_set_drive(actual_drv); + if (dev->local == NULL) + dev->local = calloc(1, local_size); + int i = plat_cdrom_set_drive(dev->local, actual_drv); if (!i) return cdrom_ioctl_open_abort(dev); diff --git a/src/include/86box/cdrom.h b/src/include/86box/cdrom.h index 636c151ce..0a28e630d 100644 --- a/src/include/86box/cdrom.h +++ b/src/include/86box/cdrom.h @@ -195,10 +195,25 @@ typedef struct track_info_t { uint8_t f; } track_info_t; +typedef struct raw_track_info_t { + uint8_t session; + uint8_t adr_ctl; + uint8_t tno; + uint8_t point; + uint8_t m; + uint8_t s; + uint8_t f; + uint8_t zero; + uint8_t pm; + uint8_t ps; + uint8_t pf; +} raw_track_info_t; + /* Define the various CD-ROM drive operations (ops). */ typedef struct cdrom_ops_t { void (*get_tracks)(struct cdrom *dev, int *first, int *last); void (*get_track_info)(struct cdrom *dev, uint32_t track, int end, track_info_t *ti); + void (*get_raw_track_info)(struct cdrom *dev, int *num, raw_track_info_t *rti); void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc); int (*is_track_pre)(struct cdrom *dev, uint32_t lba); int (*sector_size)(struct cdrom *dev, uint32_t lba); @@ -248,7 +263,7 @@ typedef struct cdrom { const cdrom_ops_t *ops; - void *image; + void *local; void (*insert)(void *priv); void (*close)(void *priv); diff --git a/src/include/86box/cdrom_image_backend.h b/src/include/86box/cdrom_image_backend.h index cf4fe95c3..c6b2d9fc7 100644 --- a/src/include/86box/cdrom_image_backend.h +++ b/src/include/86box/cdrom_image_backend.h @@ -57,7 +57,31 @@ typedef struct track_file_t { int motorola; } track_file_t; +#define BLOCK_EMPTY 0 /* Empty block. */ +#define BLOCK_ZERO 1 /* Block not in the file, return all 0x00's. */ +#define BLOCK_NORMAL 2 /* Block in the file. */ + +#define BLOCK_NONE ((uint64_t) -1LL) + +typedef struct track_block_t { + /* Is the current block in the file? If not, return all 0x00's. */ + int type; + /* The amount of bytes to skip at the beginning of each sector. */ + int skip; + /* Starting and ending sector LBA - negative in order to accomodate LBA -150 to -1 + to read the pregap of track 1. */ + int64_t start_sector; + int64_t end_sector; + /* Starting and ending offset in the file. */ + uint64_t start_offs; + uint64_t end_offs; +} track_block_t; + typedef struct track_t { + int pregap_len; /* Pre-gap - not in file. */ + int index0_len; /* Pre-gap - in file. */ + int postgap_len; /* Post-gap - not in file. */ + int blocks_num; /* Number of blocks. */ int number; int track_number; int attr; @@ -65,10 +89,11 @@ typedef struct track_t { int mode2; int form; int pre; - int noskip; /* Do not skip by 8 bytes.*/ + int noskip; /* Do not skip by 8 bytes.*/ uint64_t start; uint64_t length; uint64_t skip; + track_block_t blocks[256]; track_file_t *file; } track_t; diff --git a/src/include/86box/plat_cdrom.h b/src/include/86box/plat_cdrom.h index 8e81f9459..06439a652 100644 --- a/src/include/86box/plat_cdrom.h +++ b/src/include/86box/plat_cdrom.h @@ -49,19 +49,23 @@ typedef struct SMSF { uint8_t fr; } TMSF; -extern int plat_cdrom_is_track_audio(uint32_t sector); -extern int plat_cdrom_is_track_pre(uint32_t sector); -extern uint32_t plat_cdrom_get_last_block(void); -extern void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out); -extern int plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr); -extern int plat_cdrom_get_audio_sub(uint32_t sector, uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); -extern int plat_cdrom_get_sector_size(uint32_t sector); -extern int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector); -extern void plat_cdrom_eject(void); -extern void plat_cdrom_close(void); -extern int plat_cdrom_set_drive(const char *drv); -extern int plat_cdrom_ext_medium_changed(void); -extern uint32_t plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track); +extern void plat_cdrom_get_raw_track_info(void *local, int *num, raw_track_info_t *rti); +extern int plat_cdrom_is_track_audio(void *local, uint32_t sector); +extern int plat_cdrom_is_track_pre(void *local, uint32_t sector); +extern uint32_t plat_cdrom_get_last_block(void *local); +extern void plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out); +extern int plat_cdrom_get_audio_track_info(void *local, int end, int track, int *track_num, TMSF *start, + uint8_t *attr); +extern int plat_cdrom_get_audio_sub(void *local, uint32_t sector, uint8_t *attr, uint8_t *track, + uint8_t *index, TMSF *rel_pos, TMSF *abs_pos); +extern int plat_cdrom_get_sector_size(void *local, uint32_t sector); +extern int plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector); +extern void plat_cdrom_eject(void *local); +extern void plat_cdrom_close(void *local); +extern int plat_cdrom_set_drive(void *local, const char *drv); +extern int plat_cdrom_ext_medium_changed(void *local); +extern uint32_t plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track); +extern int plat_cdrom_get_local_size(void); #ifdef __cplusplus } diff --git a/src/qt/dummy_cdrom_ioctl.c b/src/qt/dummy_cdrom_ioctl.c index fed1444d1..bf656177b 100644 --- a/src/qt/dummy_cdrom_ioctl.c +++ b/src/qt/dummy_cdrom_ioctl.c @@ -35,7 +35,9 @@ of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static int toc_valid = 0; +typedef struct dummy_cdrom_ioctl_t { + int toc_valid; +} dummy_cdrom_ioctl_t; #ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG; @@ -56,30 +58,41 @@ dummy_cdrom_ioctl_log(const char *fmt, ...) #endif static int -plat_cdrom_open(void) +plat_cdrom_open(void *local) { return 0; } static int -plat_cdrom_load(void) +plat_cdrom_load(void *local) { return 0; } static void -plat_cdrom_read_toc(void) +plat_cdrom_read_toc(void *local) { - if (!toc_valid) - toc_valid = 1; + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + if (!ioctl->toc_valid) + ioctl->toc_valid = 1; +} + +void +plat_cdrom_get_raw_track_info(UNUSED(void *local), int *num, raw_track_info_t *rti) +{ + *num = 1; + memset(rti, 0x00, 11); } int -plat_cdrom_is_track_audio(uint32_t sector) +plat_cdrom_is_track_audio(void *local, uint32_t sector) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; - const int ret = 0; + plat_cdrom_read_toc(ioctl); + + const int ret = 0; dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); @@ -87,9 +100,11 @@ plat_cdrom_is_track_audio(uint32_t sector) } int -plat_cdrom_is_track_pre(uint32_t sector) +plat_cdrom_is_track_pre(void *local, uint32_t sector) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); const int ret = 0; @@ -99,25 +114,30 @@ plat_cdrom_is_track_pre(uint32_t sector) } uint32_t -plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) +plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); return 0x00000000; } uint32_t -plat_cdrom_get_last_block(void) +plat_cdrom_get_last_block(void *local) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); return 0x00000000; } int -plat_cdrom_ext_medium_changed(void) +plat_cdrom_ext_medium_changed(void *local) { - int ret = 0; + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + int ret = 0; dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); @@ -125,9 +145,11 @@ plat_cdrom_ext_medium_changed(void) } void -plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) +plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); *st_track = 1; *end = 1; @@ -141,9 +163,11 @@ plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) /* This replaces both Info and EndInfo, they are specified by a variable. */ int -plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) +plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); if ((track < 1) || (track == 0xaa)) { dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); @@ -165,7 +189,8 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF /* TODO: See if track start is adjusted by 150 or not. */ int -plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) +plat_cdrom_get_audio_sub(UNUSED(void *local), UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, + TMSF *rel_pos, TMSF *abs_pos) { *track = 1; *attr = 0x14; @@ -185,7 +210,7 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, } int -plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) +plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector)) { dummy_cdrom_ioctl_log("BytesPerSector=2048\n"); @@ -193,42 +218,56 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) } int -plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) +plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector) { - plat_cdrom_open(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; - if (raw) { - dummy_cdrom_ioctl_log("Raw\n"); + plat_cdrom_open(ioctl); + + if (raw) /* Raw */ - } else { - dummy_cdrom_ioctl_log("Cooked\n"); + dummy_cdrom_ioctl_log("Raw\n"); + else /* Cooked */ - } - plat_cdrom_close(); - dummy_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size); + dummy_cdrom_ioctl_log("Cooked\n"); - return -1; + plat_cdrom_close(ioctl); + + dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector); + + return 0; } void -plat_cdrom_eject(void) +plat_cdrom_eject(void *local) { - plat_cdrom_open(); - plat_cdrom_close(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_open(ioctl); + plat_cdrom_close(ioctl); } void -plat_cdrom_close(void) +plat_cdrom_close(UNUSED(void *local)) { } int -plat_cdrom_set_drive(const char *drv) +plat_cdrom_set_drive(void *local, const char *drv) { - plat_cdrom_close(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; - toc_valid = 0; + plat_cdrom_close(ioctl); + + ioctl->toc_valid = 0; + + plat_cdrom_load(ioctl); - plat_cdrom_load(); return 1; } + +int +plat_cdrom_get_local_size(void) +{ + return sizeof(dummy_cdrom_ioctl_t); +} diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 190dbc2e1..db54315e4 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -220,7 +220,7 @@ SettingsFloppyCDROM::save() for (int i = 0; i < CDROM_NUM; i++) { cdrom[i].priv = NULL; cdrom[i].ops = NULL; - cdrom[i].image = NULL; + cdrom[i].local = NULL; cdrom[i].insert = NULL; cdrom[i].close = NULL; cdrom[i].get_volume = NULL; diff --git a/src/qt/win_cdrom_ioctl.c b/src/qt/win_cdrom_ioctl.c index 995876c1d..ff65046a7 100644 --- a/src/qt/win_cdrom_ioctl.c +++ b/src/qt/win_cdrom_ioctl.c @@ -43,11 +43,16 @@ of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static int toc_valid = 0; -static CDROM_TOC cur_toc = { 0 }; -static HANDLE handle = NULL; -static WCHAR ioctl_path[256] = { 0 }; -static WCHAR old_ioctl_path[256] = { 0 }; +typedef struct win_cdrom_ioctl_t { + int toc_valid; + uint8_t cur_toc[65536]; + CDROM_READ_TOC_EX cur_read_toc_ex; + int blocks_num; + uint8_t cur_rti[65536]; + HANDLE handle; + WCHAR path[256]; + WCHAR old_path[256]; +} win_cdrom_ioctl_t; #ifdef ENABLE_WIN_CDROM_IOCTL_LOG int win_cdrom_ioctl_do_log = ENABLE_WIN_CDROM_IOCTL_LOG; @@ -68,63 +73,144 @@ win_cdrom_ioctl_log(const char *fmt, ...) #endif static int -plat_cdrom_open(void) +plat_cdrom_open(void *local) { - plat_cdrom_close(); + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; - handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError()); + plat_cdrom_close(local); - return (handle != INVALID_HANDLE_VALUE); + ioctl->handle = CreateFileW((LPCWSTR) ioctl->path, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + win_cdrom_ioctl_log("handle=%p, error=%x\n", ioctl->handle, (unsigned int) GetLastError()); + + return (ioctl->handle != INVALID_HANDLE_VALUE); } static int -plat_cdrom_load(void) +plat_cdrom_load(void *local) { - plat_cdrom_close(); + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; - handle = CreateFileW((LPCWSTR)ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError()); - if (handle != INVALID_HANDLE_VALUE) { + plat_cdrom_close(local); + + ioctl->handle = CreateFileW((LPCWSTR) ioctl->path, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + win_cdrom_ioctl_log("handle=%p, error=%x\n", ioctl->handle, (unsigned int) GetLastError()); + if (ioctl->handle != INVALID_HANDLE_VALUE) { long size; - DeviceIoControl(handle, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); + DeviceIoControl(ioctl->handle, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD) &size, NULL); return 1; } return 0; } -static void -plat_cdrom_read_toc(void) +static int +plat_cdrom_read_normal_toc(win_cdrom_ioctl_t *ioctl, uint8_t *toc_buf) { - long size = 0; + long size = 0; - if (!toc_valid) { - toc_valid = 1; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &cur_toc, sizeof(cur_toc), (LPDWORD)&size, NULL); - plat_cdrom_close(); + memset(toc_buf, 0x00, 65536); + plat_cdrom_open(ioctl); + int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC, NULL, 0, toc_buf, 65535, (LPDWORD) &size, NULL); + plat_cdrom_close(ioctl); +#ifdef ENABLE_WIN_CDROM_IOCTL_LOG + win_cdrom_ioctl_log("temp = %i\n", temp); + + PCDROM_TOC toc = (PCDROM_TOC) toc_buf; + const int tracks_num = (((toc->Length[0] << 8) | toc->Length[1]) - 2) / 8; + win_cdrom_ioctl_log("%i tracks\n", tracks_num); + for (int i = 0; i < tracks_num; i++) + win_cdrom_ioctl_log("Track %03i: Point %02X\n", i, (int) toc->TrackData[i].TrackNumber); +#endif + + return temp; +} + +static void +plat_cdrom_read_raw_toc(win_cdrom_ioctl_t *ioctl) +{ + long size = 0; + int status; + PCDROM_TOC_FULL_TOC_DATA cur_full_toc = NULL; + + memset(ioctl->cur_rti, 0x00, 65536); + cur_full_toc = (PCDROM_TOC_FULL_TOC_DATA) calloc(1, 65536); + if (ioctl->blocks_num != 0) { + memset(ioctl->cur_rti, 0x00, ioctl->blocks_num * 11); + ioctl->blocks_num = 0; + } + + ioctl->cur_read_toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC; + win_cdrom_ioctl_log("cur_read_toc_ex.Format = %i\n", ioctl->cur_read_toc_ex.Format); + ioctl->cur_read_toc_ex.Msf = 1; + ioctl->cur_read_toc_ex.SessionTrack = 1; + + plat_cdrom_open(ioctl); + status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC_EX, &ioctl->cur_read_toc_ex, 65535, + cur_full_toc, 65535, (LPDWORD) &size, NULL); + plat_cdrom_close(ioctl); + win_cdrom_ioctl_log("status = %i\n", status); + + if (status != 0) { + ioctl->blocks_num = (((cur_full_toc->Length[0] << 8) | cur_full_toc->Length[1]) - 2) / 11; + memcpy(ioctl->cur_rti, cur_full_toc->Descriptors, ioctl->blocks_num * 11); + } + + free(cur_full_toc); + +#ifdef ENABLE_WIN_CDROM_IOCTL_LOG + win_cdrom_ioctl_log("%i blocks\n", ioctl->blocks_num); + + raw_track_info_t *rti = (raw_track_info_t *) ioctl->cur_rti; + for (int i = 0; i < ioctl->blocks_num; i++) + win_cdrom_ioctl_log("Block %03i: Session %03i, Point %02X\n", i, (int) rti[i].session, (int) rti[i].point); +#endif +} + +void +plat_cdrom_get_raw_track_info(void *local, int *num, raw_track_info_t *rti) +{ + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + + *num = ioctl->blocks_num; + memcpy(rti, ioctl->cur_rti, ioctl->blocks_num * 11); +} + +static void +plat_cdrom_read_toc(win_cdrom_ioctl_t *ioctl) +{ + if (!ioctl->toc_valid) { + ioctl->toc_valid = 1; + (void) plat_cdrom_read_normal_toc(ioctl, ioctl->cur_toc); + plat_cdrom_read_raw_toc(ioctl); } } int -plat_cdrom_is_track_audio(uint32_t sector) +plat_cdrom_is_track_audio(void *local, uint32_t sector) { - int control = 0; - uint32_t track_addr = 0; - uint32_t next_track_addr = 0; + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc; + int control = 0; + uint32_t cur_addr = 0; + uint32_t next_addr = 0; - plat_cdrom_read_toc(); + plat_cdrom_read_toc(ioctl); + + for (int c = 0; toc->TrackData[c].TrackNumber != 0xaa; c++) { + PTRACK_DATA cur_td = &toc->TrackData[c]; + PTRACK_DATA next_td = &toc->TrackData[c + 1]; + + cur_addr = MSFtoLBA(cur_td->Address[1], cur_td->Address[2], cur_td->Address[3]) - 150; + next_addr = MSFtoLBA(next_td->Address[1], next_td->Address[2], next_td->Address[3]) - 150; - for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { - track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; - next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", - cur_toc.FirstTrack, cur_toc.LastTrack, - cur_toc.TrackData[c].TrackNumber, c, - cur_toc.TrackData[c].Control, track_addr, sector); - if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && - (sector >= track_addr) && (sector < next_track_addr)) { - control = cur_toc.TrackData[c].Control; + toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c, + cur_td->Control, track_addr, sector); + + if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) && + (sector >= cur_addr) && (sector < next_addr)) { + control = cur_td->Control; break; } } @@ -137,26 +223,32 @@ plat_cdrom_is_track_audio(uint32_t sector) } int -plat_cdrom_is_track_pre(uint32_t sector) +plat_cdrom_is_track_pre(void *local, uint32_t sector) { - int control = 0; - uint32_t track_addr = 0; - uint32_t next_track_addr = 0; + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc; + int control = 0; + uint32_t cur_addr = 0; + uint32_t next_addr = 0; - plat_cdrom_read_toc(); + plat_cdrom_read_toc(ioctl); + + for (int c = 0; toc->TrackData[c].TrackNumber != 0xaa; c++) { + PTRACK_DATA cur_td = &toc->TrackData[c]; + PTRACK_DATA next_td = &toc->TrackData[c + 1]; + + cur_addr = MSFtoLBA(cur_td->Address[1], cur_td->Address[2], cur_td->Address[3]) - 150; + next_addr = MSFtoLBA(next_td->Address[1], next_td->Address[2], next_td->Address[3]) - 150; - for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { - track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; - next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n", - cur_toc.FirstTrack, cur_toc.LastTrack, - cur_toc.TrackData[c].TrackNumber, c, - cur_toc.TrackData[c].Control, track_addr, sector); - if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && - (sector >= track_addr) && (sector < next_track_addr)) { - control = cur_toc.TrackData[c].Control; + toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c, + cur_td->Control, cur_addr, sector); + + if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) && + (sector >= cur_addr) && (sector < next_addr)) { + control = cur_td->Control; break; - } + } } const int ret = (control & 0x01); @@ -167,81 +259,91 @@ plat_cdrom_is_track_pre(uint32_t sector) } uint32_t -plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) +plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track) { - uint32_t track_addr = 0; - uint32_t next_track_addr = 0; + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc; + uint32_t cur_addr = 0; + uint32_t next_addr = 0; - plat_cdrom_read_toc(); + plat_cdrom_read_toc(ioctl); + + for (int c = 0; toc->TrackData[c].TrackNumber != 0xaa; c++) { + PTRACK_DATA cur_td = &toc->TrackData[c]; + PTRACK_DATA next_td = &toc->TrackData[c + 1]; + + cur_addr = MSFtoLBA(cur_td->Address[1], cur_td->Address[2], cur_td->Address[3]) - 150; + next_addr = MSFtoLBA(next_td->Address[1], next_td->Address[2], next_td->Address[3]) - 150; - for (int c = 0; cur_toc.TrackData[c].TrackNumber != 0xaa; c++) { - track_addr = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; - next_track_addr = MSFtoLBA(cur_toc.TrackData[c + 1].Address[1], cur_toc.TrackData[c + 1].Address[2], cur_toc.TrackData[c + 1].Address[3]) - 150; win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, a: %02X, A: %08X, S: %08X\n", - cur_toc.FirstTrack, cur_toc.LastTrack, - cur_toc.TrackData[c].TrackNumber, c, - cur_toc.TrackData[c].Control, cur_toc.TrackData[c].Adr, - track_addr, sector); - if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && - (sector >= track_addr) && (sector < next_track_addr)) { - *track = cur_toc.TrackData[c].TrackNumber; - *attr = cur_toc.TrackData[c].Control; - *attr |= ((cur_toc.TrackData[c].Adr << 4) & 0xf0); + toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c, + cur_td->Control, cur_td->Adr, cur_addr, sector); + + if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) && + (sector >= cur_addr) && (sector < next_addr)) { + *track = cur_td->TrackNumber; + *attr = cur_td->Control; + *attr |= ((cur_td->Adr << 4) & 0xf0); break; } } - win_cdrom_ioctl_log("plat_cdrom_get_track_start(%08X): %i\n", sector, track_addr); + win_cdrom_ioctl_log("plat_cdrom_get_track_start(%08X): %i\n", sector, cur_addr); - return track_addr; + return cur_addr; } uint32_t -plat_cdrom_get_last_block(void) +plat_cdrom_get_last_block(void *local) { - uint32_t lb = 0; - uint32_t address = 0; + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc; + uint32_t lb = 0; + uint32_t address = 0; - plat_cdrom_read_toc(); + plat_cdrom_read_toc(ioctl); + + for (int c = 0; c <= toc->LastTrack; c++) { + PTRACK_DATA td = &toc->TrackData[c]; + + address = MSFtoLBA(td->Address[1], td->Address[2], td->Address[3]) - 150; - for (int c = 0; c <= cur_toc.LastTrack; c++) { - address = MSFtoLBA(cur_toc.TrackData[c].Address[1], cur_toc.TrackData[c].Address[2], cur_toc.TrackData[c].Address[3]) - 150; if (address > lb) lb = address; } + win_cdrom_ioctl_log("LBCapacity=%d\n", lb); + return lb; } int -plat_cdrom_ext_medium_changed(void) +plat_cdrom_ext_medium_changed(void *local) { - long size; - CDROM_TOC toc; - int ret = 0; + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc; + uint8_t new_toc_buf[65536] = { 0 }; + PCDROM_TOC new_toc = (PCDROM_TOC) new_toc_buf; + int ret = 0; + int temp = plat_cdrom_read_normal_toc(ioctl, new_toc_buf); + PTRACK_DATA cur_ltd = &toc->TrackData[toc->LastTrack]; - plat_cdrom_open(); - int temp = DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, - NULL, 0, &toc, sizeof(toc), - (LPDWORD)&size, NULL); - plat_cdrom_close(); + if (temp != 0) + plat_cdrom_read_raw_toc(ioctl); - if (!temp) + PTRACK_DATA new_ltd = &new_toc->TrackData[new_toc->LastTrack]; + + if (temp == 0) /* There has been some kind of error - not a medium change, but a not ready condition. */ ret = -1; - else if (!toc_valid || (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0)) { + else if (!ioctl->toc_valid || (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0)) { /* Changed to a different host drive - we already detect such medium changes. */ - toc_valid = 1; - cur_toc = toc; - if (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0) - memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path)); - } else if ((toc.TrackData[toc.LastTrack].Address[1] != - cur_toc.TrackData[cur_toc.LastTrack].Address[1]) || - (toc.TrackData[toc.LastTrack].Address[2] != - cur_toc.TrackData[cur_toc.LastTrack].Address[2]) || - (toc.TrackData[toc.LastTrack].Address[3] != - cur_toc.TrackData[cur_toc.LastTrack].Address[3])) + ioctl->toc_valid = 1; + memcpy(toc, new_toc, 65535); + if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0) + memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path)); + } else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3)) /* The TOC has changed. */ ret = 1; @@ -251,15 +353,20 @@ plat_cdrom_ext_medium_changed(void) } void -plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) +plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out) { - plat_cdrom_read_toc(); + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc; + + plat_cdrom_read_toc(ioctl); + + PTRACK_DATA ltd = &toc->TrackData[toc->LastTrack]; *st_track = 1; - *end = cur_toc.LastTrack; - lead_out->min = cur_toc.TrackData[cur_toc.LastTrack].Address[1]; - lead_out->sec = cur_toc.TrackData[cur_toc.LastTrack].Address[2]; - lead_out->fr = cur_toc.TrackData[cur_toc.LastTrack].Address[3]; + *end = toc->LastTrack; + lead_out->min = ltd->Address[1]; + lead_out->sec = ltd->Address[2]; + lead_out->fr = ltd->Address[3]; win_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", *st_track, *end, lead_out->min, lead_out->sec, lead_out->fr); @@ -267,22 +374,27 @@ plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) /* This replaces both Info and EndInfo, they are specified by a variable. */ int -plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) +plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { - plat_cdrom_read_toc(); + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc; - if ((track < 1) || (track == 0xaa) || (track > (cur_toc.LastTrack + 1))) { + plat_cdrom_read_toc(ioctl); + + if ((track < 1) || (track == 0xaa) || (track > (toc->LastTrack + 1))) { win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); return 0; } - start->min = cur_toc.TrackData[track - 1].Address[1]; - start->sec = cur_toc.TrackData[track - 1].Address[2]; - start->fr = cur_toc.TrackData[track - 1].Address[3]; + PTRACK_DATA td = &toc->TrackData[track - 1]; - *track_num = cur_toc.TrackData[track - 1].TrackNumber; - *attr = cur_toc.TrackData[track - 1].Control; - *attr |= ((cur_toc.TrackData[track - 1].Adr << 4) & 0xf0); + start->min = td->Address[1]; + start->sec = td->Address[2]; + start->fr = td->Address[3]; + + *track_num = td->TrackNumber; + *attr = td->Control; + *attr |= ((td->Adr << 4) & 0xf0); win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i): %02i:%02i:%02i, %02i, %02X\n", track, start->min, start->sec, start->fr, *track_num, *attr); @@ -292,17 +404,20 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF /* TODO: See if track start is adjusted by 150 or not. */ int -plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) +plat_cdrom_get_audio_sub(void *local, UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, + TMSF *rel_pos, TMSF *abs_pos) { + win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local; CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - long size = 0; + SUB_Q_CHANNEL_DATA sub; + long size = 0; insub.Format = IOCTL_CDROM_CURRENT_POSITION; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); - plat_cdrom_close(); + plat_cdrom_open(ioctl); + DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), + (LPDWORD) &size, NULL); + plat_cdrom_close(ioctl); if (sub.CurrentPosition.TrackNumber < 1) return 0; @@ -320,92 +435,107 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, abs_pos->fr = sub.CurrentPosition.AbsoluteAddress[3]; win_cdrom_ioctl_log("plat_cdrom_get_audio_sub(): %02i, %02X, %02i, %02i:%02i:%02i, %02i:%02i:%02i\n", - *track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, abs_pos->fr); + *track, *attr, *index, rel_pos->min, rel_pos->sec, rel_pos->fr, abs_pos->min, abs_pos->sec, + abs_pos->fr); return 1; } int -plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) +plat_cdrom_get_sector_size(void *local, UNUSED(uint32_t sector)) { - long size; - DISK_GEOMETRY dgCDROM; + win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local; + long size; + DISK_GEOMETRY dgCDROM; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM), (LPDWORD)&size, NULL); - plat_cdrom_close(); + plat_cdrom_open(ioctl); + DeviceIoControl(ioctl->handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM), + (LPDWORD) &size, NULL); + plat_cdrom_close(ioctl); win_cdrom_ioctl_log("BytesPerSector=%d\n", dgCDROM.BytesPerSector); return dgCDROM.BytesPerSector; } int -plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) +plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector) { - int status; - long size = 0; - int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local; + int status; + long size = 0; + int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - plat_cdrom_open(); + plat_cdrom_open(ioctl); if (raw) { - win_cdrom_ioctl_log("Raw\n"); /* Raw */ + win_cdrom_ioctl_log("Raw\n"); RAW_READ_INFO in; in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE; in.DiskOffset.HighPart = 0; in.SectorCount = 1; in.TrackMode = CDDA; - status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), - buffer, buflen, (LPDWORD)&size, NULL); + status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), + buffer, buflen, (LPDWORD) &size, NULL); } else { - win_cdrom_ioctl_log("Cooked\n"); /* Cooked */ + win_cdrom_ioctl_log("Cooked\n"); int success = 0; - DWORD newPos = SetFilePointer(handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); + DWORD newPos = SetFilePointer(ioctl->handle, sector * COOKED_SECTOR_SIZE, 0, FILE_BEGIN); if (newPos != 0xFFFFFFFF) - success = ReadFile(handle, buffer, buflen, (LPDWORD)&size, NULL); + success = ReadFile(ioctl->handle, buffer, buflen, (LPDWORD) &size, NULL); status = (success != 0); } - plat_cdrom_close(); + plat_cdrom_close(ioctl); win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size); return (status > 0) ? (size == buflen) : -1; } void -plat_cdrom_eject(void) +plat_cdrom_eject(void *local) { - long size; + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + long size; - plat_cdrom_open(); - DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); - - plat_cdrom_close(); + plat_cdrom_open(ioctl); + DeviceIoControl(ioctl->handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD) &size, NULL); + plat_cdrom_close(ioctl); } void -plat_cdrom_close(void) +plat_cdrom_close(void *local) { - if (handle != NULL) { - CloseHandle(handle); - handle = NULL; + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; + + if (ioctl->handle != NULL) { + CloseHandle(ioctl->handle); + ioctl->handle = NULL; } } int -plat_cdrom_set_drive(const char *drv) +plat_cdrom_set_drive(void *local, const char *drv) { - plat_cdrom_close(); + win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local; - memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path)); - memset(ioctl_path, 0x00, sizeof(ioctl_path)); + plat_cdrom_close(ioctl); - wsprintf(ioctl_path, L"%S", drv); - win_cdrom_ioctl_log("Path is %S\n", ioctl_path); + memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path)); + memset(ioctl->path, 0x00, sizeof(ioctl->path)); - toc_valid = 0; + wsprintf(ioctl->path, L"%S", drv); + win_cdrom_ioctl_log("Path is %S\n", ioctl->path); + + ioctl->toc_valid = 0; + + plat_cdrom_load(ioctl); - plat_cdrom_load(); return 1; } + +int +plat_cdrom_get_local_size(void) +{ + return sizeof(win_cdrom_ioctl_t); +} diff --git a/src/unix/dummy_cdrom_ioctl.c b/src/unix/dummy_cdrom_ioctl.c index ed19dfb1f..bf656177b 100644 --- a/src/unix/dummy_cdrom_ioctl.c +++ b/src/unix/dummy_cdrom_ioctl.c @@ -35,7 +35,9 @@ of the audio while audio still plays. With an absolute conversion, the counter is fine. */ #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -static int toc_valid = 0; +typedef struct dummy_cdrom_ioctl_t { + int toc_valid; +} dummy_cdrom_ioctl_t; #ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG; @@ -56,30 +58,41 @@ dummy_cdrom_ioctl_log(const char *fmt, ...) #endif static int -plat_cdrom_open(void) +plat_cdrom_open(void *local) { return 0; } static int -plat_cdrom_load(void) +plat_cdrom_load(void *local) { return 0; } static void -plat_cdrom_read_toc(void) +plat_cdrom_read_toc(void *local) { - if (!toc_valid) - toc_valid = 1; + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + if (!ioctl->toc_valid) + ioctl->toc_valid = 1; +} + +void +plat_cdrom_get_raw_track_info(UNUSED(void *local), int *num, raw_track_info_t *rti) +{ + *num = 1; + memset(rti, 0x00, 11); } int -plat_cdrom_is_track_audio(uint32_t sector) +plat_cdrom_is_track_audio(void *local, uint32_t sector) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; - const int ret = 0; + plat_cdrom_read_toc(ioctl); + + const int ret = 0; dummy_cdrom_ioctl_log("plat_cdrom_is_track_audio(%08X): %i\n", sector, ret); @@ -87,9 +100,11 @@ plat_cdrom_is_track_audio(uint32_t sector) } int -plat_cdrom_is_track_pre(uint32_t sector) +plat_cdrom_is_track_pre(void *local, uint32_t sector) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); const int ret = 0; @@ -99,25 +114,30 @@ plat_cdrom_is_track_pre(uint32_t sector) } uint32_t -plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track) +plat_cdrom_get_track_start(void *local, uint32_t sector, uint8_t *attr, uint8_t *track) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); return 0x00000000; } uint32_t -plat_cdrom_get_last_block(void) +plat_cdrom_get_last_block(void *local) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); return 0x00000000; } int -plat_cdrom_ext_medium_changed(void) +plat_cdrom_ext_medium_changed(void *local) { - int ret = 0; + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + int ret = 0; dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); @@ -125,9 +145,11 @@ plat_cdrom_ext_medium_changed(void) } void -plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) +plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); *st_track = 1; *end = 1; @@ -141,9 +163,11 @@ plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out) /* This replaces both Info and EndInfo, they are specified by a variable. */ int -plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) +plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr) { - plat_cdrom_read_toc(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_read_toc(ioctl); if ((track < 1) || (track == 0xaa)) { dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); @@ -165,7 +189,8 @@ plat_cdrom_get_audio_track_info(UNUSED(int end), int track, int *track_num, TMSF /* TODO: See if track start is adjusted by 150 or not. */ int -plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, TMSF *rel_pos, TMSF *abs_pos) +plat_cdrom_get_audio_sub(UNUSED(void *local), UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, uint8_t *index, + TMSF *rel_pos, TMSF *abs_pos) { *track = 1; *attr = 0x14; @@ -185,7 +210,7 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track, } int -plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) +plat_cdrom_get_sector_size(UNUSED(void *local), UNUSED(uint32_t sector)) { dummy_cdrom_ioctl_log("BytesPerSector=2048\n"); @@ -193,42 +218,56 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) } int -plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector) +plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector) { - plat_cdrom_open(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; - if (raw) { - dummy_cdrom_ioctl_log("Raw\n"); + plat_cdrom_open(ioctl); + + if (raw) /* Raw */ - } else { - dummy_cdrom_ioctl_log("Cooked\n"); + dummy_cdrom_ioctl_log("Raw\n"); + else /* Cooked */ - } - plat_cdrom_close(); + dummy_cdrom_ioctl_log("Cooked\n"); + + plat_cdrom_close(ioctl); + dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector); return 0; } void -plat_cdrom_eject(void) +plat_cdrom_eject(void *local) { - plat_cdrom_open(); - plat_cdrom_close(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; + + plat_cdrom_open(ioctl); + plat_cdrom_close(ioctl); } void -plat_cdrom_close(void) +plat_cdrom_close(UNUSED(void *local)) { } int -plat_cdrom_set_drive(const char *drv) +plat_cdrom_set_drive(void *local, const char *drv) { - plat_cdrom_close(); + dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local; - toc_valid = 0; + plat_cdrom_close(ioctl); + + ioctl->toc_valid = 0; + + plat_cdrom_load(ioctl); - plat_cdrom_load(); return 1; } + +int +plat_cdrom_get_local_size(void) +{ + return sizeof(dummy_cdrom_ioctl_t); +}