1 /* @(#)edc_ecc.c	1.31 13/04/28 Copyright 1998-2013 Heiko Eissfeldt, Joerg Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)edc_ecc.c	1.31 13/04/28 Copyright 1998-2013 Heiko Eissfeldt, Joerg Schilling";
6 #endif
7 
8 /*
9  * Copyright 1998-2002,2008 by Heiko Eissfeldt
10  * Copyright 2002-2013 by Joerg Schilling
11  *
12  * This file contains protected intellectual property.
13  *
14  * reed-solomon encoder / decoder for compact discs.
15  *
16  */
17 /*
18  * The contents of this file are subject to the terms of the
19  * Common Development and Distribution License, Version 1.0 only
20  * (the "License").  You may not use this file except in compliance
21  * with the License.
22  *
23  * See the file CDDL.Schily.txt in this distribution for details.
24  * A copy of the CDDL is also available via the Internet at
25  * http://www.opensource.org/licenses/cddl1.txt
26  *
27  * When distributing Covered Code, include this CDDL HEADER in each
28  * file and include the License file CDDL.Schily.txt from this distribution.
29  */
30 
31 #include <schily/stdio.h>
32 #include <schily/align.h>
33 #include <schily/utypes.h>
34 #include <schily/stdlib.h>
35 #include <schily/string.h>
36 #include "ecc.h"
37 
38 #ifndef	HAVE_MEMMOVE
39 #include <schily/libport.h>	/* Define missing prototypes */
40 /*#define	memmove(dst, src, size)		movebytes((src), (dst), (size))*/
41 #define	memmove(d, s, n)	bcopy((s), (d), (n))
42 #endif
43 
44 /*
45  * The functions do_decode_L1(), do_decode_L2(), decode_L1_P(), decode_L1_Q()
46  * are currently static and limited to debug mode (#ifdef MAIN).
47  * After they are ready, they will be made public without #ifdef MAIN.
48  */
49 #ifdef	MAIN
50 /* these prototypes will become public when the function are implemented */
51 static int do_decode_L2	__PR((unsigned char in[(L2_RAW+L2_Q+L2_P)],
52 		unsigned char out[L2_RAW]));
53 
54 static int do_decode_L1	__PR((unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
55 		unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
56 		int delay1, int delay2, int delay3, int scramble));
57 #endif
58 
59 
60 /* ------------- tables generated by gen_encodes --------------*/
61 
62 #include "scramble_table"
63 
64 #define	DO4(a)	a; a; a; a;
65 #define	DO13(a)	a; a; a; a; a; a; a; a; a; a; a; a; a;
66 
67 /*
68  * Scrambles 2352 - 12 = 2340 bytes
69  */
70 int scramble_L2 __PR((unsigned char *inout));
71 
72 int
scramble_L2(inout)73 scramble_L2(inout)
74 	unsigned char *inout;
75 {
76 #ifndef	EDC_SCRAMBLE_NOSWAP
77 	unsigned int *f = (unsigned int *)inout;
78 #endif
79 
80 	if (!xaligned(inout + 12, sizeof (UInt32_t)-1)) {
81 
82 		Uchar		*r = inout + 12;
83 		const Uchar	*s = yellowbook_scrambler;
84 		register int	i;
85 
86 		for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof (unsigned char)/4; --i >= 0; ) {
87 			DO4(*r++ ^= *s++);
88 		}
89 
90 	} else {
91 		UInt32_t	*r = (UInt32_t *) (inout + 12);
92 		const UInt32_t  *s = yellowbook_scrambler_uint32;
93 		register int	i;
94 
95 		for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof (UInt32_t)/13; --i >= 0; ) {
96 			DO13(*r++ ^= *s++);
97 		}
98 	}
99 
100 #ifndef	EDC_SCRAMBLE_NOSWAP
101 
102 	/* generate F1 frames */
103 	for (i = 2352/sizeof (unsigned int); i; i--) {
104 		*f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8);
105 	}
106 #endif
107 
108 	return (0);
109 }
110 
111 #include "l2sq_table"
112 
113 int encode_L2_Q	__PR((unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]));
114 
115 int
encode_L2_Q(inout)116 encode_L2_Q(inout)
117 	unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q];
118 {
119 	unsigned char *dps;
120 	unsigned char *dp;
121 	unsigned char *Q;
122 	register int i;
123 	int j;
124 
125 	Q = inout + 4 + L2_RAW + 4 + 8 + L2_P;
126 
127 	dps = inout;
128 	for (j = 0; j < 26; j++) {
129 		register unsigned short a;
130 		register unsigned short b;
131 		a = b = 0;
132 
133 		dp = dps;
134 		for (i = 0; i < 43; i++) {
135 
136 			/* LSB */
137 			a ^= L2sq[i][*dp++];
138 
139 			/* MSB */
140 			b ^= L2sq[i][*dp];
141 
142 			dp += 2*44-1;
143 			if (dp >= &inout[(4 + L2_RAW + 4 + 8 + L2_P)]) {
144 				dp -= (4 + L2_RAW + 4 + 8 + L2_P);
145 			}
146 		}
147 		Q[0]	  = a >> 8;
148 		Q[26*2]	  = a;
149 		Q[1]	  = b >> 8;
150 		Q[26*2+1] = b;
151 
152 		Q += 2;
153 		dps += 2*43;
154 	}
155 	return (0);
156 }
157 
158 int encode_L2_P	__PR((unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]));
159 
160 int
encode_L2_P(inout)161 encode_L2_P(inout)
162 	unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P];
163 {
164 	unsigned char *dp;
165 	unsigned char *P;
166 	register int i;
167 	int j;
168 
169 	P = inout + 4 + L2_RAW + 4 + 8;
170 
171 	for (j = 0; j < 43; j++) {
172 		register unsigned short a;
173 		register unsigned short b;
174 
175 		a = b = 0;
176 		dp = inout;
177 		for (i = 19; i < 43; i++) {
178 
179 			/* LSB */
180 			a ^= L2sq[i][*dp++];
181 
182 			/* MSB */
183 			b ^= L2sq[i][*dp];
184 
185 			dp += 2*43 -1;
186 		}
187 		P[0]	  = a >> 8;
188 		P[43*2]	  = a;
189 		P[1]	  = b >> 8;
190 		P[43*2+1] = b;
191 
192 		P += 2;
193 		inout += 2;
194 	}
195 	return (0);
196 }
197 
198 static unsigned char bin2bcd	__PR((unsigned p));
199 
200 static unsigned char
bin2bcd(p)201 bin2bcd(p)
202 	unsigned p;
203 {
204 	return ((p/10)<<4)|(p%10);
205 }
206 
207 static int build_address	__PR((unsigned char inout[], int sectortype, unsigned address));
208 
209 static int
build_address(inout,sectortype,address)210 build_address(inout, sectortype, address)
211 	unsigned char inout[];
212 	int sectortype;
213 	unsigned address;
214 {
215 	inout[12] = bin2bcd(address / (60*75));
216 	inout[13] = bin2bcd((address / 75) % 60);
217 	inout[14] = bin2bcd(address % 75);
218 	if (sectortype == MODE_0)
219 		inout[15] = 0;
220 	else if (sectortype == MODE_1)
221 		inout[15] = 1;
222 	else if (sectortype == MODE_2)
223 		inout[15] = 2;
224 	else if (sectortype == MODE_2_FORM_1)
225 		inout[15] = 2;
226 	else if (sectortype == MODE_2_FORM_2)
227 		inout[15] = 2;
228 	else
229 		return (-1);
230 	return (0);
231 }
232 
233 #include "crctable.out"
234 
235 /*
236  * Called with 2064, 2056 or 2332 byte difference - all dividable by 4.
237  */
238 unsigned int build_edc __PR((unsigned char inout[], int from, int upto));
239 
240 unsigned int
build_edc(inout,from,upto)241 build_edc(inout, from, upto)
242 	unsigned char inout[];
243 	int from;
244 	int upto;
245 {
246 	unsigned char *p = inout+from;
247 	unsigned int result = 0;
248 
249 	upto -= from-1;
250 	upto /= 4;
251 	while (--upto >= 0) {
252 		result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
253 		result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
254 		result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
255 		result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
256 	}
257 	return (result);
258 }
259 
260 /* Layer 2 Product code en/decoder */
261 int do_encode_L2 __PR((unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)], int sectortype, unsigned address));
262 
263 int
do_encode_L2(inout,sectortype,address)264 do_encode_L2(inout, sectortype, address)
265 	unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)];
266 	int sectortype;
267 	unsigned address;
268 {
269 	unsigned int result;
270 
271 /*	SYNCPATTERN	"\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" */
272 #define	SYNCPATTERN	"\000\377\377\377\377\377\377\377\377\377\377"
273 
274 	/* supply initial sync pattern */
275 	memcpy(inout, SYNCPATTERN, sizeof (SYNCPATTERN));
276 
277 	if (sectortype == MODE_0) {
278 		memset(inout + sizeof (SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q);
279 		build_address(inout, sectortype, address);
280 		return (0);
281 	}
282 
283 	switch (sectortype) {
284 
285 	case MODE_1:
286 		build_address(inout, sectortype, address);
287 		result = build_edc(inout, 0, 16+2048-1);
288 		inout[2064+0] = result >> 0L;
289 		inout[2064+1] = result >> 8L;
290 		inout[2064+2] = result >> 16L;
291 		inout[2064+3] = result >> 24L;
292 		memset(inout+2064+4, 0, 8);
293 		encode_L2_P(inout+12);
294 		encode_L2_Q(inout+12);
295 		break;
296 	case MODE_2:
297 		build_address(inout, sectortype, address);
298 		break;
299 	case MODE_2_FORM_1:
300 		result = build_edc(inout, 16, 16+8+2048-1);
301 		inout[2072+0] = result >> 0L;
302 		inout[2072+1] = result >> 8L;
303 		inout[2072+2] = result >> 16L;
304 		inout[2072+3] = result >> 24L;
305 
306 		/* clear header for P/Q parity calculation */
307 		inout[12] = 0;
308 		inout[12+1] = 0;
309 		inout[12+2] = 0;
310 		inout[12+3] = 0;
311 		encode_L2_P(inout+12);
312 		encode_L2_Q(inout+12);
313 		build_address(inout, sectortype, address);
314 		break;
315 	case MODE_2_FORM_2:
316 		build_address(inout, sectortype, address);
317 		result = build_edc(inout, 16, 16+8+2324-1);
318 		inout[2348+0] = result >> 0L;
319 		inout[2348+1] = result >> 8L;
320 		inout[2348+2] = result >> 16L;
321 		inout[2348+3] = result >> 24L;
322 		break;
323 	default:
324 		return (-1);
325 	}
326 
327 	return (0);
328 }
329 
330 
331 /*--------------------------------------------------------------------------*/
332 #include "encoder_tables"
333 
334 static int encode_L1_Q	__PR((unsigned char inout[L1_RAW + L1_Q]));
335 
336 static int
encode_L1_Q(inout)337 encode_L1_Q(inout)
338 	unsigned char inout[L1_RAW + L1_Q];
339 {
340 	unsigned char *Q;
341 	int	i;
342 
343 	memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2);
344 	Q = inout + L1_RAW/2;
345 
346 	memset(Q, 0, L1_Q);
347 	for (i = 0; i < L1_RAW; i++) {
348 		unsigned char data;
349 
350 		if (i == L1_RAW/2) {
351 			inout += L1_Q;
352 		}
353 		data = inout[i];
354 		if (data != 0) {
355 			unsigned char base = rs_l12_log[data];
356 
357 			Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
358 			Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
359 			Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
360 			Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
361 		}
362 	}
363 	return (0);
364 }
365 
366 static int encode_L1_P	__PR((unsigned char inout[L1_RAW + L1_Q + L1_P]));
367 
368 static int
encode_L1_P(inout)369 encode_L1_P(inout)
370 	unsigned char inout[L1_RAW + L1_Q + L1_P];
371 {
372 	unsigned char *P;
373 	int	i;
374 
375 	P = inout + L1_RAW + L1_Q;
376 
377 	memset(P, 0, L1_P);
378 	for (i = 0; i < L1_RAW + L1_Q + L1_P; i++) {
379 		unsigned char data;
380 
381 		data = inout[i];
382 		if (data != 0) {
383 			unsigned char base = rs_l12_log[data];
384 
385 			P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
386 			P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
387 			P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
388 			P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
389 		}
390 	}
391 	return (0);
392 }
393 
394 #ifdef	MAIN	/* Make public (non-static) if completely implemented */
395 
396 static int decode_L1_Q	__PR((unsigned char inout[L1_RAW + L1_Q]));
397 
398 static int
decode_L1_Q(inout)399 decode_L1_Q(inout)
400 	unsigned char inout[L1_RAW + L1_Q];
401 {
402 	return (0);
403 }
404 
405 static int decode_L1_P	__PR((unsigned char in[L1_RAW + L1_Q + L1_P]));
406 
407 static int
decode_L1_P(in)408 decode_L1_P(in)
409 	unsigned char in[L1_RAW + L1_Q + L1_P];
410 {
411 	return (0);
412 }
413 #endif	/* MAIN */
414 
415 int decode_L2_Q __PR((unsigned char inout[4 + L2_RAW + 12 + L2_Q]));
416 
417 int
decode_L2_Q(inout)418 decode_L2_Q(inout)
419 	unsigned char inout[4 + L2_RAW + 12 + L2_Q];
420 {
421 	return (0);
422 }
423 
424 int decode_L2_P __PR((unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]));
425 
426 int
decode_L2_P(inout)427 decode_L2_P(inout)
428 	unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P];
429 {
430 	return (0);
431 }
432 
433 static int encode_LSUB_Q	__PR((unsigned char inout[LSUB_RAW + LSUB_Q]));
434 
435 static int
encode_LSUB_Q(inout)436 encode_LSUB_Q(inout)
437 	unsigned char inout[LSUB_RAW + LSUB_Q];
438 {
439 	unsigned char *Q;
440 	int i;
441 
442 	memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW);
443 	Q = inout + LSUB_QRAW;
444 
445 	memset(Q, 0, LSUB_Q);
446 
447 	for (i = 0; i < LSUB_QRAW; i++) {
448 		unsigned char data;
449 
450 		data = inout[i] & 0x3f;
451 		if (data != 0) {
452 			unsigned char base = rs_sub_rw_log[data];
453 
454 			Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
455 			Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
456 		}
457 	}
458 	return (0);
459 }
460 
461 
462 static int encode_LSUB_P	__PR((unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]));
463 
464 static int
encode_LSUB_P(inout)465 encode_LSUB_P(inout)
466 	unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P];
467 {
468 	unsigned char *P;
469 	int i;
470 
471 	P = inout + LSUB_RAW + LSUB_Q;
472 
473 	memset(P, 0, LSUB_P);
474 	for (i = 0; i < LSUB_RAW + LSUB_Q; i++) {
475 		unsigned char data;
476 
477 		data = inout[i] & 0x3f;
478 		if (data != 0) {
479 			unsigned char base = rs_sub_rw_log[data];
480 
481 			P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
482 			P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
483 			P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
484 			P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
485 		}
486 	}
487 	return (0);
488 }
489 
490 int decode_LSUB_Q __PR((unsigned char inout[LSUB_QRAW + LSUB_Q]));
491 
492 int
decode_LSUB_Q(inout)493 decode_LSUB_Q(inout)
494 	unsigned char inout[LSUB_QRAW + LSUB_Q];
495 {
496 	unsigned char Q[LSUB_Q];
497 	int i;
498 
499 	memset(Q, 0, LSUB_Q);
500 	for (i = LSUB_QRAW + LSUB_Q -1; i >= 0; i--) {
501 		unsigned char data;
502 
503 		data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f;
504 		if (data != 0) {
505 			unsigned char base = rs_sub_rw_log[data];
506 
507 			Q[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
508 			Q[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
509 		}
510 	}
511 	return (Q[0] != 0 || Q[1] != 0);
512 }
513 
514 int decode_LSUB_P __PR((unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]));
515 
516 int
decode_LSUB_P(inout)517 decode_LSUB_P(inout)
518 	unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P];
519 {
520 	unsigned char P[LSUB_P];
521 	int i;
522 
523 	memset(P, 0, LSUB_P);
524 	for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i >= 0; i--) {
525 		unsigned char data;
526 
527 		data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f;
528 		if (data != 0) {
529 			unsigned char base = rs_sub_rw_log[data];
530 
531 			P[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
532 			P[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
533 			P[2] ^= rs_sub_rw_alog[(base+2*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
534 			P[3] ^= rs_sub_rw_alog[(base+3*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
535 		}
536 	}
537 	return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0);
538 }
539 
540 /* Layer 1 CIRC en/decoder */
541 #define	MAX_L1_DEL1	2
542 static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW];
543 #define	MAX_L1_DEL2	108
544 static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q];
545 #define	MAX_L1_DEL3	1
546 static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P];
547 static unsigned l1_del_index;
548 
549 int do_encode_L1  __PR((unsigned char in[L1_RAW*FRAMES_PER_SECTOR],
550 		unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
551 		int delay1, int delay2, int delay3, int permute));
552 
553 int
do_encode_L1(in,out,delay1,delay2,delay3,permute)554 do_encode_L1(in, out, delay1, delay2, delay3, permute)
555 	unsigned char in[L1_RAW*FRAMES_PER_SECTOR];
556 	unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
557 	int delay1;
558 	int delay2;
559 	int delay3;
560 	int permute;
561 {
562 	int i;
563 
564 	for (i = 0; i < FRAMES_PER_SECTOR; i++) {
565 		int j;
566 		unsigned char t;
567 
568 		if (in != out)
569 			memcpy(out, in, L1_RAW);
570 
571 		if (delay1) {
572 			/* shift through delay line 1 */
573 			for (j = 0; j < L1_RAW; j++) {
574 				if (((j/4) % MAX_L1_DEL1) == 0) {
575 					t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
576 					l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j];
577 					out[j] = t;
578 				}
579 			}
580 		}
581 
582 		if (permute) {
583 			/* permute */
584 			t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18];
585 			out[18] = out[6]; out [6] = t;
586 			t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19];
587 			out[19] = out[7]; out [7] = t;
588 			t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14];
589 			out[14] = out[12]; out [12] = t;
590 			t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15];
591 			out[15] = out[13]; out [13] = t;
592 		}
593 
594 		/* build Q parity */
595 		encode_L1_Q(out);
596 
597 		if (delay2) {
598 			/* shift through delay line 2 */
599 			for (j = 0; j < L1_RAW+L1_Q; j++) {
600 				if (j != 0) {
601 					t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
602 					l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j];
603 					out[j] = t;
604 				}
605 			}
606 		}
607 
608 		/* build P parity */
609 		encode_L1_P(out);
610 
611 		if (delay3) {
612 			/* shift through delay line 3 */
613 			for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
614 				if (((j) & MAX_L1_DEL3) == 0) {
615 					t = l1_delay_line3[0][j];
616 					l1_delay_line3[0][j] = out[j];
617 					out[j] = t;
618 				}
619 			}
620 		}
621 
622 		/* invert Q and P parity */
623 		for (j = 0; j < L1_Q; j++)
624 			out[j+12] = ~out[j+12];
625 		for (j = 0; j < L1_P; j++)
626 			out[j+28] = ~out[j+28];
627 
628 		l1_del_index++;
629 		out += L1_RAW+L1_Q+L1_P;
630 		in += L1_RAW;
631 	}
632 	return (0);
633 }
634 
635 #ifdef	MAIN	/* Make public (non-static) if completely implemented */
636 
637 static /* XXX should be non static XXX*/
638 
639 int
do_decode_L1(in,out,delay1,delay2,delay3,permute)640 do_decode_L1(in, out, delay1, delay2, delay3, permute)
641 	unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
642 	unsigned char out[L1_RAW*FRAMES_PER_SECTOR];
643 	int delay1;
644 	int delay2;
645 	int delay3;
646 	int permute;
647 {
648 	int i;
649 
650 	for (i = 0; i < FRAMES_PER_SECTOR; i++) {
651 		int j;
652 		unsigned char t;
653 
654 		if (delay3) {
655 			/* shift through delay line 3 */
656 			for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
657 				if (((j) & MAX_L1_DEL3) != 0) {
658 					t = l1_delay_line3[0][j];
659 					l1_delay_line3[0][j] = in[j];
660 					in[j] = t;
661 				}
662 			}
663 		}
664 
665 		/* invert Q and P parity */
666 		for (j = 0; j < L1_Q; j++)
667 			in[j+12] = ~in[j+12];
668 		for (j = 0; j < L1_P; j++)
669 			in[j+28] = ~in[j+28];
670 
671 		/* build P parity */
672 		decode_L1_P(in);
673 
674 		if (delay2) {
675 			/* shift through delay line 2 */
676 			for (j = 0; j < L1_RAW+L1_Q; j++) {
677 				if (j != L1_RAW+L1_Q-1) {
678 					t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
679 					l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j];
680 					in[j] = t;
681 				}
682 			}
683 		}
684 
685 		/* build Q parity */
686 		decode_L1_Q(in);
687 
688 		if (permute) {
689 			/* permute */
690 			t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10];
691 			in[10] = in[8]; in [8] = t;
692 			t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11];
693 			in[11] = in[9]; in [9] = t;
694 			t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20];
695 			in[20] = in[16]; in [16] = t;
696 			t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21];
697 			in[21] = in[17]; in [17] = t;
698 		}
699 
700 		if (delay1) {
701 			/* shift through delay line 1 */
702 			for (j = 0; j < L1_RAW; j++) {
703 				if (((j/4) % MAX_L1_DEL1) != 0) {
704 					t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
705 					l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j];
706 					in[j] = t;
707 				}
708 			}
709 		}
710 
711 		if (in != out)
712 			memcpy(out, in, (L1_RAW));
713 
714 		l1_del_index++;
715 		in += L1_RAW+L1_Q+L1_P;
716 		out += L1_RAW;
717 	}
718 	return (0);
719 }
720 
721 static int
do_decode_L2(in,out)722 do_decode_L2(in, out)
723 	unsigned char in[(L2_RAW+L2_Q+L2_P)];
724 	unsigned char out[L2_RAW];
725 {
726 	return (0);
727 }
728 #endif	/* MAIN */
729 
730 
731 #define	MAX_SUB_DEL	8
732 static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P];
733 static unsigned sub_del_index;
734 
735 /* R-W Subchannel en/decoder */
736 
737 int do_encode_sub __PR((unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
738 		unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
739 		int delay1, int permute));
740 
741 int
do_encode_sub(in,out,delay1,permute)742 do_encode_sub(in, out, delay1, permute)
743 	unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME];
744 	unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME];
745 	int delay1;
746 	int permute;
747 {
748 	int i;
749 
750 	if (in == out)
751 		return (-1);
752 
753 	for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
754 		int j;
755 		unsigned char t;
756 
757 		memcpy(out, in, (LSUB_RAW));
758 
759 		/* build Q parity */
760 		encode_LSUB_Q(out);
761 
762 		/* build P parity */
763 		encode_LSUB_P(out);
764 
765 		if (permute) {
766 			/* permute */
767 			t = out[1]; out[1] = out[18]; out[18] = t;
768 			t = out[2]; out[2] = out[ 5]; out[ 5] = t;
769 			t = out[3]; out[3] = out[23]; out[23] = t;
770 		}
771 
772 		if (delay1) {
773 			/* shift through delay_line */
774 			for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
775 				if ((j % MAX_SUB_DEL) != 0) {
776 					t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
777 					sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j];
778 					out[j] = t;
779 				}
780 			}
781 		}
782 		sub_del_index++;
783 		out += LSUB_RAW+LSUB_Q+LSUB_P;
784 		in += LSUB_RAW;
785 	}
786 	return (0);
787 }
788 
789 int
790 do_decode_sub __PR((
791 	unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
792 	unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
793 	int delay1, int permute));
794 
795 int
do_decode_sub(in,out,delay1,permute)796 do_decode_sub(in, out, delay1, permute)
797 	unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME];
798 	unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME];
799 	int delay1;
800 	int permute;
801 {
802 	int i;
803 
804 	if (in == out)
805 		return (-1);
806 
807 	for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
808 		int j;
809 		unsigned char t;
810 
811 		if (delay1) {
812 			/* shift through delay_line */
813 			for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
814 				if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) {
815 					t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
816 					sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j];
817 					in[j] = t;
818 				}
819 			}
820 		}
821 
822 		if (permute) {
823 			/* permute */
824 			t = in[1]; in[1] = in[18]; in[18] = t;
825 			t = in[2]; in[2] = in[ 5]; in[ 5] = t;
826 			t = in[3]; in[3] = in[23]; in[23] = t;
827 		}
828 
829 		/* build P parity */
830 		decode_LSUB_P(in);
831 
832 		/* build Q parity */
833 		decode_LSUB_Q(in);
834 
835 		memcpy(out, in, LSUB_QRAW);
836 		memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW);
837 
838 		sub_del_index++;
839 		in += LSUB_RAW+LSUB_Q+LSUB_P;
840 		out += LSUB_RAW;
841 	}
842 	return (0);
843 }
844 
845 static int sectortype = MODE_0;
846 
847 int get_sector_type __PR((void));
848 
849 int
get_sector_type()850 get_sector_type()
851 {
852 	return (sectortype);
853 }
854 
855 int set_sector_type __PR((int st));
856 
857 int
set_sector_type(st)858 set_sector_type(st)
859 	int st;
860 {
861 	switch (st) {
862 
863 	case MODE_0:
864 	case MODE_1:
865 	case MODE_2:
866 	case MODE_2_FORM_1:
867 	case MODE_2_FORM_2:
868 		sectortype = st;
869 		return (0);
870 	default:
871 		return (-1);
872 	}
873 }
874 
875 /* ------------- --------------*/
876 #ifdef MAIN
877 
878 #define	DO_L1	1
879 #define	DO_L2	2
880 #define	DO_SUB	4
881 
882 static const unsigned sect_size[8][2] = {
883 /* nothing */
884 {0, 0},
885 /* Layer 1 decode/encode */
886 { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR},
887 /* Layer 2 decode/encode */
888 { 16+L2_RAW+12+L2_Q+L2_P, L2_RAW},
889 /* Layer 1 and 2 decode/encode */
890 { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR},
891 /* Subchannel decode/encode */
892 { (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
893 	LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME},
894 /* Layer 1 and subchannel decode/encode */
895 { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR +
896 	(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
897 	LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
898 	    L1_RAW*FRAMES_PER_SECTOR},
899 /* Layer 2 and subchannel decode/encode */
900 { L2_RAW+L2_Q+L2_P +
901 	(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
902 	LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
903 	    L2_RAW},
904 /* Layer 1, 2 and subchannel decode/encode */
905 { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR +
906 	(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
907 	LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
908 	L1_RAW*FRAMES_PER_SECTOR},
909 };
910 
911 int main	__PR((int argc, char **argv));
912 
913 int
main(argc,argv)914 main(argc, argv)
915 	int	argc;
916 	char	**argv;
917 {
918 	int encode = 1;
919 	int mask = DO_L2;
920 	FILE *infp;
921 	FILE *outfp;
922 	unsigned address = 0;
923 	unsigned char *l1_inbuf;
924 	unsigned char *l1_outbuf;
925 	unsigned char *l2_inbuf;
926 	unsigned char *l2_outbuf;
927 	unsigned char *sub_inbuf;
928 	unsigned char *sub_outbuf;
929 	unsigned char *last_outbuf;
930 	unsigned char inbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME +
931 			(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
932 	unsigned char outbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME +
933 			(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
934 	unsigned load_offset;
935 
936 	l1_inbuf = l2_inbuf = sub_inbuf = inbuf;
937 	l1_outbuf = l2_outbuf = sub_outbuf = last_outbuf = outbuf;
938 
939 	infp = fopen("sectors_in", "rb");
940 	outfp = fopen("sectors_out", "wb");
941 
942 	sectortype = MODE_1;
943 	address = 0 + 75*2;
944 
945 	switch (sectortype) {
946 
947 	case MODE_1:
948 	case MODE_2:
949 		load_offset = 16;
950 		break;
951 	case MODE_2_FORM_1:
952 	case MODE_2_FORM_2:
953 		load_offset = 24;
954 		break;
955 	default:
956 		load_offset = 0;
957 	}
958 	while (1) {
959 
960 		if (1 != fread(inbuf+load_offset,
961 				sect_size[mask][encode], 1, infp)) {
962 			perror("");
963 			break;
964 		}
965 		if (encode == 1) {
966 			if (mask & DO_L2) {
967 				switch (sectortype) {
968 
969 				case MODE_0:
970 					break;
971 				case MODE_1:
972 					break;
973 				case MODE_2:
974 					if (1 !=
975 					    fread(inbuf+load_offset+
976 						sect_size[mask][encode],
977 					    2336 - sect_size[mask][encode],
978 						1, infp)) { perror(""); break; }
979 					break;
980 				case MODE_2_FORM_1:
981 					break;
982 				case MODE_2_FORM_2:
983 					if (1 !=
984 					    fread(inbuf+load_offset+
985 						sect_size[mask][encode],
986 					    2324 - sect_size[mask][encode],
987 						1, infp)) { perror(""); break; }
988 					break;
989 				default:
990 					if (1 !=
991 					    fread(inbuf+load_offset+
992 						sect_size[mask][encode],
993 					    2448 - sect_size[mask][encode],
994 						1, infp)) { perror(""); break; }
995 					memset(inbuf, 0, 16);
996 					/*memset(inbuf+16+2048,0,12+272);*/
997 					break;
998 				}
999 				do_encode_L2(l2_inbuf, MODE_1, address);
1000 				if (0) scramble_L2(l2_inbuf);
1001 				last_outbuf = l1_inbuf = l2_inbuf;
1002 				l1_outbuf = l2_inbuf;
1003 				sub_inbuf = l2_inbuf + L2_RAW;
1004 				sub_outbuf = l2_outbuf + 12 + 4+ L2_RAW+4+ 8+ L2_Q+L2_P;
1005 			}
1006 			if (mask & DO_L1) {
1007 				do_encode_L1(l1_inbuf, l1_outbuf, 1, 1, 1, 1);
1008 				last_outbuf = l1_outbuf;
1009 				sub_inbuf = l1_inbuf + L1_RAW*FRAMES_PER_SECTOR;
1010 				sub_outbuf = l1_outbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR;
1011 			}
1012 			if (mask & DO_SUB) {
1013 				do_encode_sub(sub_inbuf, sub_outbuf, 0, 0);
1014 			}
1015 		} else {
1016 			if (mask & DO_L1) {
1017 				do_decode_L1(l1_inbuf, l1_outbuf, 1, 1, 1, 1);
1018 				last_outbuf = l2_inbuf = l1_outbuf;
1019 				l2_outbuf = l1_inbuf;
1020 				sub_inbuf = l1_inbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR;
1021 				sub_outbuf = l1_outbuf + L1_RAW*FRAMES_PER_SECTOR;
1022 			}
1023 			if (mask & DO_L2) {
1024 				do_decode_L2(l2_inbuf, l2_outbuf);
1025 				last_outbuf = l2_outbuf;
1026 				sub_inbuf = l2_inbuf + L2_RAW+L2_Q+L2_P;
1027 				sub_outbuf = l2_outbuf + L2_RAW;
1028 			}
1029 			if (mask & DO_SUB) {
1030 				do_decode_sub(sub_inbuf, sub_outbuf, 1, 1);
1031 			}
1032 		}
1033 		if (1 != fwrite(last_outbuf, sect_size[mask][1 - encode], 1, outfp)) {
1034 			perror("");
1035 			break;
1036 		}
1037 		address++;
1038 	}
1039 #if 0
1040 	/* flush the data from the delay lines with zeroed sectors, if necessary */
1041 #endif
1042 	fclose(infp);
1043 	fclose(outfp);
1044 
1045 	return (0);
1046 }
1047 #endif
1048