Rewritten the CD-ROM image handling and Cue sheet parsing, also fixes crashes when using VISO.

This commit is contained in:
OBattler
2025-01-02 22:38:10 +01:00
parent 91770134b8
commit 7ad3b81058
10 changed files with 858 additions and 968 deletions

View File

@@ -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

View File

@@ -8,9 +8,7 @@
*
* Virtual ISO CD-ROM image back-end.
*
*
*
* Authors: RichardG <richardg867@gmail.com>
* Authors: RichardG, <richardg867@gmail.com>
*
* Copyright 2022 RichardG.
*/

View File

@@ -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,

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)