Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/psx/mednadisc/cdrom/lec.cpp
2 views
1
/* cdrdao - write audio CD-Rs in disc-at-once mode
2
*
3
* Copyright (C) 1998-2002 Andreas Mueller <[email protected]>
4
*
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
*/
19
20
#ifdef HAVE_CONFIG_H
21
#include <config.h>
22
#endif
23
24
#include <assert.h>
25
#include <sys/types.h>
26
27
#include "lec.h"
28
29
#define GF8_PRIM_POLY 0x11d /* x^8 + x^4 + x^3 + x^2 + 1 */
30
31
#define EDC_POLY 0x8001801b /* (x^16 + x^15 + x^2 + 1) (x^16 + x^2 + x + 1) */
32
33
#define LEC_HEADER_OFFSET 12
34
#define LEC_DATA_OFFSET 16
35
#define LEC_MODE1_DATA_LEN 2048
36
#define LEC_MODE1_EDC_OFFSET 2064
37
#define LEC_MODE1_INTERMEDIATE_OFFSET 2068
38
#define LEC_MODE1_P_PARITY_OFFSET 2076
39
#define LEC_MODE1_Q_PARITY_OFFSET 2248
40
#define LEC_MODE2_FORM1_DATA_LEN (2048+8)
41
#define LEC_MODE2_FORM1_EDC_OFFSET 2072
42
#define LEC_MODE2_FORM2_DATA_LEN (2324+8)
43
#define LEC_MODE2_FORM2_EDC_OFFSET 2348
44
45
46
typedef u_int8_t gf8_t;
47
48
static u_int8_t GF8_LOG[256];
49
static gf8_t GF8_ILOG[256];
50
51
static const class Gf8_Q_Coeffs_Results_01 {
52
private:
53
u_int16_t table[43][256];
54
public:
55
Gf8_Q_Coeffs_Results_01();
56
~Gf8_Q_Coeffs_Results_01() {}
57
const u_int16_t *operator[] (int i) const { return &table[i][0]; }
58
operator const u_int16_t *() const { return &table[0][0]; }
59
} CF8_Q_COEFFS_RESULTS_01;
60
61
static const class CrcTable {
62
private:
63
u_int32_t table[256];
64
public:
65
CrcTable();
66
~CrcTable() {}
67
u_int32_t operator[](int i) const { return table[i]; }
68
operator const u_int32_t *() const { return table; }
69
} CRCTABLE;
70
71
static const class ScrambleTable {
72
private:
73
u_int8_t table[2340];
74
public:
75
ScrambleTable();
76
~ScrambleTable() {}
77
u_int8_t operator[](int i) const { return table[i]; }
78
operator const u_int8_t *() const { return table; }
79
} SCRAMBLE_TABLE;
80
81
/* Creates the logarithm and inverse logarithm table that is required
82
* for performing multiplication in the GF(8) domain.
83
*/
84
static void gf8_create_log_tables()
85
{
86
u_int8_t log;
87
u_int16_t b;
88
89
for (b = 0; b <= 255; b++) {
90
GF8_LOG[b] = 0;
91
GF8_ILOG[b] = 0;
92
}
93
94
b = 1;
95
96
for (log = 0; log < 255; log++) {
97
GF8_LOG[(u_int8_t)b] = log;
98
GF8_ILOG[log] = (u_int8_t)b;
99
100
b <<= 1;
101
102
if ((b & 0x100) != 0)
103
b ^= GF8_PRIM_POLY;
104
}
105
}
106
107
/* Addition in the GF(8) domain: just the XOR of the values.
108
*/
109
#define gf8_add(a, b) (a) ^ (b)
110
111
112
/* Multiplication in the GF(8) domain: add the logarithms (modulo 255)
113
* and return the inverse logarithm. Not used!
114
*/
115
#if 0
116
static gf8_t gf8_mult(gf8_t a, gf8_t b)
117
{
118
int16_t sum;
119
120
if (a == 0 || b == 0)
121
return 0;
122
123
sum = GF8_LOG[a] + GF8_LOG[b];
124
125
if (sum >= 255)
126
sum -= 255;
127
128
return GF8_ILOG[sum];
129
}
130
#endif
131
132
/* Division in the GF(8) domain: Like multiplication but logarithms a
133
* subtracted.
134
*/
135
static gf8_t gf8_div(gf8_t a, gf8_t b)
136
{
137
int16_t sum;
138
139
assert(b != 0);
140
141
if (a == 0)
142
return 0;
143
144
sum = GF8_LOG[a] - GF8_LOG[b];
145
146
if (sum < 0)
147
sum += 255;
148
149
return GF8_ILOG[sum];
150
}
151
152
Gf8_Q_Coeffs_Results_01::Gf8_Q_Coeffs_Results_01()
153
{
154
int i, j;
155
u_int16_t c;
156
gf8_t GF8_COEFFS_HELP[2][45];
157
u_int8_t GF8_Q_COEFFS[2][45];
158
159
160
gf8_create_log_tables();
161
162
/* build matrix H:
163
* 1 1 ... 1 1
164
* a^44 a^43 ... a^1 a^0
165
*
166
*
167
*/
168
169
for (j = 0; j < 45; j++) {
170
GF8_COEFFS_HELP[0][j] = 1; /* e0 */
171
GF8_COEFFS_HELP[1][j] = GF8_ILOG[44-j]; /* e1 */
172
}
173
174
175
/* resolve equation system for parity byte 0 and 1 */
176
177
/* e1' = e1 + e0 */
178
for (j = 0; j < 45; j++) {
179
GF8_Q_COEFFS[1][j] = gf8_add(GF8_COEFFS_HELP[1][j],
180
GF8_COEFFS_HELP[0][j]);
181
}
182
183
/* e1'' = e1' / (a^1 + 1) */
184
for (j = 0; j < 45; j++) {
185
GF8_Q_COEFFS[1][j] = gf8_div(GF8_Q_COEFFS[1][j], GF8_Q_COEFFS[1][43]);
186
}
187
188
/* e0' = e0 + e1 / a^1 */
189
for (j = 0; j < 45; j++) {
190
GF8_Q_COEFFS[0][j] = gf8_add(GF8_COEFFS_HELP[0][j],
191
gf8_div(GF8_COEFFS_HELP[1][j],
192
GF8_ILOG[1]));
193
}
194
195
/* e0'' = e0' / (1 + 1 / a^1) */
196
for (j = 0; j < 45; j++) {
197
GF8_Q_COEFFS[0][j] = gf8_div(GF8_Q_COEFFS[0][j], GF8_Q_COEFFS[0][44]);
198
}
199
200
/*
201
* Compute the products of 0..255 with all of the Q coefficients in
202
* advance. When building the scalar product between the data vectors
203
* and the P/Q vectors the individual products can be looked up in
204
* this table
205
*
206
* The P parity coefficients are just a subset of the Q coefficients so
207
* that we do not need to create a separate table for them.
208
*/
209
210
for (j = 0; j < 43; j++) {
211
212
table[j][0] = 0;
213
214
for (i = 1; i < 256; i++) {
215
c = GF8_LOG[i] + GF8_LOG[GF8_Q_COEFFS[0][j]];
216
if (c >= 255) c -= 255;
217
table[j][i] = GF8_ILOG[c];
218
219
c = GF8_LOG[i] + GF8_LOG[GF8_Q_COEFFS[1][j]];
220
if (c >= 255) c -= 255;
221
table[j][i] |= GF8_ILOG[c]<<8;
222
}
223
}
224
}
225
226
/* Reverses the bits in 'd'. 'bits' defines the bit width of 'd'.
227
*/
228
static u_int32_t mirror_bits(u_int32_t d, int bits)
229
{
230
int i;
231
u_int32_t r = 0;
232
233
for (i = 0; i < bits; i++) {
234
r <<= 1;
235
236
if ((d & 0x1) != 0)
237
r |= 0x1;
238
239
d >>= 1;
240
}
241
242
return r;
243
}
244
245
/* Build the CRC lookup table for EDC_POLY poly. The CRC is 32 bit wide
246
* and reversed (i.e. the bit stream is divided by the EDC_POLY with the
247
* LSB first order).
248
*/
249
CrcTable::CrcTable ()
250
{
251
u_int32_t i, j;
252
u_int32_t r;
253
254
for (i = 0; i < 256; i++) {
255
r = mirror_bits(i, 8);
256
257
r <<= 24;
258
259
for (j = 0; j < 8; j++) {
260
if ((r & 0x80000000) != 0) {
261
r <<= 1;
262
r ^= EDC_POLY;
263
}
264
else {
265
r <<= 1;
266
}
267
}
268
269
r = mirror_bits(r, 32);
270
271
table[i] = r;
272
}
273
}
274
275
/* Calculates the CRC of given data with given lengths based on the
276
* table lookup algorithm.
277
*/
278
static u_int32_t calc_edc(u_int8_t *data, int len)
279
{
280
u_int32_t crc = 0;
281
282
while (len--) {
283
crc = CRCTABLE[(int)(crc ^ *data++) & 0xff] ^ (crc >> 8);
284
}
285
286
return crc;
287
}
288
289
/* Build the scramble table as defined in the yellow book. The bytes
290
12 to 2351 of a sector will be XORed with the data of this table.
291
*/
292
ScrambleTable::ScrambleTable()
293
{
294
u_int16_t i, j;
295
u_int16_t reg = 1;
296
u_int8_t d;
297
298
for (i = 0; i < 2340; i++) {
299
d = 0;
300
301
for (j = 0; j < 8; j++) {
302
d >>= 1;
303
304
if ((reg & 0x1) != 0)
305
d |= 0x80;
306
307
if ((reg & 0x1) != ((reg >> 1) & 0x1)) {
308
reg >>= 1;
309
reg |= 0x4000; /* 15-bit register */
310
}
311
else {
312
reg >>= 1;
313
}
314
}
315
316
table[i] = d;
317
}
318
}
319
320
/* Calc EDC for a MODE 1 sector
321
*/
322
static void calc_mode1_edc(u_int8_t *sector)
323
{
324
u_int32_t crc = calc_edc(sector, LEC_MODE1_DATA_LEN + 16);
325
326
sector[LEC_MODE1_EDC_OFFSET] = crc & 0xffL;
327
sector[LEC_MODE1_EDC_OFFSET + 1] = (crc >> 8) & 0xffL;
328
sector[LEC_MODE1_EDC_OFFSET + 2] = (crc >> 16) & 0xffL;
329
sector[LEC_MODE1_EDC_OFFSET + 3] = (crc >> 24) & 0xffL;
330
}
331
332
/* Calc EDC for a XA form 1 sector
333
*/
334
static void calc_mode2_form1_edc(u_int8_t *sector)
335
{
336
u_int32_t crc = calc_edc(sector + LEC_DATA_OFFSET,
337
LEC_MODE2_FORM1_DATA_LEN);
338
339
sector[LEC_MODE2_FORM1_EDC_OFFSET] = crc & 0xffL;
340
sector[LEC_MODE2_FORM1_EDC_OFFSET + 1] = (crc >> 8) & 0xffL;
341
sector[LEC_MODE2_FORM1_EDC_OFFSET + 2] = (crc >> 16) & 0xffL;
342
sector[LEC_MODE2_FORM1_EDC_OFFSET + 3] = (crc >> 24) & 0xffL;
343
}
344
345
/* Calc EDC for a XA form 2 sector
346
*/
347
static void calc_mode2_form2_edc(u_int8_t *sector)
348
{
349
u_int32_t crc = calc_edc(sector + LEC_DATA_OFFSET,
350
LEC_MODE2_FORM2_DATA_LEN);
351
352
sector[LEC_MODE2_FORM2_EDC_OFFSET] = crc & 0xffL;
353
sector[LEC_MODE2_FORM2_EDC_OFFSET + 1] = (crc >> 8) & 0xffL;
354
sector[LEC_MODE2_FORM2_EDC_OFFSET + 2] = (crc >> 16) & 0xffL;
355
sector[LEC_MODE2_FORM2_EDC_OFFSET + 3] = (crc >> 24) & 0xffL;
356
}
357
358
/* Writes the sync pattern to the given sector.
359
*/
360
static void set_sync_pattern(u_int8_t *sector)
361
{
362
sector[0] = 0;
363
364
sector[1] = sector[2] = sector[3] = sector[4] = sector[5] =
365
sector[6] = sector[7] = sector[8] = sector[9] = sector[10] = 0xff;
366
367
sector[11] = 0;
368
}
369
370
371
static u_int8_t bin2bcd(u_int8_t b)
372
{
373
return (((b/10) << 4) & 0xf0) | ((b%10) & 0x0f);
374
}
375
376
/* Builds the sector header.
377
*/
378
static void set_sector_header(u_int8_t mode, u_int32_t adr, u_int8_t *sector)
379
{
380
sector[LEC_HEADER_OFFSET] = bin2bcd(adr / (60*75));
381
sector[LEC_HEADER_OFFSET + 1] = bin2bcd((adr / 75) % 60);
382
sector[LEC_HEADER_OFFSET + 2] = bin2bcd(adr % 75);
383
sector[LEC_HEADER_OFFSET + 3] = mode;
384
}
385
386
/* Calculate the P parities for the sector.
387
* The 43 P vectors of length 24 are combined with the GF8_P_COEFFS.
388
*/
389
static void calc_P_parity(u_int8_t *sector)
390
{
391
int i, j;
392
u_int16_t p01_msb, p01_lsb;
393
u_int8_t *p_lsb_start;
394
u_int8_t *p_lsb;
395
u_int8_t *p0, *p1;
396
u_int8_t d0,d1;
397
398
p_lsb_start = sector + LEC_HEADER_OFFSET;
399
400
p1 = sector + LEC_MODE1_P_PARITY_OFFSET;
401
p0 = sector + LEC_MODE1_P_PARITY_OFFSET + 2 * 43;
402
403
for (i = 0; i <= 42; i++) {
404
p_lsb = p_lsb_start;
405
406
p01_lsb = p01_msb = 0;
407
408
for (j = 19; j <= 42; j++) {
409
d0 = *p_lsb;
410
d1 = *(p_lsb+1);
411
412
p01_lsb ^= CF8_Q_COEFFS_RESULTS_01[j][d0];
413
p01_msb ^= CF8_Q_COEFFS_RESULTS_01[j][d1];
414
415
p_lsb += 2 * 43;
416
}
417
418
*p0 = p01_lsb;
419
*(p0 + 1) = p01_msb;
420
421
*p1 = p01_lsb>>8;
422
*(p1 + 1) = p01_msb>>8;
423
424
p0 += 2;
425
p1 += 2;
426
427
p_lsb_start += 2;
428
}
429
}
430
431
/* Calculate the Q parities for the sector.
432
* The 26 Q vectors of length 43 are combined with the GF8_Q_COEFFS.
433
*/
434
static void calc_Q_parity(u_int8_t *sector)
435
{
436
int i, j;
437
u_int16_t q01_lsb, q01_msb;
438
u_int8_t *q_lsb_start;
439
u_int8_t *q_lsb;
440
u_int8_t *q0, *q1, *q_start;
441
u_int8_t d0,d1;
442
443
q_lsb_start = sector + LEC_HEADER_OFFSET;
444
445
q_start = sector + LEC_MODE1_Q_PARITY_OFFSET;
446
q1 = sector + LEC_MODE1_Q_PARITY_OFFSET;
447
q0 = sector + LEC_MODE1_Q_PARITY_OFFSET + 2 * 26;
448
449
for (i = 0; i <= 25; i++) {
450
q_lsb = q_lsb_start;
451
452
q01_lsb = q01_msb = 0;
453
454
for (j = 0; j <= 42; j++) {
455
d0 = *q_lsb;
456
d1 = *(q_lsb+1);
457
458
q01_lsb ^= CF8_Q_COEFFS_RESULTS_01[j][d0];
459
q01_msb ^= CF8_Q_COEFFS_RESULTS_01[j][d1];
460
461
q_lsb += 2 * 44;
462
463
if (q_lsb >= q_start) {
464
q_lsb -= 2 * 1118;
465
}
466
}
467
468
*q0 = q01_lsb;
469
*(q0 + 1) = q01_msb;
470
471
*q1 = q01_lsb>>8;
472
*(q1 + 1) = q01_msb>>8;
473
474
q0 += 2;
475
q1 += 2;
476
477
q_lsb_start += 2 * 43;
478
}
479
}
480
481
/* Encodes a MODE 0 sector.
482
* 'adr' is the current physical sector address
483
* 'sector' must be 2352 byte wide
484
*/
485
void lec_encode_mode0_sector(u_int32_t adr, u_int8_t *sector)
486
{
487
u_int16_t i;
488
489
set_sync_pattern(sector);
490
set_sector_header(0, adr, sector);
491
492
sector += 16;
493
494
for (i = 0; i < 2336; i++)
495
*sector++ = 0;
496
}
497
498
/* Encodes a MODE 1 sector.
499
* 'adr' is the current physical sector address
500
* 'sector' must be 2352 byte wide containing 2048 bytes user data at
501
* offset 16
502
*/
503
void lec_encode_mode1_sector(u_int32_t adr, u_int8_t *sector)
504
{
505
set_sync_pattern(sector);
506
set_sector_header(1, adr, sector);
507
508
calc_mode1_edc(sector);
509
510
/* clear the intermediate field */
511
sector[LEC_MODE1_INTERMEDIATE_OFFSET] =
512
sector[LEC_MODE1_INTERMEDIATE_OFFSET + 1] =
513
sector[LEC_MODE1_INTERMEDIATE_OFFSET + 2] =
514
sector[LEC_MODE1_INTERMEDIATE_OFFSET + 3] =
515
sector[LEC_MODE1_INTERMEDIATE_OFFSET + 4] =
516
sector[LEC_MODE1_INTERMEDIATE_OFFSET + 5] =
517
sector[LEC_MODE1_INTERMEDIATE_OFFSET + 6] =
518
sector[LEC_MODE1_INTERMEDIATE_OFFSET + 7] = 0;
519
520
calc_P_parity(sector);
521
calc_Q_parity(sector);
522
}
523
524
/* Encodes a MODE 2 sector.
525
* 'adr' is the current physical sector address
526
* 'sector' must be 2352 byte wide containing 2336 bytes user data at
527
* offset 16
528
*/
529
void lec_encode_mode2_sector(u_int32_t adr, u_int8_t *sector)
530
{
531
set_sync_pattern(sector);
532
set_sector_header(2, adr, sector);
533
}
534
535
/* Encodes a XA form 1 sector.
536
* 'adr' is the current physical sector address
537
* 'sector' must be 2352 byte wide containing 2048+8 bytes user data at
538
* offset 16
539
*/
540
void lec_encode_mode2_form1_sector(u_int32_t adr, u_int8_t *sector)
541
{
542
set_sync_pattern(sector);
543
544
calc_mode2_form1_edc(sector);
545
546
/* P/Q partiy must not contain the sector header so clear it */
547
sector[LEC_HEADER_OFFSET] =
548
sector[LEC_HEADER_OFFSET + 1] =
549
sector[LEC_HEADER_OFFSET + 2] =
550
sector[LEC_HEADER_OFFSET + 3] = 0;
551
552
calc_P_parity(sector);
553
calc_Q_parity(sector);
554
555
/* finally add the sector header */
556
set_sector_header(2, adr, sector);
557
}
558
559
/* Encodes a XA form 2 sector.
560
* 'adr' is the current physical sector address
561
* 'sector' must be 2352 byte wide containing 2324+8 bytes user data at
562
* offset 16
563
*/
564
void lec_encode_mode2_form2_sector(u_int32_t adr, u_int8_t *sector)
565
{
566
set_sync_pattern(sector);
567
568
calc_mode2_form2_edc(sector);
569
570
set_sector_header(2, adr, sector);
571
}
572
573
/* Scrambles and byte swaps an encoded sector.
574
* 'sector' must be 2352 byte wide.
575
*/
576
void lec_scramble(u_int8_t *sector)
577
{
578
u_int16_t i;
579
const u_int8_t *stable = SCRAMBLE_TABLE;
580
u_int8_t *p = sector;
581
u_int8_t tmp;
582
583
584
for (i = 0; i < 6; i++) {
585
/* just swap bytes of sector sync */
586
tmp = *p;
587
*p = *(p + 1);
588
p++;
589
*p++ = tmp;
590
}
591
for (;i < (2352 / 2); i++) {
592
/* scramble and swap bytes */
593
tmp = *p ^ *stable++;
594
*p = *(p + 1) ^ *stable++;
595
p++;
596
*p++ = tmp;
597
}
598
}
599
600
#if 0
601
#include <fcntl.h>
602
#include <unistd.h>
603
#include <string.h>
604
#include <stdio.h>
605
606
int main(int argc, char **argv)
607
{
608
char *infile;
609
char *outfile;
610
int fd_in, fd_out;
611
u_int8_t buffer1[2352];
612
u_int8_t buffer2[2352];
613
u_int32_t lba;
614
int i;
615
616
#if 0
617
for (i = 0; i < 2048; i++)
618
buffer1[i + 16] = 234;
619
620
lba = 150;
621
622
for (i = 0; i < 100000; i++) {
623
lec_encode_mode1_sector(lba, buffer1);
624
lec_scramble(buffer2);
625
lba++;
626
}
627
628
#else
629
630
if (argc != 3)
631
return 1;
632
633
infile = argv[1];
634
outfile = argv[2];
635
636
637
if ((fd_in = open(infile, O_RDONLY)) < 0) {
638
perror("Cannot open input file");
639
return 1;
640
}
641
642
if ((fd_out = open(outfile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) {
643
perror("Cannot open output file");
644
return 1;
645
}
646
647
lba = 150;
648
649
do {
650
if (read(fd_in, buffer1, 2352) != 2352)
651
break;
652
653
switch (*(buffer1 + 12 + 3)) {
654
case 1:
655
memcpy(buffer2 + 16, buffer1 + 16, 2048);
656
657
lec_encode_mode1_sector(lba, buffer2);
658
break;
659
660
case 2:
661
if ((*(buffer1 + 12 + 4 + 2) & 0x20) != 0) {
662
/* form 2 sector */
663
memcpy(buffer2 + 16, buffer1 + 16, 2324 + 8);
664
lec_encode_mode2_form2_sector(lba, buffer2);
665
}
666
else {
667
/* form 1 sector */
668
memcpy(buffer2 + 16, buffer1 + 16, 2048 + 8);
669
lec_encode_mode2_form1_sector(lba, buffer2);
670
}
671
break;
672
}
673
674
if (memcmp(buffer1, buffer2, 2352) != 0) {
675
printf("Verify error at lba %ld\n", lba);
676
}
677
678
lec_scramble(buffer2);
679
write(fd_out, buffer2, 2352);
680
681
lba++;
682
} while (1);
683
684
close(fd_in);
685
close(fd_out);
686
687
#endif
688
689
return 0;
690
}
691
#endif
692
693