Fixed Mode 2 handling again and added support for reading raw sectors from non-raw images with reconstructed headers.
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
* CD-ROM image file handling module, translated to C from
|
||||
* cdrom_dosbox.cpp.
|
||||
*
|
||||
* Version: @(#)cdrom_image_backend.c 1.0.0 2019/12/19
|
||||
* Version: @(#)cdrom_image_backend.c 1.0.1 2019/12/21
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "cdrom_image_backend.h"
|
||||
|
||||
|
||||
#define CDROM_BCD(x) (((x) % 10) | (((x) / 10) << 4))
|
||||
|
||||
#define MAX_LINE_LENGTH 512
|
||||
#define MAX_FILENAME_LENGTH 256
|
||||
#define CROSS_LEN 512
|
||||
@@ -308,33 +310,61 @@ cdi_read_sector(cd_img_t *cdi, uint8_t *buffer, int raw, uint32_t sector)
|
||||
{
|
||||
size_t length;
|
||||
int track = cdi_get_track(cdi, sector) - 1;
|
||||
uint64_t s = (uint64_t) sector, seek;
|
||||
uint64_t sect = (uint64_t) sector, seek;
|
||||
track_t *trk;
|
||||
int track_is_raw, ret;
|
||||
int raw_size, cooked_size;
|
||||
uint64_t offset = 0ULL;
|
||||
int m = 0, s = 0, f = 0;
|
||||
|
||||
if (track < 0)
|
||||
return 0;
|
||||
|
||||
trk = &cdi->tracks[track];
|
||||
seek = trk->skip + ((s - trk->start) * trk->sector_size);
|
||||
track_is_raw = ((trk->sector_size == RAW_SECTOR_SIZE) || (trk->sector_size == 2448));
|
||||
if (raw && !track_is_raw)
|
||||
return 0;
|
||||
seek = trk->skip + ((sect - trk->start) * trk->sector_size);
|
||||
|
||||
if (track_is_raw)
|
||||
raw_size = trk->sector_size;
|
||||
else
|
||||
raw_size = 2448;
|
||||
|
||||
/* TODO: Is this correct? Is cooked sector size 2336 for all Mode 2 variants? */
|
||||
if (trk->mode2 && (trk->form != 1)) {
|
||||
if (trk->form == 2)
|
||||
length = (raw ? RAW_SECTOR_SIZE : 2324);
|
||||
cooked_size = (track_is_raw ? 2328 : trk->sector_size); /* Both 2324 + ECC and 2328 variants are valid. */
|
||||
else
|
||||
length = (raw ? RAW_SECTOR_SIZE : 2336);
|
||||
cooked_size = 2336;
|
||||
} else
|
||||
length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE);
|
||||
cooked_size = COOKED_SECTOR_SIZE;
|
||||
|
||||
if (raw && (trk->sector_size != RAW_SECTOR_SIZE))
|
||||
return 0;
|
||||
if (!raw && !trk->mode2 && (trk->sector_size == RAW_SECTOR_SIZE))
|
||||
seek += 16ULL;
|
||||
/* TODO: See if Mode 2 is handled correctly here. */
|
||||
if (!raw && trk->mode2)
|
||||
seek += 24ULL;
|
||||
length = (raw ? raw_size : cooked_size);
|
||||
|
||||
return trk->file->read(trk->file, buffer, seek, length);
|
||||
if (trk->mode2 && (trk->form >= 1))
|
||||
offset = 24ULL;
|
||||
else
|
||||
offset = 16ULL;
|
||||
|
||||
if (raw && !track_is_raw) {
|
||||
memset(buffer, 0x00, 2448);
|
||||
ret = trk->file->read(trk->file, buffer + offset, seek, length);
|
||||
if (!ret)
|
||||
return 0;
|
||||
/* Construct the rest of the raw sector. */
|
||||
memset(buffer + 1, 0xff, 10);
|
||||
buffer += 12;
|
||||
FRAMES_TO_MSF(sector + 150, &m, &s, &f);
|
||||
/* These have to be BCD. */
|
||||
buffer[12] = CDROM_BCD(m & 0xff);
|
||||
buffer[13] = CDROM_BCD(s & 0xff);
|
||||
buffer[14] = CDROM_BCD(f & 0xff);
|
||||
buffer[15] = trk->mode2 ? 2 : 1; /* Data, should reflect the actual sector type. */
|
||||
return 1;
|
||||
} else if (!raw && track_is_raw)
|
||||
return trk->file->read(trk->file, buffer, seek + offset, length);
|
||||
else
|
||||
return trk->file->read(trk->file, buffer, seek, length);
|
||||
}
|
||||
|
||||
|
||||
@@ -429,15 +459,15 @@ cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2)
|
||||
static int
|
||||
cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2, int form)
|
||||
{
|
||||
uint8_t pvd[COOKED_SECTOR_SIZE];
|
||||
uint64_t seek = 16ULL * sector_size; /* First VD is located at sector 16. */
|
||||
|
||||
if (!mode2 && (sector_size == RAW_SECTOR_SIZE))
|
||||
if ((!mode2 || (form == 0)) && (sector_size == RAW_SECTOR_SIZE))
|
||||
seek += 16;
|
||||
if (mode2)
|
||||
if (mode2 && (form >= 1))
|
||||
seek += 24;
|
||||
|
||||
file->read(file, pvd, seek, COOKED_SECTOR_SIZE);
|
||||
@@ -490,16 +520,16 @@ cdi_load_iso(cd_img_t *cdi, const wchar_t *filename)
|
||||
trk.form = 0;
|
||||
trk.mode2 = 0;
|
||||
/* TODO: Merge the first and last cases since they result in the same thing. */
|
||||
if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 0))
|
||||
if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 0, 0))
|
||||
trk.sector_size = RAW_SECTOR_SIZE;
|
||||
else if (cdi_can_read_pvd(trk.file, 2336, 1)) {
|
||||
else if (cdi_can_read_pvd(trk.file, 2336, 1, 0)) {
|
||||
trk.sector_size = 2336;
|
||||
trk.mode2 = 1;
|
||||
} else if (cdi_can_read_pvd(trk.file, 2324, 1)) {
|
||||
} else if (cdi_can_read_pvd(trk.file, 2324, 1, 2)) {
|
||||
trk.sector_size = 2324;
|
||||
trk.mode2 = 1;
|
||||
trk.form = 2;
|
||||
} else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1)) {
|
||||
} else if (cdi_can_read_pvd(trk.file, RAW_SECTOR_SIZE, 1, 0)) {
|
||||
trk.sector_size = RAW_SECTOR_SIZE;
|
||||
trk.mode2 = 1;
|
||||
} else {
|
||||
@@ -771,6 +801,9 @@ cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile)
|
||||
} else if (!strcmp(type, "MODE1/2352")) {
|
||||
trk.sector_size = RAW_SECTOR_SIZE;
|
||||
trk.attr = DATA_TRACK;
|
||||
} else if (!strcmp(type, "MODE1/2448")) {
|
||||
trk.sector_size = 2448;
|
||||
trk.attr = DATA_TRACK;
|
||||
} else if (!strcmp(type, "MODE2/2048")) {
|
||||
trk.form = 1;
|
||||
trk.sector_size = COOKED_SECTOR_SIZE;
|
||||
@@ -781,6 +814,11 @@ cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile)
|
||||
trk.sector_size = 2324;
|
||||
trk.attr = DATA_TRACK;
|
||||
trk.mode2 = 1;
|
||||
} else if (!strcmp(type, "MODE2/2328")) {
|
||||
trk.form = 2;
|
||||
trk.sector_size = 2328;
|
||||
trk.attr = DATA_TRACK;
|
||||
trk.mode2 = 1;
|
||||
} else if (!strcmp(type, "MODE2/2336")) {
|
||||
trk.sector_size = 2336;
|
||||
trk.attr = DATA_TRACK;
|
||||
@@ -790,6 +828,11 @@ cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile)
|
||||
trk.sector_size = RAW_SECTOR_SIZE;
|
||||
trk.attr = DATA_TRACK;
|
||||
trk.mode2 = 1;
|
||||
} else if (!strcmp(type, "MODE2/2448")) {
|
||||
trk.form = 1; /* Assume this is XA Mode 2 Form 1. */
|
||||
trk.sector_size = 2448;
|
||||
trk.attr = DATA_TRACK;
|
||||
trk.mode2 = 1;
|
||||
} else if (!strcmp(type, "CDG/2448")) {
|
||||
trk.sector_size = 2448;
|
||||
trk.attr = DATA_TRACK;
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* CD-ROM image file handling module header , translated to C
|
||||
* from cdrom_dosbox.h.
|
||||
*
|
||||
* Version: @(#)cdrom_image_backend.h 1.0.0 2019/12/19
|
||||
* Version: @(#)cdrom_image_backend.h 1.0.1 2019/12/21
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -83,7 +83,6 @@ 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_mode2(cd_img_t *cdi, uint32_t sector);
|
||||
extern int cdi_get_mode2_form(cd_img_t *cdi, uint32_t sector);
|
||||
extern int cdi_can_read_pvd(track_file_t *file, uint64_t sector_size, int mode2);
|
||||
extern int cdi_load_iso(cd_img_t *cdi, const wchar_t *filename);
|
||||
extern int cdi_load_cue(cd_img_t *cdi, const wchar_t *cuefile);
|
||||
extern int cdi_has_data_track(cd_img_t *cdi);
|
||||
|
Reference in New Issue
Block a user