Rewritten the CD-ROM image handling and Cue sheet parsing, also fixes crashes when using VISO.
This commit is contained in:
@@ -58,26 +58,32 @@ cdrom_image_log(const char *fmt, ...)
|
||||
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 void
|
||||
image_get_tracks(cdrom_t *dev, int *first, int *last)
|
||||
{
|
||||
cd_img_t *img = (cd_img_t *) dev->local;
|
||||
TMSF tmsf;
|
||||
|
||||
cdi_get_audio_tracks(img, first, last, &tmsf);
|
||||
}
|
||||
|
||||
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->local;
|
||||
TMSF tmsf;
|
||||
track_t *ct = NULL;
|
||||
|
||||
cdi_get_audio_track_info(img, end, track, &ti->number, &tmsf, &ti->attr);
|
||||
for (int i = 0; i < img->tracks_num; i++) {
|
||||
ct = &(img->tracks[i]);
|
||||
if (ct->point == track)
|
||||
break;
|
||||
}
|
||||
|
||||
ti->m = tmsf.min;
|
||||
ti->s = tmsf.sec;
|
||||
ti->f = tmsf.fr;
|
||||
ti->number = ct->point;
|
||||
|
||||
if (ct == NULL) {
|
||||
ti->attr = 0x14;
|
||||
ti->m = 0;
|
||||
ti->s = 2;
|
||||
ti->f = 0;
|
||||
} else {
|
||||
uint32_t pos = end ? ct->idx[1].start : (ct->idx[1].start + ct->idx[1].length);
|
||||
ti->attr = ct->attr;
|
||||
ti->m = (pos / 75) / 60;
|
||||
ti->s = (pos / 75) % 60;
|
||||
ti->f = pos % 75;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -113,24 +119,22 @@ static int
|
||||
image_get_capacity(cdrom_t *dev)
|
||||
{
|
||||
cd_img_t *img = (cd_img_t *) dev->local;
|
||||
int first_track;
|
||||
int last_track;
|
||||
int number;
|
||||
unsigned char attr;
|
||||
uint32_t address = 0;
|
||||
uint32_t lb = 0;
|
||||
track_t *lo = NULL;
|
||||
|
||||
if (!img)
|
||||
return 0;
|
||||
|
||||
cdi_get_audio_tracks_lba(img, &first_track, &last_track, &lb);
|
||||
|
||||
for (int c = 0; c <= last_track; c++) {
|
||||
cdi_get_audio_track_info_lba(img, 0, c + 1, &number, &address, &attr);
|
||||
if (address > lb)
|
||||
lb = address;
|
||||
for (int i = (img->tracks_num - 1); i >= 0; i--) {
|
||||
if (img->tracks[i].point == 0xa2) {
|
||||
lo = &(img->tracks[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lo != NULL)
|
||||
lb = lo->idx[1].start - 1;
|
||||
|
||||
return lb;
|
||||
}
|
||||
|
||||
@@ -138,13 +142,9 @@ static int
|
||||
image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
|
||||
{
|
||||
cd_img_t *img = (cd_img_t *) dev->local;
|
||||
uint8_t attr;
|
||||
TMSF tmsf;
|
||||
int m;
|
||||
int s;
|
||||
int f;
|
||||
int number;
|
||||
int track;
|
||||
|
||||
if (!img || (dev->cd_status == CD_STATUS_DATA_ONLY))
|
||||
return 0;
|
||||
@@ -156,29 +156,18 @@ image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf)
|
||||
pos = MSFtoLBA(m, s, f) - 150;
|
||||
}
|
||||
|
||||
/* GetTrack requires LBA. */
|
||||
track = cdi_get_track(img, pos);
|
||||
if (track == -1)
|
||||
return 0;
|
||||
else {
|
||||
cdi_get_audio_track_info(img, 0, track, &number, &tmsf, &attr);
|
||||
return attr == AUDIO_TRACK;
|
||||
}
|
||||
return cdi_is_audio(img, pos);
|
||||
}
|
||||
|
||||
static int
|
||||
image_is_track_pre(cdrom_t *dev, uint32_t lba)
|
||||
{
|
||||
cd_img_t *img = (cd_img_t *) dev->local;
|
||||
int track;
|
||||
|
||||
/* GetTrack requires LBA. */
|
||||
track = cdi_get_track(img, lba);
|
||||
if (!img || (dev->cd_status == CD_STATUS_DATA_ONLY))
|
||||
return 0;
|
||||
|
||||
if (track != -1)
|
||||
return cdi_get_audio_track_pre(img, track);
|
||||
|
||||
return 0;
|
||||
return cdi_is_pre(img, lba);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -238,7 +227,6 @@ image_exit(cdrom_t *dev)
|
||||
}
|
||||
|
||||
static const cdrom_ops_t cdrom_image_ops = {
|
||||
image_get_tracks,
|
||||
image_get_track_info,
|
||||
image_get_raw_track_info,
|
||||
image_get_subchannel,
|
||||
@@ -270,14 +258,13 @@ cdrom_image_open(cdrom_t *dev, const char *fn)
|
||||
strcpy(dev->image_path, fn);
|
||||
|
||||
/* Create new instance of the CDROM_Image class. */
|
||||
img = (cd_img_t *) malloc(sizeof(cd_img_t));
|
||||
img = (cd_img_t *) calloc(1, sizeof(cd_img_t));
|
||||
|
||||
/* This guarantees that if ops is not NULL, then
|
||||
neither is the image pointer. */
|
||||
if (!img)
|
||||
if (img == NULL)
|
||||
return image_open_abort(dev);
|
||||
|
||||
memset(img, 0, sizeof(cd_img_t));
|
||||
dev->local = img;
|
||||
|
||||
/* Open the image. */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,9 +8,7 @@
|
||||
*
|
||||
* Virtual ISO CD-ROM image back-end.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG <richardg867@gmail.com>
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2022 RichardG.
|
||||
*/
|
||||
|
||||
@@ -55,14 +55,6 @@ cdrom_ioctl_log(const char *fmt, ...)
|
||||
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 void
|
||||
ioctl_get_tracks(cdrom_t *dev, int *first, int *last)
|
||||
{
|
||||
TMSF tmsf;
|
||||
|
||||
plat_cdrom_get_audio_tracks(dev->local, first, last, &tmsf);
|
||||
}
|
||||
|
||||
static void
|
||||
ioctl_get_track_info(cdrom_t *dev, uint32_t track, int end, track_info_t *ti)
|
||||
{
|
||||
@@ -209,7 +201,6 @@ 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,
|
||||
|
||||
@@ -218,7 +218,6 @@ typedef struct 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);
|
||||
|
||||
@@ -6,16 +6,15 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* CD-ROM image file handling module header , translated to C
|
||||
* from cdrom_dosbox.h.
|
||||
* CD-ROM image file handling module header.
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* The DOSBox Team, <unknown>
|
||||
* RichardG, <richardg867@gmail.com>
|
||||
* Cacodemon345
|
||||
*
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
* Copyright 2017-2020 Fred N. van Kempen.
|
||||
* Copyright 2002-2020 The DOSBox Team.
|
||||
* Copyright 2016-2025 Miran Grca.
|
||||
* Copyright 2016-2025 Miran Grca.
|
||||
* Copyright 2024-2025 Cacodemon345.
|
||||
*/
|
||||
#ifndef CDROM_IMAGE_BACKEND_H
|
||||
#define CDROM_IMAGE_BACKEND_H
|
||||
@@ -57,72 +56,59 @@ 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)
|
||||
#define INDEX_SPECIAL -2 /* Track A0h onwards. */
|
||||
#define INDEX_NONE -1 /* Empty block. */
|
||||
#define INDEX_ZERO 0 /* Block not in the file, return all 0x00's. */
|
||||
#define INDEX_NORMAL 1 /* Block in the file. */
|
||||
|
||||
typedef struct track_index_t {
|
||||
/* Is the current block in the file? If not, return all 0x00's. */
|
||||
int in_file;
|
||||
/* Is the current block in the file? If not, return all 0x00's. -1 means not yet loaded. */
|
||||
int32_t type;
|
||||
/* The amount of bytes to skip at the beginning of each sector. */
|
||||
int skip;
|
||||
int32_t skip;
|
||||
/* Starting and ending sector LBA - negative in order to accomodate LBA -150 to -1
|
||||
to read the pregap of track 1. */
|
||||
uint64_t start;
|
||||
uint64_t length;
|
||||
uint64_t file_start;
|
||||
uint64_t file_length;
|
||||
track_file_t *file;
|
||||
} track_index_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;
|
||||
int sector_size;
|
||||
int mode2;
|
||||
int form;
|
||||
int pre;
|
||||
int noskip; /* Do not skip by 8 bytes.*/
|
||||
uint64_t start;
|
||||
uint64_t length;
|
||||
uint64_t skip;
|
||||
track_index_t indexes[3];
|
||||
track_file_t *file;
|
||||
uint8_t session;
|
||||
uint8_t attr;
|
||||
uint8_t tno;
|
||||
uint8_t point;
|
||||
uint8_t extra[4];
|
||||
uint8_t mode;
|
||||
uint8_t form;
|
||||
uint8_t pad;
|
||||
uint8_t skip;
|
||||
uint32_t sector_size;
|
||||
track_index_t idx[3];
|
||||
} track_t;
|
||||
|
||||
typedef struct cd_img_t {
|
||||
int tracks_num;
|
||||
track_t *tracks;
|
||||
int32_t tracks_num;
|
||||
track_t *tracks;
|
||||
} cd_img_t;
|
||||
|
||||
/* Binary file functions. */
|
||||
extern void cdi_close(cd_img_t *cdi);
|
||||
extern int cdi_set_device(cd_img_t *cdi, const char *path);
|
||||
extern void cdi_get_audio_tracks(cd_img_t *cdi, int *st_track, int *end, TMSF *lead_out);
|
||||
extern void cdi_get_audio_tracks_lba(cd_img_t *cdi, int *st_track, int *end, uint32_t *lead_out);
|
||||
extern int cdi_get_audio_track_pre(cd_img_t *cdi, int track);
|
||||
extern int cdi_get_audio_track_info(cd_img_t *cdi, int end, int track, int *track_num,
|
||||
TMSF *start, uint8_t *attr);
|
||||
extern int cdi_get_audio_track_info_lba(cd_img_t *cdi, int end, int track, int *track_num,
|
||||
uint32_t *start, uint8_t *attr);
|
||||
extern void cdi_get_raw_track_info(cd_img_t *cdi, int *num, uint8_t *buffer);
|
||||
extern int cdi_get_track(cd_img_t *cdi, uint32_t sector);
|
||||
extern int cdi_get_audio_sub(cd_img_t *cdi, uint32_t sector, uint8_t *attr, uint8_t *track,
|
||||
uint8_t *index, TMSF *rel_pos, TMSF *abs_pos);
|
||||
extern int cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector);
|
||||
extern int cdi_read_sectors(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector, uint32_t num);
|
||||
extern int cdi_read_sector_sub(cd_img_t *cdi, uint8_t *buffer, uint32_t sector);
|
||||
extern int cdi_get_sector_size(cd_img_t *cdi, uint32_t sector);
|
||||
extern int cdi_is_audio(cd_img_t *cdi, uint32_t sector);
|
||||
extern int cdi_is_pre(cd_img_t *cdi, uint32_t sector);
|
||||
extern int cdi_is_mode2(cd_img_t *cdi, uint32_t sector);
|
||||
extern int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector);
|
||||
extern int cdi_load_iso(cd_img_t *cdi, const char *filename);
|
||||
extern int cdi_load_cue(cd_img_t *cdi, const char *cuefile);
|
||||
extern int cdi_has_data_track(cd_img_t *cdi);
|
||||
extern int cdi_has_audio_track(cd_img_t *cdi);
|
||||
extern void cdi_close(cd_img_t *cdi);
|
||||
extern int cdi_set_device(cd_img_t *cdi, const char *path);
|
||||
|
||||
/* Virtual ISO functions. */
|
||||
extern int viso_read(void *priv, uint8_t *buffer, uint64_t seek, size_t count);
|
||||
|
||||
@@ -53,7 +53,6 @@ extern void plat_cdrom_get_raw_track_info(void *local, int *num, raw_track_i
|
||||
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,
|
||||
|
||||
@@ -144,23 +144,6 @@ plat_cdrom_ext_medium_changed(void *local)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
|
||||
{
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
*st_track = 1;
|
||||
*end = 1;
|
||||
lead_out->min = 0;
|
||||
lead_out->sec = 0;
|
||||
lead_out->fr = 2;
|
||||
|
||||
dummy_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);
|
||||
}
|
||||
|
||||
/* This replaces both Info and EndInfo, they are specified by a variable. */
|
||||
int
|
||||
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
|
||||
@@ -398,26 +398,6 @@ plat_cdrom_ext_medium_changed(void *local)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
|
||||
{
|
||||
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 = 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);
|
||||
}
|
||||
|
||||
/* This replaces both Info and EndInfo, they are specified by a variable. */
|
||||
int
|
||||
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
|
||||
@@ -144,23 +144,6 @@ plat_cdrom_ext_medium_changed(void *local)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
plat_cdrom_get_audio_tracks(void *local, int *st_track, int *end, TMSF *lead_out)
|
||||
{
|
||||
dummy_cdrom_ioctl_t *ioctl = (dummy_cdrom_ioctl_t *) local;
|
||||
|
||||
plat_cdrom_read_toc(ioctl);
|
||||
|
||||
*st_track = 1;
|
||||
*end = 1;
|
||||
lead_out->min = 0;
|
||||
lead_out->sec = 0;
|
||||
lead_out->fr = 2;
|
||||
|
||||
dummy_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);
|
||||
}
|
||||
|
||||
/* This replaces both Info and EndInfo, they are specified by a variable. */
|
||||
int
|
||||
plat_cdrom_get_audio_track_info(void *local, UNUSED(int end), int track, int *track_num, TMSF *start, uint8_t *attr)
|
||||
|
||||
Reference in New Issue
Block a user