filename | src/drivers/cdrom/edc_ecc.c |
changeset | 1097:d4807997e450 |
prev | 678: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 +00001.2 +++ b/src/drivers/cdrom/edc_ecc.c Sun Jan 31 18:35:06 2010 +10001.3 @@ -0,0 +1,801 @@1.4 +/*1.5 + * Note: This file has been extracted from crkit 1.1.6 and modified to work within1.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 major1.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 you1.15 + * received this file from another source then ask the distributing person for1.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 Eissfeldt1.24 + * Copyright 2002 by Joerg Schilling1.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 modify1.33 + * it under the terms of the GNU General Public License version 21.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 of1.38 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.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 with1.42 + * this program; see the file COPYING. If not, write to the Free Software1.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 bytes1.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_NOSWAP1.93 + unsigned int *f = (unsigned int *)inout;1.94 +#endif1.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_NOSWAP1.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 +#endif1.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 + else1.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 21.513 +static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW];1.514 +#define MAX_L1_DEL2 1081.515 +static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q];1.516 +#define MAX_L1_DEL3 11.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 81.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 +
.