GitHub

@@ -292,17 +292,101 @@ msf_to_bcd(int *m, int *s, int *f)

292292

*f = bin2bcd(*f);

293293

}

294294295+

void

296+

cdrom_compute_ecc_block(cdrom_t *dev, uint8_t *parity, const uint8_t *data,

297+

uint32_t major_count, uint32_t minor_count,

298+

uint32_t major_mult, uint32_t minor_inc)

299+

{

300+

uint32_t size = major_count * minor_count;

301+302+

for (uint32_t major = 0; major < major_count; ++major) {

303+

uint32_t index = (major >> 1) * major_mult + (major & 1);

304+305+

uint8_t ecc_a = 0;

306+

uint8_t ecc_b = 0;

307+308+

for (uint32_t minor = 0; minor < minor_count; ++minor) {

309+

uint8_t temp = data[index];

310+311+

index += minor_inc;

312+313+

if (index >= size)

314+

index -= size;

315+316+

ecc_a ^= temp;

317+

ecc_b ^= temp;

318+

ecc_a = dev->_F_LUT[ecc_a];

319+

}

320+321+

parity[major] = dev->_B_LUT[dev->_F_LUT[ecc_a] ^ ecc_b];

322+

parity[major + major_count] = parity[major] ^ ecc_b;

323+

}

324+

}

325+326+

extern void

327+

cdrom_generate_ecc_data(cdrom_t *dev, const uint8_t *data)

328+

{

329+

/* Compute ECC P code. */

330+

cdrom_compute_ecc_block(dev, dev->p_parity, data, 86, 24, 2, 86);

331+332+

/* Compute ECC Q code. */

333+

cdrom_compute_ecc_block(dev, dev->q_parity, data, 52, 43, 86, 88);

334+

}

335+295336

static int

296-

read_data(cdrom_t *dev, const uint32_t lba)

337+

cdrom_is_sector_good(cdrom_t *dev, const uint8_t *b, const uint8_t mode2, const uint8_t form)

297338

{

298-

int ret = 1;

339+

int ret = 1;

340+341+

if (mode2 && (form == 1)) {

342+

const uint32_t crc = cdrom_crc32(0xffffffff, b, 2072) ^ 0xffffffff;

343+344+

ret = ret && (crc == (*(uint32_t *) &(b[2072])));

345+

} else if (!mode2) {

346+

const uint32_t crc = cdrom_crc32(0xffffffff, b, 2064) ^ 0xffffffff;

347+348+

ret = ret && (crc == (*(uint32_t *) &(b[2064])));

349+

}

350+351+

cdrom_generate_ecc_data(dev, &(b[12]));

352+353+

ret = ret && !memcmp(dev->p_parity, &(b[2076]), 172);

354+

ret = ret && !memcmp(dev->q_parity, &(b[2248]), 104);

355+356+

return ret;

357+

}

358+359+

static int

360+

read_data(cdrom_t *dev, const uint32_t lba, int check)

361+

{

362+

int ret = 1;

363+

int form = 0;

299364300365

if (dev->cached_sector != lba) {

301366

dev->cached_sector = lba;

302367303368

ret = dev->ops->read_sector(dev->local,

304369

dev->raw_buffer[dev->cur_buf ^ 1], lba);

305370371+

if ((ret > 0) && check) {

372+

if (dev->mode2) {

373+

if (dev->raw_buffer[dev->cur_buf ^ 1][0x000f] == 0x01)

374+

/*

375+

Use Mode 1, since evidently specification-violating

376+

discs exist.

377+

*/

378+

dev->mode2 = 0;

379+

else if (dev->raw_buffer[dev->cur_buf ^ 1][0x0012] ==

380+

dev->raw_buffer[dev->cur_buf ^ 1][0x0016])

381+

form = ((dev->raw_buffer[dev->cur_buf ^ 1][0x0012] &

382+

0x20) >> 5) + 1;

383+

} else if (dev->raw_buffer[dev->cur_buf ^ 1][0x000f] == 0x02)

384+

dev->mode2 = 1;

385+386+

if (!cdrom_is_sector_good(dev, dev->raw_buffer[dev->cur_buf ^ 1], dev->mode2, form))

387+

ret = -1;

388+

}

389+306390

if (ret <= 0) {

307391

memset(dev->raw_buffer[dev->cur_buf ^ 1], 0x00, 2448);

308392

dev->cached_sector = -1;

@@ -322,7 +406,7 @@ cdrom_get_subchannel(cdrom_t *dev, const uint32_t lba,

322406

if (lba != dev->cached_sector)

323407

dev->cached_sector = -1;

324408325-

(void) read_data(dev, lba);

409+

(void) read_data(dev, lba, 0);

326410327411

for (int i = 0; i < 12; i++)

328412

for (int j = 0; j < 8; j++)

@@ -679,7 +763,7 @@ track_type_is_valid(UNUSED(const cdrom_t *dev), const int type, const int flags,

679763

static int

680764

read_audio(cdrom_t *dev, const uint32_t lba, uint8_t *b)

681765

{

682-

const int ret = read_data(dev, lba);

766+

const int ret = read_data(dev, lba, 0);

683767684768

memcpy(b, dev->raw_buffer[dev->cur_buf], 2352);

685769

@@ -2379,6 +2463,8 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int

23792463

if (dm != CD_TRACK_NORMAL)

23802464

mode2 = 1;

238124652466+

dev->mode2 = mode2;

2467+23822468

memset(dev->extra_buffer, 0, 296);

2383246923842470

if ((cdrom_sector_flags & 0xf8) == 0x08) {

@@ -2405,7 +2491,7 @@ cdrom_readsector_raw(cdrom_t *dev, uint8_t *buffer, const int sector, const int

24052491

else

24062492

ret = read_audio(dev, lba, temp_b);

24072493

} else {

2408-

ret = read_data(dev, lba);

2494+

ret = read_data(dev, lba, 1);

2409249524102496

/* Return with error if we had one. */

24112497

if (ret > 0) {

@@ -2800,7 +2886,7 @@ cdrom_read_track_information(cdrom_t *dev, const uint8_t *cdb, uint8_t *buffer)

28002886

}

2801288728022888

if (track->adr_ctl & 0x04) {

2803-

ret = read_data(dev, start);

2889+

ret = read_data(dev, start, 0);

28042890

mode = dev->raw_buffer[dev->cur_buf][3];

28052891

}

28062892

} else if (track->point != 0xa2)

@@ -2829,9 +2915,9 @@ uint8_t

28292915

cdrom_get_current_mode(cdrom_t *dev)

28302916

{

28312917

if (dev->cached_sector == -1)

2832-

(void) read_data(dev, dev->seek_pos);

2918+

(void) read_data(dev, dev->seek_pos, 0);

28332919

else

2834-

(void) read_data(dev, dev->cached_sector);

2920+

(void) read_data(dev, dev->cached_sector, 0);

2835292128362922

return dev->raw_buffer[dev->cur_buf][3];

28372923

}

@@ -3011,6 +3097,11 @@ cdrom_hard_reset(void)

3011309730123098

cdrom_load(dev, dev->image_path, 0);

30133099

}

3100+3101+

for (uint32_t j = 0; j < _LUT_SIZE; ++j) {

3102+

dev->_F_LUT[j] = (j << 1) ^ (j & 0x80 ? 0x11d : 0);

3103+

dev->_B_LUT[j ^ dev->_F_LUT[j]] = j;

3104+

}

30143105

}

30153106

}

30163107

Read the original on github.com ↗