Search
lxdream.org :: lxdream/src/gdrom/edc_ecc.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/edc_ecc.c
changeset 644:ccae4bfa5f82
next669:ab344e42bca9
author nkeynes
date Sun Mar 02 11:38:08 2008 +0000 (12 years ago)
permissions -rw-r--r--
last change Bug #59: Add provisional support for all CD read modes (not validated)
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/gdrom/edc_ecc.c Sun Mar 02 11:38:08 2008 +0000
1.3 @@ -0,0 +1,979 @@
1.4 +/*
1.5 + * Note: This file has been extracted from crkit 1.1.6 and modified to work within
1.6 + * lxdream, but is otherwise unchanged.
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 "gdrom.h"
1.50 +#include "ecc.h"
1.51 +
1.52 +#define xaligned(a, s) ((((uintptr_t)(a)) & (s)) == 0 )
1.53 +
1.54 +/* these prototypes will become public when the function are implemented */
1.55 +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)],
1.56 + unsigned char out[L2_RAW]);
1.57 +
1.58 +static int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.59 + unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
1.60 + int delay1, int delay2, int delay3, int scramble);
1.61 +
1.62 +
1.63 +/* ------------- tables generated by gen_encodes --------------*/
1.64 +
1.65 +#include "edc_scramble.h"
1.66 +
1.67 +#define DO4(a) a;a;a;a;
1.68 +#define DO13(a) a;a;a;a;a;a;a;a;a;a;a;a;a;
1.69 +
1.70 +/*
1.71 + * Scrambles 2352 - 12 = 2340 bytes
1.72 + */
1.73 +int scramble_L2(unsigned char *inout);
1.74 +
1.75 +int scramble_L2(unsigned char *inout)
1.76 +{
1.77 +#ifndef EDC_SCRAMBLE_NOSWAP
1.78 + unsigned int *f = (unsigned int *)inout;
1.79 +#endif
1.80 +
1.81 + if (!xaligned(inout + 12, sizeof(uint32_t)-1)) {
1.82 +
1.83 + uint8_t *r = inout + 12;
1.84 + const uint8_t *s = yellowbook_scrambler;
1.85 + register int i;
1.86 +
1.87 + for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(unsigned char)/4; --i >= 0;) {
1.88 + DO4(*r++ ^= *s++);
1.89 + }
1.90 +
1.91 + } else {
1.92 + uint32_t *r = (uint32_t *) (inout + 12);
1.93 + const uint32_t *s = yellowbook_scrambler_uint32;
1.94 + register int i;
1.95 +
1.96 + for (i = (L2_RAW + L2_Q + L2_P +16)/sizeof(uint32_t)/13; --i >= 0;) {
1.97 + DO13(*r++ ^= *s++);
1.98 + }
1.99 + }
1.100 +
1.101 +#ifndef EDC_SCRAMBLE_NOSWAP
1.102 +
1.103 + /* generate F1 frames */
1.104 + for (i = 2352/sizeof(unsigned int); i; i--) {
1.105 + *f++ = ((*f & 0xff00ff00UL) >> 8) | ((*f & 0x00ff00ffUL) << 8);
1.106 + }
1.107 +#endif
1.108 +
1.109 + return (0);
1.110 +}
1.111 +
1.112 +#include "edc_l2sq.h"
1.113 +
1.114 +static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q]);
1.115 +
1.116 +static int encode_L2_Q(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P + L2_Q])
1.117 +{
1.118 + unsigned char *dps;
1.119 + unsigned char *dp;
1.120 + unsigned char *Q;
1.121 + register int i;
1.122 + int j;
1.123 +
1.124 + Q = inout + 4 + L2_RAW + 4 + 8 + L2_P;
1.125 +
1.126 + dps = inout;
1.127 + for (j = 0; j < 26; j++) {
1.128 + register unsigned short a;
1.129 + register unsigned short b;
1.130 + a = b = 0;
1.131 +
1.132 + dp = dps;
1.133 + for (i = 0; i < 43; i++) {
1.134 +
1.135 + /* LSB */
1.136 + a ^= L2sq[i][*dp++];
1.137 +
1.138 + /* MSB */
1.139 + b ^= L2sq[i][*dp];
1.140 +
1.141 + dp += 2*44-1;
1.142 + if (dp >= &inout[(4 + L2_RAW + 4 + 8 + L2_P)]) {
1.143 + dp -= (4 + L2_RAW + 4 + 8 + L2_P);
1.144 + }
1.145 + }
1.146 + Q[0] = a >> 8;
1.147 + Q[26*2] = a;
1.148 + Q[1] = b >> 8;
1.149 + Q[26*2+1] = b;
1.150 +
1.151 + Q += 2;
1.152 + dps += 2*43;
1.153 + }
1.154 + return (0);
1.155 +}
1.156 +
1.157 +static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P]);
1.158 +
1.159 +static int encode_L2_P(unsigned char inout[4 + L2_RAW + 4 + 8 + L2_P])
1.160 +{
1.161 + unsigned char *dp;
1.162 + unsigned char *P;
1.163 + register int i;
1.164 + int j;
1.165 +
1.166 + P = inout + 4 + L2_RAW + 4 + 8;
1.167 +
1.168 + for (j = 0; j < 43; j++) {
1.169 + register unsigned short a;
1.170 + register unsigned short b;
1.171 +
1.172 + a = b = 0;
1.173 + dp = inout;
1.174 + for (i = 19; i < 43; i++) {
1.175 +
1.176 + /* LSB */
1.177 + a ^= L2sq[i][*dp++];
1.178 +
1.179 + /* MSB */
1.180 + b ^= L2sq[i][*dp];
1.181 +
1.182 + dp += 2*43 -1;
1.183 + }
1.184 + P[0] = a >> 8;
1.185 + P[43*2] = a;
1.186 + P[1] = b >> 8;
1.187 + P[43*2+1] = b;
1.188 +
1.189 + P += 2;
1.190 + inout += 2;
1.191 + }
1.192 + return (0);
1.193 +}
1.194 +
1.195 +static unsigned char bin2bcd(unsigned p);
1.196 +
1.197 +static unsigned char bin2bcd(unsigned p)
1.198 +{
1.199 + return ((p/10)<<4)|(p%10);
1.200 +}
1.201 +
1.202 +int cd_build_address(unsigned char inout[], int sectortype, unsigned address)
1.203 +{
1.204 + inout[12] = bin2bcd(address / (60*75));
1.205 + inout[13] = bin2bcd((address / 75) % 60);
1.206 + inout[14] = bin2bcd(address % 75);
1.207 + if (sectortype == MODE_0)
1.208 + inout[15] = 0;
1.209 + else if (sectortype == MODE_1)
1.210 + inout[15] = 1;
1.211 + else if (sectortype == MODE_2)
1.212 + inout[15] = 2;
1.213 + else if (sectortype == MODE_2_FORM_1)
1.214 + inout[15] = 2;
1.215 + else if (sectortype == MODE_2_FORM_2)
1.216 + inout[15] = 2;
1.217 + else
1.218 + return (-1);
1.219 + return (0);
1.220 +}
1.221 +
1.222 +#include "edc_crctable.h"
1.223 +
1.224 +/*
1.225 + * Called with 2064, 2056 or 2332 byte difference - all dividable by 4.
1.226 + */
1.227 +unsigned int build_edc(unsigned char inout[], int from, int upto);
1.228 +
1.229 +unsigned int build_edc(unsigned char inout[], int from, int upto)
1.230 +{
1.231 + unsigned char *p = inout+from;
1.232 + unsigned int result = 0;
1.233 +
1.234 + upto -= from-1;
1.235 + upto /= 4;
1.236 + while (--upto >= 0) {
1.237 + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
1.238 + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
1.239 + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
1.240 + result = EDC_crctable[(result ^ *p++) & 0xffL] ^ (result >> 8);
1.241 + }
1.242 + return (result);
1.243 +}
1.244 +
1.245 +/* Layer 2 Product code en/decoder */
1.246 +int do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)],
1.247 + int sectortype, unsigned address);
1.248 +
1.249 +int
1.250 +do_encode_L2(unsigned char inout[(12 + 4 + L2_RAW+4+8+L2_Q+L2_P)],
1.251 + int sectortype, unsigned address)
1.252 +{
1.253 + unsigned int result;
1.254 +
1.255 +/* SYNCPATTERN "\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" */
1.256 +#define SYNCPATTERN "\000\377\377\377\377\377\377\377\377\377\377"
1.257 +
1.258 + /* supply initial sync pattern */
1.259 + memcpy(inout, SYNCPATTERN, sizeof(SYNCPATTERN));
1.260 +
1.261 + if (sectortype == MODE_0) {
1.262 + memset(inout + sizeof(SYNCPATTERN), 0, 4 + L2_RAW + 12 + L2_P + L2_Q);
1.263 + cd_build_address(inout, sectortype, address);
1.264 + return (0);
1.265 + }
1.266 +
1.267 + switch (sectortype) {
1.268 +
1.269 + case MODE_1:
1.270 + cd_build_address(inout, sectortype, address);
1.271 + result = build_edc(inout, 0, 16+2048-1);
1.272 + inout[2064+0] = result >> 0L;
1.273 + inout[2064+1] = result >> 8L;
1.274 + inout[2064+2] = result >> 16L;
1.275 + inout[2064+3] = result >> 24L;
1.276 + memset(inout+2064+4, 0, 8);
1.277 + encode_L2_P(inout+12);
1.278 + encode_L2_Q(inout+12);
1.279 + break;
1.280 + case MODE_2:
1.281 + cd_build_address(inout, sectortype, address);
1.282 + break;
1.283 + case MODE_2_FORM_1:
1.284 + result = build_edc(inout, 16, 16+8+2048-1);
1.285 + inout[2072+0] = result >> 0L;
1.286 + inout[2072+1] = result >> 8L;
1.287 + inout[2072+2] = result >> 16L;
1.288 + inout[2072+3] = result >> 24L;
1.289 +
1.290 + /* clear header for P/Q parity calculation */
1.291 + inout[12] = 0;
1.292 + inout[12+1] = 0;
1.293 + inout[12+2] = 0;
1.294 + inout[12+3] = 0;
1.295 + encode_L2_P(inout+12);
1.296 + encode_L2_Q(inout+12);
1.297 + cd_build_address(inout, sectortype, address);
1.298 + break;
1.299 + case MODE_2_FORM_2:
1.300 + cd_build_address(inout, sectortype, address);
1.301 + result = build_edc(inout, 16, 16+8+2324-1);
1.302 + inout[2348+0] = result >> 0L;
1.303 + inout[2348+1] = result >> 8L;
1.304 + inout[2348+2] = result >> 16L;
1.305 + inout[2348+3] = result >> 24L;
1.306 + break;
1.307 + default:
1.308 + return (-1);
1.309 + }
1.310 +
1.311 + return (0);
1.312 +}
1.313 +
1.314 +
1.315 +/*--------------------------------------------------------------------------*/
1.316 +#include "edc_encoder.h"
1.317 +
1.318 +static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q]);
1.319 +
1.320 +static int encode_L1_Q(unsigned char inout[L1_RAW + L1_Q])
1.321 +{
1.322 + unsigned char *Q;
1.323 + int i;
1.324 +
1.325 + memmove(inout+L1_RAW/2+L1_Q, inout+L1_RAW/2, L1_RAW/2);
1.326 + Q = inout + L1_RAW/2;
1.327 +
1.328 + memset(Q, 0, L1_Q);
1.329 + for (i = 0; i < L1_RAW + L1_Q; i++) {
1.330 + unsigned char data;
1.331 +
1.332 + if (i == L1_RAW/2) i += L1_Q;
1.333 + data = inout[i];
1.334 + if (data != 0) {
1.335 + unsigned char base = rs_l12_log[data];
1.336 +
1.337 + Q[0] ^= rs_l12_alog[(base+AQ[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.338 + Q[1] ^= rs_l12_alog[(base+AQ[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.339 + Q[2] ^= rs_l12_alog[(base+AQ[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.340 + Q[3] ^= rs_l12_alog[(base+AQ[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.341 + }
1.342 + }
1.343 + return (0);
1.344 +}
1.345 +
1.346 +static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P]);
1.347 +
1.348 +static int encode_L1_P(unsigned char inout[L1_RAW + L1_Q + L1_P])
1.349 +{
1.350 + unsigned char *P;
1.351 + int i;
1.352 +
1.353 + P = inout + L1_RAW + L1_Q;
1.354 +
1.355 + memset(P, 0, L1_P);
1.356 + for (i = 0; i < L2_RAW + L2_Q + L2_P; i++) {
1.357 + unsigned char data;
1.358 +
1.359 + data = inout[i];
1.360 + if (data != 0) {
1.361 + unsigned char base = rs_l12_log[data];
1.362 +
1.363 + P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.364 + P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.365 + P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.366 + P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
1.367 + }
1.368 + }
1.369 + return (0);
1.370 +}
1.371 +
1.372 +static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q]);
1.373 +
1.374 +static int decode_L1_Q(unsigned char inout[L1_RAW + L1_Q])
1.375 +{
1.376 + return (0);
1.377 +}
1.378 +
1.379 +static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P]);
1.380 +
1.381 +static int decode_L1_P(unsigned char in[L1_RAW + L1_Q + L1_P])
1.382 +{
1.383 + return (0);
1.384 +}
1.385 +
1.386 +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q]);
1.387 +
1.388 +int decode_L2_Q(unsigned char inout[4 + L2_RAW + 12 + L2_Q])
1.389 +{
1.390 + return (0);
1.391 +}
1.392 +
1.393 +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P]);
1.394 +
1.395 +int decode_L2_P(unsigned char inout[4 + L2_RAW + 12 + L2_Q + L2_P])
1.396 +{
1.397 + return (0);
1.398 +}
1.399 +
1.400 +static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q]);
1.401 +
1.402 +static int encode_LSUB_Q(unsigned char inout[LSUB_RAW + LSUB_Q])
1.403 +{
1.404 + unsigned char *Q;
1.405 + int i;
1.406 +
1.407 + memmove(inout+LSUB_QRAW+LSUB_Q, inout+LSUB_QRAW, LSUB_RAW-LSUB_QRAW);
1.408 + Q = inout + LSUB_QRAW;
1.409 +
1.410 + memset(Q, 0, LSUB_Q);
1.411 +
1.412 + for (i = 0; i < LSUB_QRAW; i++) {
1.413 + unsigned char data;
1.414 +
1.415 + data = inout[i] & 0x3f;
1.416 + if (data != 0) {
1.417 + unsigned char base = rs_sub_rw_log[data];
1.418 +
1.419 + Q[0] ^= rs_sub_rw_alog[(base+SQ[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.420 + Q[1] ^= rs_sub_rw_alog[(base+SQ[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.421 + }
1.422 + }
1.423 + return (0);
1.424 +}
1.425 +
1.426 +
1.427 +static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]);
1.428 +
1.429 +static int encode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P])
1.430 +{
1.431 + unsigned char *P;
1.432 + int i;
1.433 +
1.434 + P = inout + LSUB_RAW + LSUB_Q;
1.435 +
1.436 + memset(P, 0, LSUB_P);
1.437 + for (i = 0; i < LSUB_RAW + LSUB_Q; i++) {
1.438 + unsigned char data;
1.439 +
1.440 + data = inout[i] & 0x3f;
1.441 + if (data != 0) {
1.442 + unsigned char base = rs_sub_rw_log[data];
1.443 +
1.444 + P[0] ^= rs_sub_rw_alog[(base+SP[0][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.445 + P[1] ^= rs_sub_rw_alog[(base+SP[1][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.446 + P[2] ^= rs_sub_rw_alog[(base+SP[2][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.447 + P[3] ^= rs_sub_rw_alog[(base+SP[3][i]) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.448 + }
1.449 + }
1.450 + return (0);
1.451 +}
1.452 +
1.453 +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q]);
1.454 +
1.455 +int decode_LSUB_Q(unsigned char inout[LSUB_QRAW + LSUB_Q])
1.456 +{
1.457 + unsigned char Q[LSUB_Q];
1.458 + int i;
1.459 +
1.460 + memset(Q, 0, LSUB_Q);
1.461 + for (i = LSUB_QRAW + LSUB_Q -1; i>=0; i--) {
1.462 + unsigned char data;
1.463 +
1.464 + data = inout[LSUB_QRAW + LSUB_Q -1 -i] & 0x3f;
1.465 + if (data != 0) {
1.466 + unsigned char base = rs_sub_rw_log[data];
1.467 +
1.468 + Q[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.469 + Q[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.470 + }
1.471 + }
1.472 + return (Q[0] != 0 || Q[1] != 0);
1.473 +}
1.474 +
1.475 +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P]);
1.476 +
1.477 +int decode_LSUB_P(unsigned char inout[LSUB_RAW + LSUB_Q + LSUB_P])
1.478 +{
1.479 + unsigned char P[LSUB_P];
1.480 + int i;
1.481 +
1.482 + memset(P, 0, LSUB_P);
1.483 + for (i = LSUB_RAW + LSUB_Q + LSUB_P-1; i>=0; i--) {
1.484 + unsigned char data;
1.485 +
1.486 + data = inout[LSUB_RAW + LSUB_Q + LSUB_P -1 -i] & 0x3f;
1.487 + if (data != 0) {
1.488 + unsigned char base = rs_sub_rw_log[data];
1.489 +
1.490 + P[0] ^= rs_sub_rw_alog[(base+0*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.491 + P[1] ^= rs_sub_rw_alog[(base+1*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.492 + P[2] ^= rs_sub_rw_alog[(base+2*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.493 + P[3] ^= rs_sub_rw_alog[(base+3*i) % (unsigned)((1 << RS_SUB_RW_BITS)-1)];
1.494 + }
1.495 + }
1.496 + return (P[0] != 0 || P[1] != 0 || P[2] != 0 || P[3] != 0);
1.497 +}
1.498 +
1.499 +/* Layer 1 CIRC en/decoder */
1.500 +#define MAX_L1_DEL1 2
1.501 +static unsigned char l1_delay_line1[MAX_L1_DEL1][L1_RAW];
1.502 +#define MAX_L1_DEL2 108
1.503 +static unsigned char l1_delay_line2[MAX_L1_DEL2][L1_RAW+L1_Q];
1.504 +#define MAX_L1_DEL3 1
1.505 +static unsigned char l1_delay_line3[MAX_L1_DEL3][L1_RAW+L1_Q+L1_P];
1.506 +static unsigned l1_del_index;
1.507 +
1.508 +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR],
1.509 + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.510 + int delay1, int delay2, int delay3, int permute);
1.511 +
1.512 +int do_encode_L1(unsigned char in[L1_RAW*FRAMES_PER_SECTOR],
1.513 + unsigned char out[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.514 + int delay1, int delay2, int delay3, int permute)
1.515 +{
1.516 + int i;
1.517 +
1.518 + for (i = 0; i < FRAMES_PER_SECTOR; i++) {
1.519 + int j;
1.520 + unsigned char t;
1.521 +
1.522 + if (in != out)
1.523 + memcpy(out, in, L1_RAW);
1.524 +
1.525 + if (delay1) {
1.526 + /* shift through delay line 1 */
1.527 + for (j = 0; j < L1_RAW; j++) {
1.528 + if (((j/4) % MAX_L1_DEL1) == 0) {
1.529 + t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
1.530 + l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = out[j];
1.531 + out[j] = t;
1.532 + }
1.533 + }
1.534 + }
1.535 +
1.536 + if (permute) {
1.537 + /* permute */
1.538 + t = out[2]; out[2] = out[8]; out[8] = out[10]; out[10] = out[18];
1.539 + out[18] = out[6]; out [6] = t;
1.540 + t = out[3]; out[3] = out[9]; out[9] = out[11]; out[11] = out[19];
1.541 + out[19] = out[7]; out [7] = t;
1.542 + t = out[4]; out[4] = out[16]; out[16] = out[20]; out[20] = out[14];
1.543 + out[14] = out[12]; out [12] = t;
1.544 + t = out[5]; out[5] = out[17]; out[17] = out[21]; out[21] = out[15];
1.545 + out[15] = out[13]; out [13] = t;
1.546 + }
1.547 +
1.548 + /* build Q parity */
1.549 + encode_L1_Q(out);
1.550 +
1.551 + if (delay2) {
1.552 + /* shift through delay line 2 */
1.553 + for (j = 0; j < L1_RAW+L1_Q; j++) {
1.554 + if (j != 0) {
1.555 + t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
1.556 + l1_delay_line2[(l1_del_index + j*4) % MAX_L1_DEL2][j] = out[j];
1.557 + out[j] = t;
1.558 + }
1.559 + }
1.560 + }
1.561 +
1.562 + /* build P parity */
1.563 + encode_L1_P(out);
1.564 +
1.565 + if (delay3) {
1.566 + /* shift through delay line 3 */
1.567 + for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
1.568 + if (((j) & MAX_L1_DEL3) == 0) {
1.569 + t = l1_delay_line3[0][j];
1.570 + l1_delay_line3[0][j] = out[j];
1.571 + out[j] = t;
1.572 + }
1.573 + }
1.574 + }
1.575 +
1.576 + /* invert Q and P parity */
1.577 + for (j = 0; j < L1_Q; j++)
1.578 + out[j+12] = ~out[j+12];
1.579 + for (j = 0; j < L1_P; j++)
1.580 + out[j+28] = ~out[j+28];
1.581 +
1.582 + l1_del_index++;
1.583 + out += L1_RAW+L1_Q+L1_P;
1.584 + in += L1_RAW;
1.585 + }
1.586 + return (0);
1.587 +}
1.588 +
1.589 +static
1.590 +int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.591 + unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
1.592 + int delay1, int delay2, int delay3, int permute);
1.593 +
1.594 +static /* XXX should be non static XXX*/
1.595 +
1.596 +int do_decode_L1(unsigned char in[(L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR],
1.597 + unsigned char out[L1_RAW*FRAMES_PER_SECTOR],
1.598 + int delay1, int delay2, int delay3, int permute)
1.599 +{
1.600 + int i;
1.601 +
1.602 + for (i = 0; i < FRAMES_PER_SECTOR; i++) {
1.603 + int j;
1.604 + unsigned char t;
1.605 +
1.606 + if (delay3) {
1.607 + /* shift through delay line 3 */
1.608 + for (j = 0; j < L1_RAW+L1_Q+L1_P; j++) {
1.609 + if (((j) & MAX_L1_DEL3) != 0) {
1.610 + t = l1_delay_line3[0][j];
1.611 + l1_delay_line3[0][j] = in[j];
1.612 + in[j] = t;
1.613 + }
1.614 + }
1.615 + }
1.616 +
1.617 + /* invert Q and P parity */
1.618 + for (j = 0; j < L1_Q; j++)
1.619 + in[j+12] = ~in[j+12];
1.620 + for (j = 0; j < L1_P; j++)
1.621 + in[j+28] = ~in[j+28];
1.622 +
1.623 + /* build P parity */
1.624 + decode_L1_P(in);
1.625 +
1.626 + if (delay2) {
1.627 + /* shift through delay line 2 */
1.628 + for (j = 0; j < L1_RAW+L1_Q; j++) {
1.629 + if (j != L1_RAW+L1_Q-1) {
1.630 + t = l1_delay_line2[(l1_del_index) % MAX_L1_DEL2][j];
1.631 + l1_delay_line2[(l1_del_index + (MAX_L1_DEL2 - j*4)) % MAX_L1_DEL2][j] = in[j];
1.632 + in[j] = t;
1.633 + }
1.634 + }
1.635 + }
1.636 +
1.637 + /* build Q parity */
1.638 + decode_L1_Q(in);
1.639 +
1.640 + if (permute) {
1.641 + /* permute */
1.642 + t = in[2]; in[2] = in[6]; in[6] = in[18]; in[18] = in[10];
1.643 + in[10] = in[8]; in [8] = t;
1.644 + t = in[3]; in[3] = in[7]; in[7] = in[19]; in[19] = in[11];
1.645 + in[11] = in[9]; in [9] = t;
1.646 + t = in[4]; in[4] = in[12]; in[12] = in[14]; in[14] = in[20];
1.647 + in[20] = in[16]; in [16] = t;
1.648 + t = in[5]; in[5] = in[13]; in[13] = in[15]; in[15] = in[21];
1.649 + in[21] = in[17]; in [17] = t;
1.650 + }
1.651 +
1.652 + if (delay1) {
1.653 + /* shift through delay line 1 */
1.654 + for (j = 0; j < L1_RAW; j++) {
1.655 + if (((j/4) % MAX_L1_DEL1) != 0) {
1.656 + t = l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j];
1.657 + l1_delay_line1[l1_del_index % (MAX_L1_DEL1)][j] = in[j];
1.658 + in[j] = t;
1.659 + }
1.660 + }
1.661 + }
1.662 +
1.663 + if (in != out)
1.664 + memcpy(out, in, (L1_RAW));
1.665 +
1.666 + l1_del_index++;
1.667 + in += L1_RAW+L1_Q+L1_P;
1.668 + out += L1_RAW;
1.669 + }
1.670 + return (0);
1.671 +}
1.672 +
1.673 +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)],
1.674 + unsigned char out[L2_RAW]);
1.675 +
1.676 +static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)],
1.677 + unsigned char out[L2_RAW])
1.678 +{
1.679 + return (0);
1.680 +}
1.681 +
1.682 +
1.683 +
1.684 +#define MAX_SUB_DEL 8
1.685 +static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P];
1.686 +static unsigned sub_del_index;
1.687 +
1.688 +/* R-W Subchannel en/decoder */
1.689 +
1.690 +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
1.691 + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
1.692 + int delay1, int permute);
1.693 +
1.694 +int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
1.695 + unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
1.696 + int delay1, int permute)
1.697 +{
1.698 + int i;
1.699 +
1.700 + if (in == out) return -1;
1.701 +
1.702 + for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
1.703 + int j;
1.704 + unsigned char t;
1.705 +
1.706 + memcpy(out, in, (LSUB_RAW));
1.707 +
1.708 + /* build Q parity */
1.709 + encode_LSUB_Q(out);
1.710 +
1.711 + /* build P parity */
1.712 + encode_LSUB_P(out);
1.713 +
1.714 + if (permute) {
1.715 + /* permute */
1.716 + t = out[1]; out[1] = out[18]; out[18] = t;
1.717 + t = out[2]; out[2] = out[ 5]; out[ 5] = t;
1.718 + t = out[3]; out[3] = out[23]; out[23] = t;
1.719 + }
1.720 +
1.721 + if (delay1) {
1.722 + /* shift through delay_line */
1.723 + for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
1.724 + if ((j % MAX_SUB_DEL) != 0) {
1.725 + t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
1.726 + sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j];
1.727 + out[j] = t;
1.728 + }
1.729 + }
1.730 + }
1.731 + sub_del_index++;
1.732 + out += LSUB_RAW+LSUB_Q+LSUB_P;
1.733 + in += LSUB_RAW;
1.734 + }
1.735 + return (0);
1.736 +}
1.737 +
1.738 +int
1.739 +do_decode_sub(
1.740 + unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
1.741 + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
1.742 + int delay1, int permute);
1.743 +
1.744 +int
1.745 +do_decode_sub(unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME],
1.746 + unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME],
1.747 + int delay1, int permute)
1.748 +{
1.749 + int i;
1.750 +
1.751 + if (in == out) return -1;
1.752 +
1.753 + for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) {
1.754 + int j;
1.755 + unsigned char t;
1.756 +
1.757 + if (delay1) {
1.758 + /* shift through delay_line */
1.759 + for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) {
1.760 + if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) {
1.761 + t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j];
1.762 + sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j];
1.763 + in[j] = t;
1.764 + }
1.765 + }
1.766 + }
1.767 +
1.768 + if (permute) {
1.769 + /* permute */
1.770 + t = in[1]; in[1] = in[18]; in[18] = t;
1.771 + t = in[2]; in[2] = in[ 5]; in[ 5] = t;
1.772 + t = in[3]; in[3] = in[23]; in[23] = t;
1.773 + }
1.774 +
1.775 + /* build P parity */
1.776 + decode_LSUB_P(in);
1.777 +
1.778 + /* build Q parity */
1.779 + decode_LSUB_Q(in);
1.780 +
1.781 + memcpy(out, in, LSUB_QRAW);
1.782 + memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW);
1.783 +
1.784 + sub_del_index++;
1.785 + in += LSUB_RAW+LSUB_Q+LSUB_P;
1.786 + out += LSUB_RAW;
1.787 + }
1.788 + return (0);
1.789 +}
1.790 +
1.791 +static int sectortype = MODE_0;
1.792 +
1.793 +int get_sector_type(void);
1.794 +
1.795 +int get_sector_type()
1.796 +{
1.797 + return (sectortype);
1.798 +}
1.799 +
1.800 +int set_sector_type(int st);
1.801 +
1.802 +int set_sector_type(int st)
1.803 +{
1.804 + switch(st) {
1.805 +
1.806 + case MODE_0:
1.807 + case MODE_1:
1.808 + case MODE_2:
1.809 + case MODE_2_FORM_1:
1.810 + case MODE_2_FORM_2:
1.811 + sectortype = st;
1.812 + return 0;
1.813 + default:
1.814 + return -1;
1.815 + }
1.816 +}
1.817 +
1.818 +/* ------------- --------------*/
1.819 +#ifdef MAIN
1.820 +
1.821 +#define DO_L1 1
1.822 +#define DO_L2 2
1.823 +#define DO_SUB 4
1.824 +
1.825 +static const unsigned sect_size[8][2] = {
1.826 +/* nothing */
1.827 +{0,0},
1.828 +/* Layer 1 decode/encode */
1.829 +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR},
1.830 +/* Layer 2 decode/encode */
1.831 +{ 16+L2_RAW+12+L2_Q+L2_P, L2_RAW},
1.832 +/* Layer 1 and 2 decode/encode */
1.833 +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR},
1.834 +/* Subchannel decode/encode */
1.835 +{ (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
1.836 + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME},
1.837 +/* Layer 1 and subchannel decode/encode */
1.838 +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR +
1.839 + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
1.840 + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
1.841 + L1_RAW*FRAMES_PER_SECTOR},
1.842 +/* Layer 2 and subchannel decode/encode */
1.843 +{ L2_RAW+L2_Q+L2_P+
1.844 + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
1.845 + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
1.846 + L2_RAW},
1.847 +/* Layer 1, 2 and subchannel decode/encode */
1.848 +{ (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR +
1.849 + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME,
1.850 + LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME +
1.851 + L1_RAW*FRAMES_PER_SECTOR},
1.852 +};
1.853 +
1.854 +int main(int argc, char *argv[])
1.855 +{
1.856 + int encode = 1;
1.857 + int mask = DO_L2;
1.858 + FILE *infp;
1.859 + FILE *outfp;
1.860 + unsigned address = 0;
1.861 + unsigned char *l1_inbuf;
1.862 + unsigned char *l1_outbuf;
1.863 + unsigned char *l2_inbuf;
1.864 + unsigned char *l2_outbuf;
1.865 + unsigned char *sub_inbuf;
1.866 + unsigned char *sub_outbuf;
1.867 + unsigned char *last_outbuf;
1.868 + unsigned char inbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME +
1.869 + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
1.870 + unsigned char outbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME +
1.871 + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR];
1.872 + unsigned load_offset;
1.873 +
1.874 + l1_inbuf = l2_inbuf = sub_inbuf = inbuf;
1.875 + l1_outbuf = l2_outbuf = sub_outbuf = last_outbuf = outbuf;
1.876 +
1.877 + infp = fopen("sectors_in", "rb");
1.878 + outfp = fopen("sectors_out", "wb");
1.879 +
1.880 + sectortype= MODE_1;
1.881 + address = 0 + 75*2;
1.882 +
1.883 + switch (sectortype) {
1.884 +
1.885 + case MODE_1:
1.886 + case MODE_2:
1.887 + load_offset = 16;
1.888 + break;
1.889 + case MODE_2_FORM_1:
1.890 + case MODE_2_FORM_2:
1.891 + load_offset = 24;
1.892 + break;
1.893 + default:
1.894 + load_offset = 0;
1.895 + }
1.896 + while(1) {
1.897 +
1.898 + if (1 != fread(inbuf+load_offset,
1.899 + sect_size[mask][encode], 1, infp)) {
1.900 + perror("");
1.901 + break;
1.902 + }
1.903 + if (encode == 1) {
1.904 + if (mask & DO_L2) {
1.905 + switch (sectortype) {
1.906 +
1.907 + case MODE_0:
1.908 + break;
1.909 + case MODE_1:
1.910 + break;
1.911 + case MODE_2:
1.912 + if (1 !=
1.913 + fread(inbuf+load_offset+
1.914 + sect_size[mask][encode],
1.915 + 2336 - sect_size[mask][encode],
1.916 + 1, infp)) { perror(""); break; }
1.917 + break;
1.918 + case MODE_2_FORM_1:
1.919 + break;
1.920 + case MODE_2_FORM_2:
1.921 + if (1 !=
1.922 + fread(inbuf+load_offset+
1.923 + sect_size[mask][encode],
1.924 + 2324 - sect_size[mask][encode],
1.925 + 1, infp)) { perror(""); break; }
1.926 + break;
1.927 + default:
1.928 + if (1 !=
1.929 + fread(inbuf+load_offset+
1.930 + sect_size[mask][encode],
1.931 + 2448 - sect_size[mask][encode],
1.932 + 1, infp)) { perror(""); break; }
1.933 + memset(inbuf,0,16);
1.934 + /*memset(inbuf+16+2048,0,12+272);*/
1.935 + break;
1.936 + }
1.937 + do_encode_L2(l2_inbuf, MODE_1, address);
1.938 + if (0) scramble_L2(l2_inbuf);
1.939 + last_outbuf = l1_inbuf = l2_inbuf;
1.940 + l1_outbuf = l2_inbuf;
1.941 + sub_inbuf = l2_inbuf + L2_RAW;
1.942 + sub_outbuf = l2_outbuf + 12 + 4+ L2_RAW+4+ 8+ L2_Q+L2_P;
1.943 + }
1.944 + if (mask & DO_L1) {
1.945 + do_encode_L1(l1_inbuf, l1_outbuf,1,1,1,1);
1.946 + last_outbuf = l1_outbuf;
1.947 + sub_inbuf = l1_inbuf + L1_RAW*FRAMES_PER_SECTOR;
1.948 + sub_outbuf = l1_outbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR;
1.949 + }
1.950 + if (mask & DO_SUB) {
1.951 + do_encode_sub(sub_inbuf, sub_outbuf, 0, 0);
1.952 + }
1.953 + } else {
1.954 + if (mask & DO_L1) {
1.955 + do_decode_L1(l1_inbuf, l1_outbuf,1,1,1,1);
1.956 + last_outbuf = l2_inbuf = l1_outbuf;
1.957 + l2_outbuf = l1_inbuf;
1.958 + sub_inbuf = l1_inbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR;
1.959 + sub_outbuf = l1_outbuf + L1_RAW*FRAMES_PER_SECTOR;
1.960 + }
1.961 + if (mask & DO_L2) {
1.962 + do_decode_L2(l2_inbuf, l2_outbuf);
1.963 + last_outbuf = l2_outbuf;
1.964 + sub_inbuf = l2_inbuf + L2_RAW+L2_Q+L2_P;
1.965 + sub_outbuf = l2_outbuf + L2_RAW;
1.966 + }
1.967 + if (mask & DO_SUB) {
1.968 + do_decode_sub(sub_inbuf, sub_outbuf, 1, 1);
1.969 + }
1.970 + }
1.971 + if (1 != fwrite(last_outbuf, sect_size[mask][1 - encode], 1, outfp)) {
1.972 + perror("");
1.973 + break;
1.974 + }
1.975 + address++;
1.976 + }
1.977 +#if 0
1.978 + /* flush the data from the delay lines with zeroed sectors, if necessary */
1.979 +#endif
1.980 + return (0);
1.981 +}
1.982 +#endif
.