filename | src/gdrom/edc_ecc.c |
changeset | 678:35eb00945316 |
prev | 669:ab344e42bca9 |
author | nkeynes |
date | Wed Jul 30 22:50:44 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Bug #61: OpenBSD support (Modified) patch from bsdmaniak, thanks! |
view | annotate | diff | log | raw |
1 /*
2 * Note: This file has been extracted from crkit 1.1.6 and modified to work within
3 * lxdream.
4 */
5 /*
6 * This file has been modified for the cdrkit suite.
7 *
8 * The behaviour and appearence of the program code below can differ to a major
9 * extent from the version distributed by the original author(s).
10 *
11 * For details, see Changelog file distributed with the cdrkit package. If you
12 * received this file from another source then ask the distributing person for
13 * a log of modifications.
14 *
15 */
17 /* @(#)edc_ecc.c 1.21 03/04/04 Copyright 1998-2002 Heiko Eissfeldt, Joerg Schilling */
19 /*
20 * Copyright 1998-2002 by Heiko Eissfeldt
21 * Copyright 2002 by Joerg Schilling
22 *
23 * This file contains protected intellectual property.
24 *
25 * reed-solomon encoder / decoder for compact discs.
26 *
27 */
28 /*
29 * This program is free software; you can redistribute it and/or modify
30 * it under the terms of the GNU General Public License version 2
31 * as published by the Free Software Foundation.
32 *
33 * This program is distributed in the hope that it will be useful,
34 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 * GNU General Public License for more details.
37 *
38 * You should have received a copy of the GNU General Public License along with
39 * this program; see the file COPYING. If not, write to the Free Software
40 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 */
43 #include <stdint.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include "gdrom/gddriver.h"
47 #include "ecc.h"
49 #define xaligned(a, s) ((((uintptr_t)(a)) & (s)) == 0 )
51 int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)],
52 int sectortype, unsigned address);
54 int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR],
55 unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
56 int delay1, int delay2, int delay3, int permute);
58 int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
59 unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
60 int delay1, int permute);
62 int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)],
63 unsigned char out[L2_RAW]);
65 int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
66 unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
67 int delay1, int delay2, int delay3, int permute);
69 int do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
70 unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
71 int delay1, int permute);
75 /* ------------- tables generated by gen_encodes --------------*/
77 #include "edc_scramble.h"
79 #define DO4(a) a;a;a;a;
80 #define DO13(a) a;a;a;a;a;a;a;a;a;a;a;a;a;
82 /*
83 * Scrambles 2352 - 12 = 2340 bytes
84 */
85 int scramble_L2(unsigned char *inout);
87 int scramble_L2(unsigned char *inout)
88 {
89 #ifndef EDC_SCRAMBLE_NOSWAP
90 unsigned int *f = (unsigned int *)inout;
91 #endif
93 if (!xaligned(inout + 12, sizeof(uint32_t)-1)) {
95 uint8_t *r = inout + 12;
96 const uint8_t *s = yellowbook_scrambler;
97 register int i;
99 for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char)/4; --i >= 0;) {
100 DO4(*r++ ^= *s++);
101 }
103 } else {
104 uint32_t *r = (uint32_t *) (inout + 12);
105 const uint32_t *s = yellowbook_scrambler_uint32;
106 register int i;
108 for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(uint32_t)/13; --i >= 0;) {
109 DO13(*r++ ^= *s++);
110 }
111 }
113 #ifndef EDC_SCRAMBLE_NOSWAP
115 /* generate F1 frames */
116 for (i = 2352/sizeof(unsigned int); i; i--) {
117 *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8);
118 }
119 #endif
121 return (0);
122 }
124 #include "edc_l2sq.h"
126 static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]);
128 static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q])
129 {
130 unsigned char *dps;
131 unsigned char *dp;
132 unsigned char *Q;
133 register int i;
134 int j;
136 Q = inout + 4 + L2_RAW + 4 + 8 + L2_P;
138 dps = inout;
139 for (j = 0; j < 26; j++) {
140 register unsigned short a;
141 register unsigned short b;
142 a = b = 0;
144 dp = dps;
145 for (i = 0; i < 43; i++) {
147 /* LSB */
148 a ^= L2sq[i][*dp++];
150 /* MSB */
151 b ^= L2sq[i][*dp];
153 dp += 2*44-1;
154 if (dp >= &inout[(4 + L2_RAW + 4 + 8 + L2_P)]) {
155 dp -= (4 + L2_RAW + 4 + 8 + L2_P);
156 }
157 }
158 Q[0] = a >> 8;
159 Q[26*2] = a;
160 Q[1] = b >> 8;
161 Q[26*2+1] = b;
163 Q += 2;
164 dps += 2*43;
165 }
166 return (0);
167 }
169 static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]);
171 static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P])
172 {
173 unsigned char *dp;
174 unsigned char *P;
175 register int i;
176 int j;
178 P = inout + 4 + L2_RAW + 4 + 8;
180 for (j = 0; j < 43; j++) {
181 register unsigned short a;
182 register unsigned short b;
184 a = b = 0;
185 dp = inout;
186 for (i = 19; i < 43; i++) {
188 /* LSB */
189 a ^= L2sq[i][*dp++];
191 /* MSB */
192 b ^= L2sq[i][*dp];
194 dp += 2*43 -1;
195 }
196 P[0] = a >> 8;
197 P[43*2] = a;
198 P[1] = b >> 8;
199 P[43*2+1] = b;
201 P += 2;
202 inout += 2;
203 }
204 return (0);
205 }
207 static unsigned char bin2bcd(unsigned p);
209 static unsigned char bin2bcd(unsigned p)
210 {
211 return ((p/10)<<4)|(p%10);
212 }
214 int cd_build_address(unsigned char inout[], int sectortype, unsigned address)
215 {
216 inout[12] = bin2bcd(address / (60*75));
217 inout[13] = bin2bcd((address / 75) % 60);
218 inout[14] = bin2bcd(address % 75);
219 if (sectortype == MODE_0)
220 inout[15] = 0;
221 else if (sectortype == MODE_1)
222 inout[15] = 1;
223 else if (sectortype == MODE_2)
224 inout[15] = 2;
225 else if (sectortype == MODE_2_FORM_1)
226 inout[15] = 2;
227 else if (sectortype == MODE_2_FORM_2)
228 inout[15] = 2;
229 else
230 return (-1);
231 return (0);
232 }
234 #include "edc_crctable.h"
236 /*
237 * Called with 2064, 2056 or 2332 byte difference - all dividable by 4.
238 */
239 unsigned int build_edc(unsigned char inout[], int from, int upto);
241 unsigned int build_edc(unsigned char inout[], int from, int upto)
242 {
243 unsigned char *p = inout+from;
244 unsigned int result = 0;
246 upto -= from-1;
247 upto /= 4;
248 while (--upto >= 0) {
249 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
250 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
251 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
252 result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
253 }
254 return (result);
255 }
257 /* Layer 2 Product code en/decoder */
259 int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)],
260 int sectortype, unsigned address)
261 {
262 unsigned int result;
264 /* SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" */
265 #define SYNCPATTERN "\000\377\377\377\377\377\377\377\377\377\377"
267 /* supply initial sync pattern */
268 memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN));
270 if (sectortype == MODE_0) {
271 memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q);
272 cd_build_address(inout, sectortype, address);
273 return (0);
274 }
276 switch (sectortype) {
278 case MODE_1:
279 cd_build_address(inout, sectortype, address);
280 result = build_edc(inout, 0, 16+2048-1);
281 inout[2064+0] = result >> 0L;
282 inout[2064+1] = result >> 8L;
283 inout[2064+2] = result >> 16L;
284 inout[2064+3] = result >> 24L;
285 memset(inout+2064+4, 0, 8);
286 encode_L2_P(inout+12);
287 encode_L2_Q(inout+12);
288 break;
289 case MODE_2:
290 cd_build_address(inout, sectortype, address);
291 break;
292 case MODE_2_FORM_1:
293 result = build_edc(inout, 16, 16+8+2048-1);
294 inout[2072+0] = result >> 0L;
295 inout[2072+1] = result >> 8L;
296 inout[2072+2] = result >> 16L;
297 inout[2072+3] = result >> 24L;
299 /* clear header for P/Q parity calculation */
300 inout[12] = 0;
301 inout[12+1] = 0;
302 inout[12+2] = 0;
303 inout[12+3] = 0;
304 encode_L2_P(inout+12);
305 encode_L2_Q(inout+12);
306 cd_build_address(inout, sectortype, address);
307 break;
308 case MODE_2_FORM_2:
309 cd_build_address(inout, sectortype, address);
310 result = build_edc(inout, 16, 16+8+2324-1);
311 inout[2348+0] = result >> 0L;
312 inout[2348+1] = result >> 8L;
313 inout[2348+2] = result >> 16L;
314 inout[2348+3] = result >> 24L;
315 break;
316 default:
317 return (-1);
318 }
320 return (0);
321 }
324 /*--------------------------------------------------------------------------*/
325 #include "edc_encoder.h"
327 static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]);
329 static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q])
330 {
331 unsigned char *Q;
332 int i;
334 memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2);
335 Q = inout + L1_RAW/2;
337 memset(Q, 0, L1_Q);
338 for (i = 0; i < L1_RAW + L1_Q; i++) {
339 unsigned char data;
341 if (i == L1_RAW/2) i += L1_Q;
342 data = inout[i];
343 if (data != 0) {
344 unsigned char base = rs_l12_log[data];
346 Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
347 Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
348 Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
349 Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
350 }
351 }
352 return (0);
353 }
355 static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]);
357 static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P])
358 {
359 unsigned char *P;
360 int i;
362 P = inout + L1_RAW + L1_Q;
364 memset(P, 0, L1_P);
365 for (i = 0; i < L2_RAW + L2_Q + L2_P; i++) {
366 unsigned char data;
368 data = inout[i];
369 if (data != 0) {
370 unsigned char base = rs_l12_log[data];
372 P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
373 P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
374 P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
375 P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
376 }
377 }
378 return (0);
379 }
381 static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]);
383 static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q])
384 {
385 return (0);
386 }
388 static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]);
390 static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P])
391 {
392 return (0);
393 }
395 int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]);
397 int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q])
398 {
399 return (0);
400 }
402 int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]);
404 int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P])
405 {
406 return (0);
407 }
409 static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]);
411 static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q])
412 {
413 unsigned char *Q;
414 int i;
416 memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW);
417 Q = inout + LSUB_QRAW;
419 memset(Q, 0, LSUB_Q);
421 for (i = 0; i < LSUB_QRAW; i++) {
422 unsigned char data;
424 data = inout[i] & 0x3f;
425 if (data != 0) {
426 unsigned char base = rs_sub_rw_log[data];
428 Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
429 Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
430 }
431 }
432 return (0);
433 }
436 static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]);
438 static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P])
439 {
440 unsigned char *P;
441 int i;
443 P = inout + LSUB_RAW + LSUB_Q;
445 memset(P, 0, LSUB_P);
446 for (i = 0; i < LSUB_RAW + LSUB_Q; i++) {
447 unsigned char data;
449 data = inout[i] & 0x3f;
450 if (data != 0) {
451 unsigned char base = rs_sub_rw_log[data];
453 P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
454 P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
455 P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
456 P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
457 }
458 }
459 return (0);
460 }
462 int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]);
464 int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q])
465 {
466 unsigned char Q[LSUB_Q];
467 int i;
469 memset(Q, 0, LSUB_Q);
470 for (i = LSUB_QRAW + LSUB_Q -1; i>=0; i--) {
471 unsigned char data;
473 data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f;
474 if (data != 0) {
475 unsigned char base = rs_sub_rw_log[data];
477 Q[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
478 Q[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
479 }
480 }
481 return (Q[0] != 0 || Q[1] != 0);
482 }
484 int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]);
486 int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P])
487 {
488 unsigned char P[LSUB_P];
489 int i;
491 memset(P, 0, LSUB_P);
492 for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i>=0; i--) {
493 unsigned char data;
495 data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f;
496 if (data != 0) {
497 unsigned char base = rs_sub_rw_log[data];
499 P[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
500 P[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
501 P[2] ^= rs_sub_rw_alog[(base+2*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
502 P[3] ^= rs_sub_rw_alog[(base+3*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
503 }
504 }
505 return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0);
506 }
508 /* Layer 1 CIRC en/decoder */
509 #define MAX_L1_DEL1 2
510 static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW];
511 #define MAX_L1_DEL2 108
512 static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q];
513 #define MAX_L1_DEL3 1
514 static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P];
515 static unsigned l1_del_index;
517 int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR],
518 unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
519 int delay1, int delay2, int delay3, int permute)
520 {
521 int i;
523 for (i = 0; i < FRAMES_PER_SECTOR; i++) {
524 int j;
525 unsigned char t;
527 if (in != out)
528 memcpy(out, in, L1_RAW);
530 if (delay1) {
531 /* shift through delay line 1 */
532 for (j = 0; j < L1_RAW; j++) {
533 if (((j/4) % MAX_L1_DEL1) == 0) {
534 t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
535 l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j];
536 out[j] = t;
537 }
538 }
539 }
541 if (permute) {
542 /* permute */
543 t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18];
544 out[18] = out[6]; out [6] = t;
545 t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19];
546 out[19] = out[7]; out [7] = t;
547 t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14];
548 out[14] = out[12]; out [12] = t;
549 t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15];
550 out[15] = out[13]; out [13] = t;
551 }
553 /* build Q parity */
554 encode_L1_Q(out);
556 if (delay2) {
557 /* shift through delay line 2 */
558 for (j = 0; j < L1_RAW+L1_Q; j++) {
559 if (j != 0) {
560 t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
561 l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j];
562 out[j] = t;
563 }
564 }
565 }
567 /* build P parity */
568 encode_L1_P(out);
570 if (delay3) {
571 /* shift through delay line 3 */
572 for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
573 if (((j) & MAX_L1_DEL3) == 0) {
574 t = l1_delay_line3[0][j];
575 l1_delay_line3[0][j] = out[j];
576 out[j] = t;
577 }
578 }
579 }
581 /* invert Q and P parity */
582 for (j = 0; j < L1_Q; j++)
583 out[j+12] = ~out[j+12];
584 for (j = 0; j < L1_P; j++)
585 out[j+28] = ~out[j+28];
587 l1_del_index++;
588 out += L1_RAW+L1_Q+L1_P;
589 in += L1_RAW;
590 }
591 return (0);
592 }
594 int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
595 unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
596 int delay1, int delay2, int delay3, int permute)
597 {
598 int i;
600 for (i = 0; i < FRAMES_PER_SECTOR; i++) {
601 int j;
602 unsigned char t;
604 if (delay3) {
605 /* shift through delay line 3 */
606 for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
607 if (((j) & MAX_L1_DEL3) != 0) {
608 t = l1_delay_line3[0][j];
609 l1_delay_line3[0][j] = in[j];
610 in[j] = t;
611 }
612 }
613 }
615 /* invert Q and P parity */
616 for (j = 0; j < L1_Q; j++)
617 in[j+12] = ~in[j+12];
618 for (j = 0; j < L1_P; j++)
619 in[j+28] = ~in[j+28];
621 /* build P parity */
622 decode_L1_P(in);
624 if (delay2) {
625 /* shift through delay line 2 */
626 for (j = 0; j < L1_RAW+L1_Q; j++) {
627 if (j != L1_RAW+L1_Q-1) {
628 t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
629 l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j];
630 in[j] = t;
631 }
632 }
633 }
635 /* build Q parity */
636 decode_L1_Q(in);
638 if (permute) {
639 /* permute */
640 t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10];
641 in[10] = in[8]; in [8] = t;
642 t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11];
643 in[11] = in[9]; in [9] = t;
644 t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20];
645 in[20] = in[16]; in [16] = t;
646 t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21];
647 in[21] = in[17]; in [17] = t;
648 }
650 if (delay1) {
651 /* shift through delay line 1 */
652 for (j = 0; j < L1_RAW; j++) {
653 if (((j/4) % MAX_L1_DEL1) != 0) {
654 t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
655 l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j];
656 in[j] = t;
657 }
658 }
659 }
661 if (in != out)
662 memcpy(out, in, (L1_RAW));
664 l1_del_index++;
665 in += L1_RAW+L1_Q+L1_P;
666 out += L1_RAW;
667 }
668 return (0);
669 }
671 int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)],
672 unsigned char out[L2_RAW])
673 {
674 return (0);
675 }
679 #define MAX_SUB_DEL 8
680 static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P];
681 static unsigned sub_del_index;
683 /* R-W Subchannel en/decoder */
685 int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
686 unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
687 int delay1, int permute)
688 {
689 int i;
691 if (in == out) return -1;
693 for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
694 int j;
695 unsigned char t;
697 memcpy(out, in, (LSUB_RAW));
699 /* build Q parity */
700 encode_LSUB_Q(out);
702 /* build P parity */
703 encode_LSUB_P(out);
705 if (permute) {
706 /* permute */
707 t = out[1]; out[1] = out[18]; out[18] = t;
708 t = out[2]; out[2] = out[ 5]; out[ 5] = t;
709 t = out[3]; out[3] = out[23]; out[23] = t;
710 }
712 if (delay1) {
713 /* shift through delay_line */
714 for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
715 if ((j % MAX_SUB_DEL) != 0) {
716 t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
717 sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j];
718 out[j] = t;
719 }
720 }
721 }
722 sub_del_index++;
723 out += LSUB_RAW+LSUB_Q+LSUB_P;
724 in += LSUB_RAW;
725 }
726 return (0);
727 }
729 int do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
730 unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
731 int delay1, int permute)
732 {
733 int i;
735 if (in == out) return -1;
737 for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
738 int j;
739 unsigned char t;
741 if (delay1) {
742 /* shift through delay_line */
743 for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
744 if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) {
745 t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
746 sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j];
747 in[j] = t;
748 }
749 }
750 }
752 if (permute) {
753 /* permute */
754 t = in[1]; in[1] = in[18]; in[18] = t;
755 t = in[2]; in[2] = in[ 5]; in[ 5] = t;
756 t = in[3]; in[3] = in[23]; in[23] = t;
757 }
759 /* build P parity */
760 decode_LSUB_P(in);
762 /* build Q parity */
763 decode_LSUB_Q(in);
765 memcpy(out, in, LSUB_QRAW);
766 memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW);
768 sub_del_index++;
769 in += LSUB_RAW+LSUB_Q+LSUB_P;
770 out += LSUB_RAW;
771 }
772 return (0);
773 }
775 static int sectortype = MODE_0;
777 int get_sector_type(void);
779 int get_sector_type()
780 {
781 return (sectortype);
782 }
784 int set_sector_type(int st);
786 int set_sector_type(int st)
787 {
788 switch(st) {
790 case MODE_0:
791 case MODE_1:
792 case MODE_2:
793 case MODE_2_FORM_1:
794 case MODE_2_FORM_2:
795 sectortype = st;
796 return 0;
797 default:
798 return -1;
799 }
800 }
.