Search
lxdream.org :: lxdream/src/drivers/cdrom/edc_ecc.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/cdrom/edc_ecc.c
changeset 1097:d4807997e450
prev678:35eb00945316
author nkeynes
date Sun Jan 31 18:35:06 2010 +1000 (14 years ago)
permissions -rw-r--r--
last change Refactor CDROM host support
- Completely separate GDROM hardware (in gdrom/gdrom.c) from generic CDROM
support (now in drivers/cdrom)
- Add concept of 'sector sources' that can be mixed and matched to create
cdrom discs (makes support of arbitrary disc types much simpler)
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/drivers/cdrom/edc_ecc.c Sun Jan 31 18:35:06 2010 +1000
1.3 @@ -0,0 +1,801 @@
1.4 +/*
1.5 + * Note: This file has been extracted from crkit 1.1.6 and modified to work within
1.6 + * lxdream.
1.7 + */
1.8 +/*
1.9 + * This file has been modified for the cdrkit suite.
1.10 + *
1.11 + * The behaviour and appearence of the program code below can differ to a major
1.12 + * extent from the version distributed by the original author(s).
1.13 + *
1.14 + * For details, see Changelog file distributed with the cdrkit package. If you
1.15 + * received this file from another source then ask the distributing person for
1.16 + * a log of modifications.
1.17 + *
1.18 + */
1.19 +
1.20 +/* @(#)edc_ecc.c 1.21 03/04/04 Copyright 1998-2002 Heiko Eissfeldt, Joerg Schilling */
1.21 +
1.22 +/*
1.23 + * Copyright 1998-2002 by Heiko Eissfeldt
1.24 + * Copyright 2002 by Joerg Schilling
1.25 + *
1.26 + * This file contains protected intellectual property.
1.27 + *
1.28 + * reed-solomon encoder / decoder for compact discs.
1.29 + *
1.30 + */
1.31 +/*
1.32 + * This program is free software; you can redistribute it and/or modify
1.33 + * it under the terms of the GNU General Public License version 2
1.34 + * as published by the Free Software Foundation.
1.35 + *
1.36 + * This program is distributed in the hope that it will be useful,
1.37 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.38 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.39 + * GNU General Public License for more details.
1.40 + *
1.41 + * You should have received a copy of the GNU General Public License along with
1.42 + * this program; see the file COPYING. If not, write to the Free Software
1.43 + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1.44 + */
1.45 +
1.46 +#include <stdint.h>
1.47 +#include <stdio.h>
1.48 +#include <string.h>
1.49 +#include "drivers/cdrom/defs.h"
1.50 +#include "drivers/cdrom/ecc.h"
1.51 +
1.52 +#define xaligned(a, s) ((((uintptr_t)(a)) & (s)) == 0 )
1.53 +
1.54 +int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)],
1.55 + int sectortype, unsigned address);
1.56 +
1.57 +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR],
1.58 + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.59 + int delay1, int delay2, int delay3, int permute);
1.60 +
1.61 +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
1.62 + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
1.63 + int delay1, int permute);
1.64 +
1.65 +int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)],
1.66 + unsigned char out[L2_RAW]);
1.67 +
1.68 +int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.69 + unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
1.70 + int delay1, int delay2, int delay3, int permute);
1.71 +
1.72 +int do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
1.73 + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
1.74 + int delay1, int permute);
1.75 +
1.76 +
1.77 +
1.78 +/* ------------- tables generated by gen_encodes --------------*/
1.79 +
1.80 +#include "edc_scramble.h"
1.81 +
1.82 +#define DO4(a) a;a;a;a;
1.83 +#define DO13(a) a;a;a;a;a;a;a;a;a;a;a;a;a;
1.84 +
1.85 +/*
1.86 + * Scrambles 2352 - 12 = 2340 bytes
1.87 + */
1.88 +int scramble_L2(unsigned char *inout);
1.89 +
1.90 +int scramble_L2(unsigned char *inout)
1.91 +{
1.92 +#ifndef EDC_SCRAMBLE_NOSWAP
1.93 + unsigned int *f = (unsigned int *)inout;
1.94 +#endif
1.95 +
1.96 + if (!xaligned(inout + 12, sizeof(uint32_t)-1)) {
1.97 +
1.98 + uint8_t *r = inout + 12;
1.99 + const uint8_t *s = yellowbook_scrambler;
1.100 + register int i;
1.101 +
1.102 + for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char)/4; --i >= 0;) {
1.103 + DO4(*r++ ^= *s++);
1.104 + }
1.105 +
1.106 + } else {
1.107 + uint32_t *r = (uint32_t *) (inout + 12);
1.108 + const uint32_t *s = yellowbook_scrambler_uint32;
1.109 + register int i;
1.110 +
1.111 + for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(uint32_t)/13; --i >= 0;) {
1.112 + DO13(*r++ ^= *s++);
1.113 + }
1.114 + }
1.115 +
1.116 +#ifndef EDC_SCRAMBLE_NOSWAP
1.117 +
1.118 + /* generate F1 frames */
1.119 + for (i = 2352/sizeof(unsigned int); i; i--) {
1.120 + *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8);
1.121 + }
1.122 +#endif
1.123 +
1.124 + return (0);
1.125 +}
1.126 +
1.127 +#include "edc_l2sq.h"
1.128 +
1.129 +static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]);
1.130 +
1.131 +static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q])
1.132 +{
1.133 + unsigned char *dps;
1.134 + unsigned char *dp;
1.135 + unsigned char *Q;
1.136 + register int i;
1.137 + int j;
1.138 +
1.139 + Q = inout + 4 + L2_RAW + 4 + 8 + L2_P;
1.140 +
1.141 + dps = inout;
1.142 + for (j = 0; j < 26; j++) {
1.143 + register unsigned short a;
1.144 + register unsigned short b;
1.145 + a = b = 0;
1.146 +
1.147 + dp = dps;
1.148 + for (i = 0; i < 43; i++) {
1.149 +
1.150 + /* LSB */
1.151 + a ^= L2sq[i][*dp++];
1.152 +
1.153 + /* MSB */
1.154 + b ^= L2sq[i][*dp];
1.155 +
1.156 + dp += 2*44-1;
1.157 + if (dp >= &inout[(4 + L2_RAW + 4 + 8 + L2_P)]) {
1.158 + dp -= (4 + L2_RAW + 4 + 8 + L2_P);
1.159 + }
1.160 + }
1.161 + Q[0] = a >> 8;
1.162 + Q[26*2] = a;
1.163 + Q[1] = b >> 8;
1.164 + Q[26*2+1] = b;
1.165 +
1.166 + Q += 2;
1.167 + dps += 2*43;
1.168 + }
1.169 + return (0);
1.170 +}
1.171 +
1.172 +static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]);
1.173 +
1.174 +static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P])
1.175 +{
1.176 + unsigned char *dp;
1.177 + unsigned char *P;
1.178 + register int i;
1.179 + int j;
1.180 +
1.181 + P = inout + 4 + L2_RAW + 4 + 8;
1.182 +
1.183 + for (j = 0; j < 43; j++) {
1.184 + register unsigned short a;
1.185 + register unsigned short b;
1.186 +
1.187 + a = b = 0;
1.188 + dp = inout;
1.189 + for (i = 19; i < 43; i++) {
1.190 +
1.191 + /* LSB */
1.192 + a ^= L2sq[i][*dp++];
1.193 +
1.194 + /* MSB */
1.195 + b ^= L2sq[i][*dp];
1.196 +
1.197 + dp += 2*43 -1;
1.198 + }
1.199 + P[0] = a >> 8;
1.200 + P[43*2] = a;
1.201 + P[1] = b >> 8;
1.202 + P[43*2+1] = b;
1.203 +
1.204 + P += 2;
1.205 + inout += 2;
1.206 + }
1.207 + return (0);
1.208 +}
1.209 +
1.210 +static unsigned char bin2bcd(unsigned p);
1.211 +
1.212 +static unsigned char bin2bcd(unsigned p)
1.213 +{
1.214 + return ((p/10)<<4)|(p%10);
1.215 +}
1.216 +
1.217 +int cd_build_address(unsigned char inout[], int sectortype, unsigned address)
1.218 +{
1.219 + inout[12] = bin2bcd(address / (60*75));
1.220 + inout[13] = bin2bcd((address / 75) % 60);
1.221 + inout[14] = bin2bcd(address % 75);
1.222 + if (sectortype == MODE_0)
1.223 + inout[15] = 0;
1.224 + else if (sectortype == MODE_1)
1.225 + inout[15] = 1;
1.226 + else if (sectortype == MODE_2)
1.227 + inout[15] = 2;
1.228 + else if (sectortype == MODE_2_FORM_1)
1.229 + inout[15] = 2;
1.230 + else if (sectortype == MODE_2_FORM_2)
1.231 + inout[15] = 2;
1.232 + else
1.233 + return (-1);
1.234 + return (0);
1.235 +}
1.236 +
1.237 +#include "edc_crctable.h"
1.238 +
1.239 +/*
1.240 + * Called with 2064, 2056 or 2332 byte difference - all dividable by 4.
1.241 + */
1.242 +unsigned int build_edc(unsigned char inout[], int from, int upto);
1.243 +
1.244 +unsigned int build_edc(unsigned char inout[], int from, int upto)
1.245 +{
1.246 + unsigned char *p = inout+from;
1.247 + unsigned int result = 0;
1.248 +
1.249 + upto -= from-1;
1.250 + upto /= 4;
1.251 + while (--upto >= 0) {
1.252 + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
1.253 + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
1.254 + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
1.255 + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
1.256 + }
1.257 + return (result);
1.258 +}
1.259 +
1.260 +/* Layer 2 Product code en/decoder */
1.261 +
1.262 +int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)],
1.263 + int sectortype, unsigned address)
1.264 +{
1.265 + unsigned int result;
1.266 +
1.267 +/* SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" */
1.268 +#define SYNCPATTERN "\000\377\377\377\377\377\377\377\377\377\377"
1.269 +
1.270 + /* supply initial sync pattern */
1.271 + memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN));
1.272 +
1.273 + if (sectortype == MODE_0) {
1.274 + memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q);
1.275 + cd_build_address(inout, sectortype, address);
1.276 + return (0);
1.277 + }
1.278 +
1.279 + switch (sectortype) {
1.280 +
1.281 + case MODE_1:
1.282 + cd_build_address(inout, sectortype, address);
1.283 + result = build_edc(inout, 0, 16+2048-1);
1.284 + inout[2064+0] = result >> 0L;
1.285 + inout[2064+1] = result >> 8L;
1.286 + inout[2064+2] = result >> 16L;
1.287 + inout[2064+3] = result >> 24L;
1.288 + memset(inout+2064+4, 0, 8);
1.289 + encode_L2_P(inout+12);
1.290 + encode_L2_Q(inout+12);
1.291 + break;
1.292 + case MODE_2:
1.293 + cd_build_address(inout, sectortype, address);
1.294 + break;
1.295 + case MODE_2_FORM_1:
1.296 + result = build_edc(inout, 16, 16+8+2048-1);
1.297 + inout[2072+0] = result >> 0L;
1.298 + inout[2072+1] = result >> 8L;
1.299 + inout[2072+2] = result >> 16L;
1.300 + inout[2072+3] = result >> 24L;
1.301 +
1.302 + /* clear header for P/Q parity calculation */
1.303 + inout[12] = 0;
1.304 + inout[12+1] = 0;
1.305 + inout[12+2] = 0;
1.306 + inout[12+3] = 0;
1.307 + encode_L2_P(inout+12);
1.308 + encode_L2_Q(inout+12);
1.309 + cd_build_address(inout, sectortype, address);
1.310 + break;
1.311 + case MODE_2_FORM_2:
1.312 + cd_build_address(inout, sectortype, address);
1.313 + result = build_edc(inout, 16, 16+8+2324-1);
1.314 + inout[2348+0] = result >> 0L;
1.315 + inout[2348+1] = result >> 8L;
1.316 + inout[2348+2] = result >> 16L;
1.317 + inout[2348+3] = result >> 24L;
1.318 + break;
1.319 + default:
1.320 + return (-1);
1.321 + }
1.322 +
1.323 + return (0);
1.324 +}
1.325 +
1.326 +
1.327 +/*--------------------------------------------------------------------------*/
1.328 +#include "edc_encoder.h"
1.329 +
1.330 +static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]);
1.331 +
1.332 +static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q])
1.333 +{
1.334 + unsigned char *Q;
1.335 + int i;
1.336 +
1.337 + memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2);
1.338 + Q = inout + L1_RAW/2;
1.339 +
1.340 + memset(Q, 0, L1_Q);
1.341 + for (i = 0; i < L1_RAW + L1_Q; i++) {
1.342 + unsigned char data;
1.343 +
1.344 + if (i == L1_RAW/2) i += L1_Q;
1.345 + data = inout[i];
1.346 + if (data != 0) {
1.347 + unsigned char base = rs_l12_log[data];
1.348 +
1.349 + Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.350 + Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.351 + Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.352 + Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.353 + }
1.354 + }
1.355 + return (0);
1.356 +}
1.357 +
1.358 +static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]);
1.359 +
1.360 +static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P])
1.361 +{
1.362 + unsigned char *P;
1.363 + int i;
1.364 +
1.365 + P = inout + L1_RAW + L1_Q;
1.366 +
1.367 + memset(P, 0, L1_P);
1.368 + for (i = 0; i < L2_RAW + L2_Q + L2_P; i++) {
1.369 + unsigned char data;
1.370 +
1.371 + data = inout[i];
1.372 + if (data != 0) {
1.373 + unsigned char base = rs_l12_log[data];
1.374 +
1.375 + P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.376 + P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.377 + P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.378 + P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.379 + }
1.380 + }
1.381 + return (0);
1.382 +}
1.383 +
1.384 +static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]);
1.385 +
1.386 +static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q])
1.387 +{
1.388 + return (0);
1.389 +}
1.390 +
1.391 +static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]);
1.392 +
1.393 +static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P])
1.394 +{
1.395 + return (0);
1.396 +}
1.397 +
1.398 +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]);
1.399 +
1.400 +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q])
1.401 +{
1.402 + return (0);
1.403 +}
1.404 +
1.405 +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]);
1.406 +
1.407 +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P])
1.408 +{
1.409 + return (0);
1.410 +}
1.411 +
1.412 +static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]);
1.413 +
1.414 +static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q])
1.415 +{
1.416 + unsigned char *Q;
1.417 + int i;
1.418 +
1.419 + memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW);
1.420 + Q = inout + LSUB_QRAW;
1.421 +
1.422 + memset(Q, 0, LSUB_Q);
1.423 +
1.424 + for (i = 0; i < LSUB_QRAW; i++) {
1.425 + unsigned char data;
1.426 +
1.427 + data = inout[i] & 0x3f;
1.428 + if (data != 0) {
1.429 + unsigned char base = rs_sub_rw_log[data];
1.430 +
1.431 + Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.432 + Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.433 + }
1.434 + }
1.435 + return (0);
1.436 +}
1.437 +
1.438 +
1.439 +static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]);
1.440 +
1.441 +static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P])
1.442 +{
1.443 + unsigned char *P;
1.444 + int i;
1.445 +
1.446 + P = inout + LSUB_RAW + LSUB_Q;
1.447 +
1.448 + memset(P, 0, LSUB_P);
1.449 + for (i = 0; i < LSUB_RAW + LSUB_Q; i++) {
1.450 + unsigned char data;
1.451 +
1.452 + data = inout[i] & 0x3f;
1.453 + if (data != 0) {
1.454 + unsigned char base = rs_sub_rw_log[data];
1.455 +
1.456 + P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.457 + P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.458 + P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.459 + P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.460 + }
1.461 + }
1.462 + return (0);
1.463 +}
1.464 +
1.465 +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]);
1.466 +
1.467 +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q])
1.468 +{
1.469 + unsigned char Q[LSUB_Q];
1.470 + int i;
1.471 +
1.472 + memset(Q, 0, LSUB_Q);
1.473 + for (i = LSUB_QRAW + LSUB_Q -1; i>=0; i--) {
1.474 + unsigned char data;
1.475 +
1.476 + data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f;
1.477 + if (data != 0) {
1.478 + unsigned char base = rs_sub_rw_log[data];
1.479 +
1.480 + Q[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.481 + Q[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.482 + }
1.483 + }
1.484 + return (Q[0] != 0 || Q[1] != 0);
1.485 +}
1.486 +
1.487 +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]);
1.488 +
1.489 +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P])
1.490 +{
1.491 + unsigned char P[LSUB_P];
1.492 + int i;
1.493 +
1.494 + memset(P, 0, LSUB_P);
1.495 + for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i>=0; i--) {
1.496 + unsigned char data;
1.497 +
1.498 + data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f;
1.499 + if (data != 0) {
1.500 + unsigned char base = rs_sub_rw_log[data];
1.501 +
1.502 + P[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.503 + P[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.504 + P[2] ^= rs_sub_rw_alog[(base+2*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.505 + P[3] ^= rs_sub_rw_alog[(base+3*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.506 + }
1.507 + }
1.508 + return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0);
1.509 +}
1.510 +
1.511 +/* Layer 1 CIRC en/decoder */
1.512 +#define MAX_L1_DEL1 2
1.513 +static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW];
1.514 +#define MAX_L1_DEL2 108
1.515 +static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q];
1.516 +#define MAX_L1_DEL3 1
1.517 +static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P];
1.518 +static unsigned l1_del_index;
1.519 +
1.520 +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR],
1.521 + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.522 + int delay1, int delay2, int delay3, int permute)
1.523 +{
1.524 + int i;
1.525 +
1.526 + for (i = 0; i < FRAMES_PER_SECTOR; i++) {
1.527 + int j;
1.528 + unsigned char t;
1.529 +
1.530 + if (in != out)
1.531 + memcpy(out, in, L1_RAW);
1.532 +
1.533 + if (delay1) {
1.534 + /* shift through delay line 1 */
1.535 + for (j = 0; j < L1_RAW; j++) {
1.536 + if (((j/4) % MAX_L1_DEL1) == 0) {
1.537 + t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
1.538 + l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j];
1.539 + out[j] = t;
1.540 + }
1.541 + }
1.542 + }
1.543 +
1.544 + if (permute) {
1.545 + /* permute */
1.546 + t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18];
1.547 + out[18] = out[6]; out [6] = t;
1.548 + t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19];
1.549 + out[19] = out[7]; out [7] = t;
1.550 + t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14];
1.551 + out[14] = out[12]; out [12] = t;
1.552 + t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15];
1.553 + out[15] = out[13]; out [13] = t;
1.554 + }
1.555 +
1.556 + /* build Q parity */
1.557 + encode_L1_Q(out);
1.558 +
1.559 + if (delay2) {
1.560 + /* shift through delay line 2 */
1.561 + for (j = 0; j < L1_RAW+L1_Q; j++) {
1.562 + if (j != 0) {
1.563 + t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
1.564 + l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j];
1.565 + out[j] = t;
1.566 + }
1.567 + }
1.568 + }
1.569 +
1.570 + /* build P parity */
1.571 + encode_L1_P(out);
1.572 +
1.573 + if (delay3) {
1.574 + /* shift through delay line 3 */
1.575 + for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
1.576 + if (((j) & MAX_L1_DEL3) == 0) {
1.577 + t = l1_delay_line3[0][j];
1.578 + l1_delay_line3[0][j] = out[j];
1.579 + out[j] = t;
1.580 + }
1.581 + }
1.582 + }
1.583 +
1.584 + /* invert Q and P parity */
1.585 + for (j = 0; j < L1_Q; j++)
1.586 + out[j+12] = ~out[j+12];
1.587 + for (j = 0; j < L1_P; j++)
1.588 + out[j+28] = ~out[j+28];
1.589 +
1.590 + l1_del_index++;
1.591 + out += L1_RAW+L1_Q+L1_P;
1.592 + in += L1_RAW;
1.593 + }
1.594 + return (0);
1.595 +}
1.596 +
1.597 +int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.598 + unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
1.599 + int delay1, int delay2, int delay3, int permute)
1.600 +{
1.601 + int i;
1.602 +
1.603 + for (i = 0; i < FRAMES_PER_SECTOR; i++) {
1.604 + int j;
1.605 + unsigned char t;
1.606 +
1.607 + if (delay3) {
1.608 + /* shift through delay line 3 */
1.609 + for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
1.610 + if (((j) & MAX_L1_DEL3) != 0) {
1.611 + t = l1_delay_line3[0][j];
1.612 + l1_delay_line3[0][j] = in[j];
1.613 + in[j] = t;
1.614 + }
1.615 + }
1.616 + }
1.617 +
1.618 + /* invert Q and P parity */
1.619 + for (j = 0; j < L1_Q; j++)
1.620 + in[j+12] = ~in[j+12];
1.621 + for (j = 0; j < L1_P; j++)
1.622 + in[j+28] = ~in[j+28];
1.623 +
1.624 + /* build P parity */
1.625 + decode_L1_P(in);
1.626 +
1.627 + if (delay2) {
1.628 + /* shift through delay line 2 */
1.629 + for (j = 0; j < L1_RAW+L1_Q; j++) {
1.630 + if (j != L1_RAW+L1_Q-1) {
1.631 + t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
1.632 + l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j];
1.633 + in[j] = t;
1.634 + }
1.635 + }
1.636 + }
1.637 +
1.638 + /* build Q parity */
1.639 + decode_L1_Q(in);
1.640 +
1.641 + if (permute) {
1.642 + /* permute */
1.643 + t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10];
1.644 + in[10] = in[8]; in [8] = t;
1.645 + t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11];
1.646 + in[11] = in[9]; in [9] = t;
1.647 + t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20];
1.648 + in[20] = in[16]; in [16] = t;
1.649 + t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21];
1.650 + in[21] = in[17]; in [17] = t;
1.651 + }
1.652 +
1.653 + if (delay1) {
1.654 + /* shift through delay line 1 */
1.655 + for (j = 0; j < L1_RAW; j++) {
1.656 + if (((j/4) % MAX_L1_DEL1) != 0) {
1.657 + t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
1.658 + l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j];
1.659 + in[j] = t;
1.660 + }
1.661 + }
1.662 + }
1.663 +
1.664 + if (in != out)
1.665 + memcpy(out, in, (L1_RAW));
1.666 +
1.667 + l1_del_index++;
1.668 + in += L1_RAW+L1_Q+L1_P;
1.669 + out += L1_RAW;
1.670 + }
1.671 + return (0);
1.672 +}
1.673 +
1.674 +int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)],
1.675 + unsigned char out[L2_RAW])
1.676 +{
1.677 + return (0);
1.678 +}
1.679 +
1.680 +
1.681 +
1.682 +#define MAX_SUB_DEL 8
1.683 +static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P];
1.684 +static unsigned sub_del_index;
1.685 +
1.686 +/* R-W Subchannel en/decoder */
1.687 +
1.688 +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
1.689 + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
1.690 + int delay1, int permute)
1.691 +{
1.692 + int i;
1.693 +
1.694 + if (in == out) return -1;
1.695 +
1.696 + for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
1.697 + int j;
1.698 + unsigned char t;
1.699 +
1.700 + memcpy(out, in, (LSUB_RAW));
1.701 +
1.702 + /* build Q parity */
1.703 + encode_LSUB_Q(out);
1.704 +
1.705 + /* build P parity */
1.706 + encode_LSUB_P(out);
1.707 +
1.708 + if (permute) {
1.709 + /* permute */
1.710 + t = out[1]; out[1] = out[18]; out[18] = t;
1.711 + t = out[2]; out[2] = out[ 5]; out[ 5] = t;
1.712 + t = out[3]; out[3] = out[23]; out[23] = t;
1.713 + }
1.714 +
1.715 + if (delay1) {
1.716 + /* shift through delay_line */
1.717 + for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
1.718 + if ((j % MAX_SUB_DEL) != 0) {
1.719 + t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
1.720 + sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j];
1.721 + out[j] = t;
1.722 + }
1.723 + }
1.724 + }
1.725 + sub_del_index++;
1.726 + out += LSUB_RAW+LSUB_Q+LSUB_P;
1.727 + in += LSUB_RAW;
1.728 + }
1.729 + return (0);
1.730 +}
1.731 +
1.732 +int do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
1.733 + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
1.734 + int delay1, int permute)
1.735 +{
1.736 + int i;
1.737 +
1.738 + if (in == out) return -1;
1.739 +
1.740 + for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
1.741 + int j;
1.742 + unsigned char t;
1.743 +
1.744 + if (delay1) {
1.745 + /* shift through delay_line */
1.746 + for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
1.747 + if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) {
1.748 + t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
1.749 + sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j];
1.750 + in[j] = t;
1.751 + }
1.752 + }
1.753 + }
1.754 +
1.755 + if (permute) {
1.756 + /* permute */
1.757 + t = in[1]; in[1] = in[18]; in[18] = t;
1.758 + t = in[2]; in[2] = in[ 5]; in[ 5] = t;
1.759 + t = in[3]; in[3] = in[23]; in[23] = t;
1.760 + }
1.761 +
1.762 + /* build P parity */
1.763 + decode_LSUB_P(in);
1.764 +
1.765 + /* build Q parity */
1.766 + decode_LSUB_Q(in);
1.767 +
1.768 + memcpy(out, in, LSUB_QRAW);
1.769 + memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW);
1.770 +
1.771 + sub_del_index++;
1.772 + in += LSUB_RAW+LSUB_Q+LSUB_P;
1.773 + out += LSUB_RAW;
1.774 + }
1.775 + return (0);
1.776 +}
1.777 +
1.778 +static int sectortype = MODE_0;
1.779 +
1.780 +int get_sector_type(void);
1.781 +
1.782 +int get_sector_type()
1.783 +{
1.784 + return (sectortype);
1.785 +}
1.786 +
1.787 +int set_sector_type(int st);
1.788 +
1.789 +int set_sector_type(int st)
1.790 +{
1.791 + switch(st) {
1.792 +
1.793 + case MODE_0:
1.794 + case MODE_1:
1.795 + case MODE_2:
1.796 + case MODE_2_FORM_1:
1.797 + case MODE_2_FORM_2:
1.798 + sectortype = st;
1.799 + return 0;
1.800 + default:
1.801 + return -1;
1.802 + }
1.803 +}
1.804 +
.