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.

This commit is contained in:
OBattler
2024-11-25 21:23:28 +01:00
parent 971b3a0aba
commit 5c27083af6
11 changed files with 671 additions and 307 deletions

View File

@@ -1168,18 +1168,90 @@ static int
read_toc_raw(cdrom_t *dev, unsigned char *b) read_toc_raw(cdrom_t *dev, unsigned char *b)
{ {
track_info_t ti; track_info_t ti;
raw_track_info_t rti[256] = { 0 };
int num = 0;
int len = 4; int len = 4;
int first_track; int first_track;
int last_track; int last_track;
cdrom_log("read_toc_raw(%08X, %08X)\n", dev, b);
dev->ops->get_tracks(dev, &first_track, &last_track);
/* Bytes 2 and 3 = Number of first and last sessions */ /* Bytes 2 and 3 = Number of first and last sessions */
b[2] = b[3] = 1; b[2] = b[3] = 1;
for (int i = 0; i <= last_track; i++) { 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++] = 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;
b[len++] = 0;
b[len++] = 0;
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); 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); cdrom_log(" tracks(%i) = %02X, %02X, %i:%02i.%02i\n", i, ti.attr, ti.number, ti.m, ti.s, ti.f);
@@ -1197,6 +1269,7 @@ read_toc_raw(cdrom_t *dev, unsigned char *b)
b[len++] = ti.s; /* PS */ b[len++] = ti.s; /* PS */
b[len++] = ti.f; /* PF */ b[len++] = ti.f; /* PF */
} }
}
return len; return len;
} }
@@ -1954,6 +2027,22 @@ cdrom_drive_reset(cdrom_t *dev)
dev->get_channel = NULL; 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 void
cdrom_hard_reset(void) cdrom_hard_reset(void)
{ {
@@ -1994,6 +2083,10 @@ cdrom_hard_reset(void)
cdrom_ioctl_open(dev, dev->image_path); cdrom_ioctl_open(dev, dev->image_path);
else else
cdrom_image_open(dev, dev->image_path); 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); strcpy(dev->image_path, dev->prev_image_path);
#ifdef _WIN32 #ifdef _WIN32
if (strlen(dev->prev_image_path) > 0) { if ((strlen(dev->prev_image_path) > 0) && (strlen(dev->image_path) >= 1) &&
if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '/')) (dev->image_path[strlen(dev->image_path) - 1] == '/'))
dev->image_path[strlen(dev->image_path) - 1] = '\\'; dev->image_path[strlen(dev->image_path) - 1] = '\\';
}
#else #else
if (strlen(dev->prev_image_path) > 0) { if ((strlen(dev->prev_image_path) > 0) && (strlen(dev->image_path) >= 1) &&
if ((strlen(dev->image_path) >= 1) && (dev->image_path[strlen(dev->image_path) - 1] == '\\')) (dev->image_path[strlen(dev->image_path) - 1] == '\\'))
dev->image_path[strlen(dev->image_path) - 1] = '/'; dev->image_path[strlen(dev->image_path) - 1] = '/';
}
#endif #endif
if ((strlen(dev->image_path) != 0) && (strstr(dev->image_path, "ioctl://") == dev->image_path)) if ((strlen(dev->image_path) != 0) && (strstr(dev->image_path, "ioctl://") == dev->image_path))
@@ -2111,6 +2202,10 @@ cdrom_reload(uint8_t id)
else else
cdrom_image_open(dev, dev->image_path); cdrom_image_open(dev, dev->image_path);
#ifdef ENABLE_CDROM_LOG
cdrom_toc_dump(dev);
#endif
cdrom_insert(id); cdrom_insert(id);
} }

View File

@@ -61,7 +61,7 @@ cdrom_image_log(const char *fmt, ...)
static void static void
image_get_tracks(cdrom_t *dev, int *first, int *last) 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; TMSF tmsf;
cdi_get_audio_tracks(img, first, last, &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 static void
image_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti) 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; TMSF tmsf;
cdi_get_audio_track_info(img, end, track, &ti->number, &tmsf, &ti->attr); 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 static void
image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc) 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 rel_pos;
TMSF abs_pos; TMSF abs_pos;
@@ -105,7 +105,7 @@ image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
static int static int
image_get_capacity(cdrom_t *dev) 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 first_track;
int last_track; int last_track;
int number; int number;
@@ -130,7 +130,7 @@ image_get_capacity(cdrom_t *dev)
static int static int
image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) 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; uint8_t attr;
TMSF tmsf; TMSF tmsf;
int m; int m;
@@ -162,7 +162,7 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
static int static int
image_is_track_pre(cdrom_t *dev, uint32_t lba) 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; int track;
/* GetTrack requires LBA. */ /* GetTrack requires LBA. */
@@ -177,7 +177,7 @@ image_is_track_pre(cdrom_t *dev, uint32_t lba)
static int static int
image_sector_size(struct cdrom *dev, uint32_t lba) 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); return cdi_get_sector_size(img, lba);
} }
@@ -185,7 +185,7 @@ image_sector_size(struct cdrom *dev, uint32_t lba)
static int static int
image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba) 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) { switch (type) {
case CD_READ_DATA: case CD_READ_DATA:
@@ -206,7 +206,7 @@ image_read_sector(struct cdrom *dev, int type, uint8_t *b, uint32_t lba)
static int static int
image_track_type(cdrom_t *dev, uint32_t lba) 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 (img) {
if (image_is_track_audio(dev, lba, 0)) if (image_is_track_audio(dev, lba, 0))
@@ -229,14 +229,14 @@ image_ext_medium_changed(cdrom_t *dev)
static void static void
image_exit(cdrom_t *dev) 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); cdrom_image_log("CDROM: image_exit(%s)\n", dev->image_path);
dev->cd_status = CD_STATUS_EMPTY; dev->cd_status = CD_STATUS_EMPTY;
if (img) { if (img) {
cdi_close(img); cdi_close(img);
dev->image = NULL; dev->local = NULL;
} }
dev->ops = NULL; dev->ops = NULL;
@@ -245,6 +245,7 @@ image_exit(cdrom_t *dev)
static const cdrom_ops_t cdrom_image_ops = { static const cdrom_ops_t cdrom_image_ops = {
image_get_tracks, image_get_tracks,
image_get_track_info, image_get_track_info,
NULL,
image_get_subchannel, image_get_subchannel,
image_is_track_pre, image_is_track_pre,
image_sector_size, image_sector_size,
@@ -282,7 +283,7 @@ cdrom_image_open(cdrom_t *dev, const char *fn)
return image_open_abort(dev); return image_open_abort(dev);
memset(img, 0, sizeof(cd_img_t)); memset(img, 0, sizeof(cd_img_t));
dev->image = img; dev->local = img;
/* Open the image. */ /* Open the image. */
int i = cdi_set_device(img, fn); 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->cd_buflen = 0;
dev->cdrom_capacity = image_get_capacity(dev); 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); 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. */ /* Attach this handler to the drive. */
dev->ops = &cdrom_image_ops; dev->ops = &cdrom_image_ops;

View File

@@ -1189,7 +1189,6 @@ cdi_load_cue(cd_img_t *cdi, const char *cuefile)
/* Add lead out track. */ /* Add lead out track. */
trk.number++; trk.number++;
trk.track_number = 0xAA; trk.track_number = 0xAA;
trk.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */
trk.start = 0; trk.start = 0;
trk.length = 0; trk.length = 0;
trk.file = NULL; trk.file = NULL;

View File

@@ -28,9 +28,9 @@
#include <86box/config.h> #include <86box/config.h>
#include <86box/path.h> #include <86box/path.h>
#include <86box/plat.h> #include <86box/plat.h>
#include <86box/plat_cdrom.h>
#include <86box/scsi_device.h> #include <86box/scsi_device.h>
#include <86box/cdrom.h> #include <86box/cdrom.h>
#include <86box/plat_cdrom.h>
#ifdef ENABLE_CDROM_IOCTL_LOG #ifdef ENABLE_CDROM_IOCTL_LOG
int cdrom_ioctl_do_log = 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) #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
static void 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; TMSF tmsf;
plat_cdrom_get_audio_tracks(first, last, &tmsf); plat_cdrom_get_audio_tracks(dev->local, first, last, &tmsf);
} }
static void 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; 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->m = tmsf.min;
ti->s = tmsf.sec; 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 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 rel_pos;
TMSF abs_pos; TMSF abs_pos;
if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED)) { 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); 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; subc->index = 1;
} else } 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); &rel_pos, &abs_pos);
subc->abs_m = abs_pos.min; 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 static int
ioctl_get_capacity(UNUSED(cdrom_t *dev)) ioctl_get_capacity(cdrom_t *dev)
{ {
int ret; int ret;
ret = plat_cdrom_get_last_block(); ret = plat_cdrom_get_last_block(dev->local);
cdrom_ioctl_log("GetCapacity=%x.\n", ret); cdrom_ioctl_log("GetCapacity=%x.\n", ret);
return ret; return ret;
} }
@@ -134,35 +140,35 @@ ioctl_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
} }
/* GetTrack requires LBA. */ /* GetTrack requires LBA. */
return plat_cdrom_is_track_audio(pos); return plat_cdrom_is_track_audio(dev->local, pos);
} }
static int 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 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); 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 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) { switch (type) {
case CD_READ_DATA: case CD_READ_DATA:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Data.\n"); 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: case CD_READ_AUDIO:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Audio.\n"); 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: case CD_READ_RAW:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Raw.\n"); 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: default:
cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n"); cdrom_ioctl_log("cdrom_ioctl_read_sector(): Unknown CD read type.\n");
break; 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)) if ((dev->cd_status == CD_STATUS_PLAYING) || (dev->cd_status == CD_STATUS_PAUSED))
ret = 0; ret = 0;
else else
ret = plat_cdrom_ext_medium_changed(); ret = plat_cdrom_ext_medium_changed(dev->local);
if (ret == 1) { if (ret == 1) {
dev->cd_status = CD_STATUS_STOPPED; 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); cdrom_ioctl_log("CDROM: ioctl_exit(%s)\n", dev->image_path);
dev->cd_status = CD_STATUS_EMPTY; dev->cd_status = CD_STATUS_EMPTY;
plat_cdrom_close(); plat_cdrom_close(dev->local);
dev->local = NULL;
dev->ops = NULL; dev->ops = NULL;
} }
@@ -216,6 +223,7 @@ ioctl_exit(cdrom_t *dev)
static const cdrom_ops_t cdrom_ioctl_ops = { static const cdrom_ops_t cdrom_ioctl_ops = {
ioctl_get_tracks, ioctl_get_tracks,
ioctl_get_track_info, ioctl_get_track_info,
ioctl_get_raw_track_info,
ioctl_get_subchannel, ioctl_get_subchannel,
ioctl_is_track_pre, ioctl_is_track_pre,
ioctl_sector_size, ioctl_sector_size,
@@ -238,6 +246,7 @@ int
cdrom_ioctl_open(cdrom_t *dev, const char *drv) cdrom_ioctl_open(cdrom_t *dev, const char *drv)
{ {
const char *actual_drv = &(drv[8]); const char *actual_drv = &(drv[8]);
int local_size = plat_cdrom_get_local_size();
/* Make sure to not STRCPY if the two are pointing /* Make sure to not STRCPY if the two are pointing
at the same place. */ at the same place. */
@@ -248,7 +257,9 @@ cdrom_ioctl_open(cdrom_t *dev, const char *drv)
if (strstr(drv, "ioctl://") != drv) if (strstr(drv, "ioctl://") != drv)
return cdrom_ioctl_open_abort(dev); return cdrom_ioctl_open_abort(dev);
cdrom_ioctl_log("actual_drv = %s\n", actual_drv); 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) if (!i)
return cdrom_ioctl_open_abort(dev); return cdrom_ioctl_open_abort(dev);

View File

@@ -195,10 +195,25 @@ typedef struct track_info_t {
uint8_t f; uint8_t f;
} track_info_t; } 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). */ /* Define the various CD-ROM drive operations (ops). */
typedef struct cdrom_ops_t { typedef struct cdrom_ops_t {
void (*get_tracks)(struct cdrom *dev, int *first, int *last); 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_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); void (*get_subchannel)(struct cdrom *dev, uint32_t lba, subchannel_t *subc);
int (*is_track_pre)(struct cdrom *dev, uint32_t lba); int (*is_track_pre)(struct cdrom *dev, uint32_t lba);
int (*sector_size)(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; const cdrom_ops_t *ops;
void *image; void *local;
void (*insert)(void *priv); void (*insert)(void *priv);
void (*close)(void *priv); void (*close)(void *priv);

View File

@@ -57,7 +57,31 @@ typedef struct track_file_t {
int motorola; int motorola;
} track_file_t; } 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 { 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 number;
int track_number; int track_number;
int attr; int attr;
@@ -69,6 +93,7 @@ typedef struct track_t {
uint64_t start; uint64_t start;
uint64_t length; uint64_t length;
uint64_t skip; uint64_t skip;
track_block_t blocks[256];
track_file_t *file; track_file_t *file;
} track_t; } track_t;

View File

@@ -49,19 +49,23 @@ typedef struct SMSF {
uint8_t fr; uint8_t fr;
} TMSF; } TMSF;
extern int plat_cdrom_is_track_audio(uint32_t sector); extern void plat_cdrom_get_raw_track_info(void *local, int *num, raw_track_info_t *rti);
extern int plat_cdrom_is_track_pre(uint32_t sector); extern int plat_cdrom_is_track_audio(void *local, uint32_t sector);
extern uint32_t plat_cdrom_get_last_block(void); extern int plat_cdrom_is_track_pre(void *local, uint32_t sector);
extern void plat_cdrom_get_audio_tracks(int *st_track, int *end, TMSF *lead_out); extern uint32_t plat_cdrom_get_last_block(void *local);
extern int plat_cdrom_get_audio_track_info(int end, int track, int *track_num, TMSF *start, uint8_t *attr); extern void plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out);
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_audio_track_info(void *local, int end, int track, int *track_num, TMSF *start,
extern int plat_cdrom_get_sector_size(uint32_t sector); uint8_t *attr);
extern int plat_cdrom_read_sector(uint8_t *buffer, int raw, uint32_t sector); extern int plat_cdrom_get_audio_sub(void *local, uint32_t sector, uint8_t *attr, uint8_t *track,
extern void plat_cdrom_eject(void); uint8_t *index, TMSF *rel_pos, TMSF *abs_pos);
extern void plat_cdrom_close(void); extern int plat_cdrom_get_sector_size(void *local, uint32_t sector);
extern int plat_cdrom_set_drive(const char *drv); extern int plat_cdrom_read_sector(void *local, uint8_t *buffer, int raw, uint32_t sector);
extern int plat_cdrom_ext_medium_changed(void); extern void plat_cdrom_eject(void *local);
extern uint32_t plat_cdrom_get_track_start(uint32_t sector, uint8_t *attr, uint8_t *track); 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 #ifdef __cplusplus
} }

View File

@@ -35,7 +35,9 @@
of the audio while audio still plays. With an absolute conversion, the counter is fine. */ 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) #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 #ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG
int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG; int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG;
@@ -56,28 +58,39 @@ dummy_cdrom_ioctl_log(const char *fmt, ...)
#endif #endif
static int static int
plat_cdrom_open(void) plat_cdrom_open(void *local)
{ {
return 0; return 0;
} }
static int static int
plat_cdrom_load(void) plat_cdrom_load(void *local)
{ {
return 0; return 0;
} }
static void static void
plat_cdrom_read_toc(void) plat_cdrom_read_toc(void *local)
{ {
if (!toc_valid) dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
toc_valid = 1;
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 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;
plat_cdrom_read_toc(ioctl);
const int ret = 0; const int ret = 0;
@@ -87,9 +100,11 @@ plat_cdrom_is_track_audio(uint32_t sector)
} }
int 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; const int ret = 0;
@@ -99,24 +114,29 @@ plat_cdrom_is_track_pre(uint32_t sector)
} }
uint32_t 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; return 0x00000000;
} }
uint32_t 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; return 0x00000000;
} }
int int
plat_cdrom_ext_medium_changed(void) plat_cdrom_ext_medium_changed(void *local)
{ {
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
int ret = 0; int ret = 0;
dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
@@ -125,9 +145,11 @@ plat_cdrom_ext_medium_changed(void)
} }
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; *st_track = 1;
*end = 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. */ /* This replaces both Info and EndInfo, they are specified by a variable. */
int 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)) { if ((track < 1) || (track == 0xaa)) {
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); 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. */ /* TODO: See if track start is adjusted by 150 or not. */
int 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; *track = 1;
*attr = 0x14; *attr = 0x14;
@@ -185,7 +210,7 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track,
} }
int 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"); dummy_cdrom_ioctl_log("BytesPerSector=2048\n");
@@ -193,42 +218,56 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector))
} }
int 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) { plat_cdrom_open(ioctl);
dummy_cdrom_ioctl_log("Raw\n");
if (raw)
/* Raw */ /* Raw */
} else { dummy_cdrom_ioctl_log("Raw\n");
dummy_cdrom_ioctl_log("Cooked\n"); else
/* Cooked */ /* Cooked */
} dummy_cdrom_ioctl_log("Cooked\n");
plat_cdrom_close();
dummy_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
return -1; plat_cdrom_close(ioctl);
dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector);
return 0;
} }
void void
plat_cdrom_eject(void) plat_cdrom_eject(void *local)
{ {
plat_cdrom_open(); dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_close();
plat_cdrom_open(ioctl);
plat_cdrom_close(ioctl);
} }
void void
plat_cdrom_close(void) plat_cdrom_close(UNUSED(void *local))
{ {
} }
int 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; return 1;
} }
int
plat_cdrom_get_local_size(void)
{
return sizeof(dummy_cdrom_ioctl_t);
}

View File

@@ -220,7 +220,7 @@ SettingsFloppyCDROM::save()
for (int i = 0; i < CDROM_NUM; i++) { for (int i = 0; i < CDROM_NUM; i++) {
cdrom[i].priv = NULL; cdrom[i].priv = NULL;
cdrom[i].ops = NULL; cdrom[i].ops = NULL;
cdrom[i].image = NULL; cdrom[i].local = NULL;
cdrom[i].insert = NULL; cdrom[i].insert = NULL;
cdrom[i].close = NULL; cdrom[i].close = NULL;
cdrom[i].get_volume = NULL; cdrom[i].get_volume = NULL;

View File

@@ -43,11 +43,16 @@
of the audio while audio still plays. With an absolute conversion, the counter is fine. */ 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) #define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
static int toc_valid = 0; typedef struct win_cdrom_ioctl_t {
static CDROM_TOC cur_toc = { 0 }; int toc_valid;
static HANDLE handle = NULL; uint8_t cur_toc[65536];
static WCHAR ioctl_path[256] = { 0 }; CDROM_READ_TOC_EX cur_read_toc_ex;
static WCHAR old_ioctl_path[256] = { 0 }; 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 #ifdef ENABLE_WIN_CDROM_IOCTL_LOG
int win_cdrom_ioctl_do_log = 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 #endif
static int 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); plat_cdrom_close(local);
win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError());
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 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); plat_cdrom_close(local);
win_cdrom_ioctl_log("handle=%p, error=%x\n", handle, (unsigned int) GetLastError());
if (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());
if (ioctl->handle != INVALID_HANDLE_VALUE) {
long size; 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 1;
} }
return 0; return 0;
} }
static void static int
plat_cdrom_read_toc(void) plat_cdrom_read_normal_toc(win_cdrom_ioctl_t *ioctl, uint8_t *toc_buf)
{ {
long size = 0; long size = 0;
if (!toc_valid) { memset(toc_buf, 0x00, 65536);
toc_valid = 1; plat_cdrom_open(ioctl);
plat_cdrom_open(); int temp = DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_TOC, NULL, 0, toc_buf, 65535, (LPDWORD) &size, NULL);
DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, NULL, 0, &cur_toc, sizeof(cur_toc), (LPDWORD)&size, NULL); plat_cdrom_close(ioctl);
plat_cdrom_close(); #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 int
plat_cdrom_is_track_audio(uint32_t sector) plat_cdrom_is_track_audio(void *local, uint32_t sector)
{ {
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
int control = 0; int control = 0;
uint32_t track_addr = 0; uint32_t cur_addr = 0;
uint32_t next_track_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", win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n",
cur_toc.FirstTrack, cur_toc.LastTrack, toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c,
cur_toc.TrackData[c].TrackNumber, c, cur_td->Control, track_addr, sector);
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) && if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) &&
(sector >= track_addr) && (sector < next_track_addr)) { (sector >= cur_addr) && (sector < next_addr)) {
control = cur_toc.TrackData[c].Control; control = cur_td->Control;
break; break;
} }
} }
@@ -137,24 +223,30 @@ plat_cdrom_is_track_audio(uint32_t sector)
} }
int int
plat_cdrom_is_track_pre(uint32_t sector) plat_cdrom_is_track_pre(void *local, uint32_t sector)
{ {
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
int control = 0; int control = 0;
uint32_t track_addr = 0; uint32_t cur_addr = 0;
uint32_t next_track_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", win_cdrom_ioctl_log("F: %i, L: %i, C: %i (%i), c: %02X, A: %08X, S: %08X\n",
cur_toc.FirstTrack, cur_toc.LastTrack, toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c,
cur_toc.TrackData[c].TrackNumber, c, cur_td->Control, cur_addr, sector);
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) && if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) &&
(sector >= track_addr) && (sector < next_track_addr)) { (sector >= cur_addr) && (sector < next_addr)) {
control = cur_toc.TrackData[c].Control; control = cur_td->Control;
break; break;
} }
} }
@@ -167,81 +259,91 @@ plat_cdrom_is_track_pre(uint32_t sector)
} }
uint32_t 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; win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
uint32_t next_track_addr = 0; 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", 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, toc->FirstTrack, toc->LastTrack, cur_td->TrackNumber, c,
cur_toc.TrackData[c].TrackNumber, c, cur_td->Control, cur_td->Adr, cur_addr, sector);
cur_toc.TrackData[c].Control, cur_toc.TrackData[c].Adr,
track_addr, sector); if ((cur_td->TrackNumber >= toc->FirstTrack) && (cur_td->TrackNumber <= toc->LastTrack) &&
if ((cur_toc.TrackData[c].TrackNumber >= cur_toc.FirstTrack) && (cur_toc.TrackData[c].TrackNumber <= cur_toc.LastTrack) && (sector >= cur_addr) && (sector < next_addr)) {
(sector >= track_addr) && (sector < next_track_addr)) { *track = cur_td->TrackNumber;
*track = cur_toc.TrackData[c].TrackNumber; *attr = cur_td->Control;
*attr = cur_toc.TrackData[c].Control; *attr |= ((cur_td->Adr << 4) & 0xf0);
*attr |= ((cur_toc.TrackData[c].Adr << 4) & 0xf0);
break; 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 uint32_t
plat_cdrom_get_last_block(void) plat_cdrom_get_last_block(void *local)
{ {
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
PCDROM_TOC toc = (PCDROM_TOC) ioctl->cur_toc;
uint32_t lb = 0; uint32_t lb = 0;
uint32_t address = 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) if (address > lb)
lb = address; lb = address;
} }
win_cdrom_ioctl_log("LBCapacity=%d\n", lb); win_cdrom_ioctl_log("LBCapacity=%d\n", lb);
return lb; return lb;
} }
int int
plat_cdrom_ext_medium_changed(void) plat_cdrom_ext_medium_changed(void *local)
{ {
long size; win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
CDROM_TOC toc; 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 ret = 0;
int temp = plat_cdrom_read_normal_toc(ioctl, new_toc_buf);
PTRACK_DATA cur_ltd = &toc->TrackData[toc->LastTrack];
plat_cdrom_open(); if (temp != 0)
int temp = DeviceIoControl(handle, IOCTL_CDROM_READ_TOC, plat_cdrom_read_raw_toc(ioctl);
NULL, 0, &toc, sizeof(toc),
(LPDWORD)&size, NULL);
plat_cdrom_close();
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 /* There has been some kind of error - not a medium change, but a not ready
condition. */ condition. */
ret = -1; 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. */ /* Changed to a different host drive - we already detect such medium changes. */
toc_valid = 1; ioctl->toc_valid = 1;
cur_toc = toc; memcpy(toc, new_toc, 65535);
if (memcmp(ioctl_path, old_ioctl_path, sizeof(ioctl_path)) != 0) if (memcmp(ioctl->path, ioctl->old_path, sizeof(ioctl->path)) != 0)
memcpy(old_ioctl_path, ioctl_path, sizeof(ioctl_path)); memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path));
} else if ((toc.TrackData[toc.LastTrack].Address[1] != } else if (memcmp(&(new_ltd->Address[1]), &(cur_ltd->Address[1]), 3))
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]))
/* The TOC has changed. */ /* The TOC has changed. */
ret = 1; ret = 1;
@@ -251,15 +353,20 @@ plat_cdrom_ext_medium_changed(void)
} }
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; *st_track = 1;
*end = cur_toc.LastTrack; *end = toc->LastTrack;
lead_out->min = cur_toc.TrackData[cur_toc.LastTrack].Address[1]; lead_out->min = ltd->Address[1];
lead_out->sec = cur_toc.TrackData[cur_toc.LastTrack].Address[2]; lead_out->sec = ltd->Address[2];
lead_out->fr = cur_toc.TrackData[cur_toc.LastTrack].Address[3]; lead_out->fr = ltd->Address[3];
win_cdrom_ioctl_log("plat_cdrom_get_audio_tracks(): %02i, %02i, %02i:%02i:%02i\n", 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); *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. */ /* This replaces both Info and EndInfo, they are specified by a variable. */
int 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); win_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track);
return 0; return 0;
} }
start->min = cur_toc.TrackData[track - 1].Address[1]; PTRACK_DATA td = &toc->TrackData[track - 1];
start->sec = cur_toc.TrackData[track - 1].Address[2];
start->fr = cur_toc.TrackData[track - 1].Address[3];
*track_num = cur_toc.TrackData[track - 1].TrackNumber; start->min = td->Address[1];
*attr = cur_toc.TrackData[track - 1].Control; start->sec = td->Address[2];
*attr |= ((cur_toc.TrackData[track - 1].Adr << 4) & 0xf0); 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", 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); 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. */ /* TODO: See if track start is adjusted by 150 or not. */
int 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; CDROM_SUB_Q_DATA_FORMAT insub;
SUB_Q_CHANNEL_DATA sub; SUB_Q_CHANNEL_DATA sub;
long size = 0; long size = 0;
insub.Format = IOCTL_CDROM_CURRENT_POSITION; insub.Format = IOCTL_CDROM_CURRENT_POSITION;
plat_cdrom_open(); plat_cdrom_open(ioctl);
DeviceIoControl(handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); DeviceIoControl(ioctl->handle, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub),
plat_cdrom_close(); (LPDWORD) &size, NULL);
plat_cdrom_close(ioctl);
if (sub.CurrentPosition.TrackNumber < 1) if (sub.CurrentPosition.TrackNumber < 1)
return 0; 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]; 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", 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; return 1;
} }
int int
plat_cdrom_get_sector_size(UNUSED(uint32_t sector)) plat_cdrom_get_sector_size(void *local, UNUSED(uint32_t sector))
{ {
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
long size; long size;
DISK_GEOMETRY dgCDROM; DISK_GEOMETRY dgCDROM;
plat_cdrom_open(); plat_cdrom_open(ioctl);
DeviceIoControl(handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM), (LPDWORD)&size, NULL); DeviceIoControl(ioctl->handle, IOCTL_CDROM_GET_DRIVE_GEOMETRY, NULL, 0, &dgCDROM, sizeof(dgCDROM),
plat_cdrom_close(); (LPDWORD) &size, NULL);
plat_cdrom_close(ioctl);
win_cdrom_ioctl_log("BytesPerSector=%d\n", dgCDROM.BytesPerSector); win_cdrom_ioctl_log("BytesPerSector=%d\n", dgCDROM.BytesPerSector);
return dgCDROM.BytesPerSector; return dgCDROM.BytesPerSector;
} }
int 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)
{ {
win_cdrom_ioctl_t * ioctl = (win_cdrom_ioctl_t *) local;
int status; int status;
long size = 0; long size = 0;
int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; int buflen = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
plat_cdrom_open(); plat_cdrom_open(ioctl);
if (raw) { if (raw) {
win_cdrom_ioctl_log("Raw\n");
/* Raw */ /* Raw */
win_cdrom_ioctl_log("Raw\n");
RAW_READ_INFO in; RAW_READ_INFO in;
in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE; in.DiskOffset.LowPart = sector * COOKED_SECTOR_SIZE;
in.DiskOffset.HighPart = 0; in.DiskOffset.HighPart = 0;
in.SectorCount = 1; in.SectorCount = 1;
in.TrackMode = CDDA; in.TrackMode = CDDA;
status = DeviceIoControl(handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in), status = DeviceIoControl(ioctl->handle, IOCTL_CDROM_RAW_READ, &in, sizeof(in),
buffer, buflen, (LPDWORD) &size, NULL); buffer, buflen, (LPDWORD) &size, NULL);
} else { } else {
win_cdrom_ioctl_log("Cooked\n");
/* Cooked */ /* Cooked */
win_cdrom_ioctl_log("Cooked\n");
int success = 0; 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) if (newPos != 0xFFFFFFFF)
success = ReadFile(handle, buffer, buflen, (LPDWORD)&size, NULL); success = ReadFile(ioctl->handle, buffer, buflen, (LPDWORD) &size, NULL);
status = (success != 0); 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); win_cdrom_ioctl_log("ReadSector status=%d, sector=%d, size=%" PRId64 ".\n", status, sector, (long long) size);
return (status > 0) ? (size == buflen) : -1; return (status > 0) ? (size == buflen) : -1;
} }
void void
plat_cdrom_eject(void) plat_cdrom_eject(void *local)
{ {
win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
long size; long size;
plat_cdrom_open(); plat_cdrom_open(ioctl);
DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); DeviceIoControl(ioctl->handle, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD) &size, NULL);
plat_cdrom_close(ioctl);
plat_cdrom_close();
} }
void void
plat_cdrom_close(void) plat_cdrom_close(void *local)
{ {
if (handle != NULL) { win_cdrom_ioctl_t *ioctl = (win_cdrom_ioctl_t *) local;
CloseHandle(handle);
handle = NULL; if (ioctl->handle != NULL) {
CloseHandle(ioctl->handle);
ioctl->handle = NULL;
} }
} }
int 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)); plat_cdrom_close(ioctl);
memset(ioctl_path, 0x00, sizeof(ioctl_path));
wsprintf(ioctl_path, L"%S", drv); memcpy(ioctl->old_path, ioctl->path, sizeof(ioctl->path));
win_cdrom_ioctl_log("Path is %S\n", 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; return 1;
} }
int
plat_cdrom_get_local_size(void)
{
return sizeof(win_cdrom_ioctl_t);
}

View File

@@ -35,7 +35,9 @@
of the audio while audio still plays. With an absolute conversion, the counter is fine. */ 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) #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 #ifdef ENABLE_DUMMY_CDROM_IOCTL_LOG
int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG; int dummy_cdrom_ioctl_do_log = ENABLE_DUMMY_CDROM_IOCTL_LOG;
@@ -56,28 +58,39 @@ dummy_cdrom_ioctl_log(const char *fmt, ...)
#endif #endif
static int static int
plat_cdrom_open(void) plat_cdrom_open(void *local)
{ {
return 0; return 0;
} }
static int static int
plat_cdrom_load(void) plat_cdrom_load(void *local)
{ {
return 0; return 0;
} }
static void static void
plat_cdrom_read_toc(void) plat_cdrom_read_toc(void *local)
{ {
if (!toc_valid) dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
toc_valid = 1;
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 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;
plat_cdrom_read_toc(ioctl);
const int ret = 0; const int ret = 0;
@@ -87,9 +100,11 @@ plat_cdrom_is_track_audio(uint32_t sector)
} }
int 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; const int ret = 0;
@@ -99,24 +114,29 @@ plat_cdrom_is_track_pre(uint32_t sector)
} }
uint32_t 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; return 0x00000000;
} }
uint32_t 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; return 0x00000000;
} }
int int
plat_cdrom_ext_medium_changed(void) plat_cdrom_ext_medium_changed(void *local)
{ {
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
int ret = 0; int ret = 0;
dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret); dummy_cdrom_ioctl_log("plat_cdrom_ext_medium_changed(): %i\n", ret);
@@ -125,9 +145,11 @@ plat_cdrom_ext_medium_changed(void)
} }
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; *st_track = 1;
*end = 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. */ /* This replaces both Info and EndInfo, they are specified by a variable. */
int 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)) { if ((track < 1) || (track == 0xaa)) {
dummy_cdrom_ioctl_log("plat_cdrom_get_audio_track_info(%02i)\n", track); 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. */ /* TODO: See if track start is adjusted by 150 or not. */
int 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; *track = 1;
*attr = 0x14; *attr = 0x14;
@@ -185,7 +210,7 @@ plat_cdrom_get_audio_sub(UNUSED(uint32_t sector), uint8_t *attr, uint8_t *track,
} }
int 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"); dummy_cdrom_ioctl_log("BytesPerSector=2048\n");
@@ -193,42 +218,56 @@ plat_cdrom_get_sector_size(UNUSED(uint32_t sector))
} }
int 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) { plat_cdrom_open(ioctl);
dummy_cdrom_ioctl_log("Raw\n");
if (raw)
/* Raw */ /* Raw */
} else { dummy_cdrom_ioctl_log("Raw\n");
dummy_cdrom_ioctl_log("Cooked\n"); else
/* Cooked */ /* Cooked */
} dummy_cdrom_ioctl_log("Cooked\n");
plat_cdrom_close();
plat_cdrom_close(ioctl);
dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector); dummy_cdrom_ioctl_log("ReadSector sector=%d.\n", sector);
return 0; return 0;
} }
void void
plat_cdrom_eject(void) plat_cdrom_eject(void *local)
{ {
plat_cdrom_open(); dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
plat_cdrom_close();
plat_cdrom_open(ioctl);
plat_cdrom_close(ioctl);
} }
void void
plat_cdrom_close(void) plat_cdrom_close(UNUSED(void *local))
{ {
} }
int 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; return 1;
} }
int
plat_cdrom_get_local_size(void)
{
return sizeof(dummy_cdrom_ioctl_t);
}