Search
lxdream.org :: lxdream/src/gdrom/edc_ecc.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/edc_ecc.c
changeset 669:ab344e42bca9
prev644:ccae4bfa5f82
next678:35eb00945316
author nkeynes
date Mon May 12 10:00:13 2008 +0000 (13 years ago)
permissions -rw-r--r--
last change Cleanup most of the -Wall warnings (getting a bit sloppy...)
Convert FP code to use fixed banks rather than indirect pointer
(3-4% faster this way now)
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.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 }
.