gen_encodes.c
上传用户:weiliju62
上传日期:2007-01-06
资源大小:619k
文件大小:8k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /* reed-solomon encoder table generator 
  2.  * Copyright 1998 by Heiko Eissfeldt
  3.  */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include "ecc.h"
  8. #define RS_L12_POLY 0x1d /* x^8 + x^4 + x^3 + x^2 + 1 */
  9. #define RS_L12_BITS 8
  10. #define RS_SUB_RW_POLY 0x03 /* x^6 + x + 1 */
  11. #define RS_SUB_RW_BITS 6
  12. #define RS_L12_PRIM_ELEM 2
  13. #define RS_SUB_RW_PRIM_ELEM 2
  14. /* define macros for polynomial arithmetic on GF(2^n) */
  15. #define add(a,b) (a ^ b)
  16. #define sub(a,b) (a ^ b)
  17. #define neg(a) (a)
  18. #define mul(a,b,m) (((a) != 0) && ((b) != 0) ? alog[(log[a] + log[b]) % (m)] : 0)
  19. #define div(a,b,m) ((a) != 0 ? alog[(log[a] - log[b] + (m)) % (m)] : 0)
  20. /* global variables */
  21. static unsigned char rs_l12_log[1 << RS_L12_BITS];
  22. static unsigned char rs_l12_alog[1 << RS_L12_BITS];
  23. static unsigned char rs_sub_rw_log[1 << RS_SUB_RW_BITS];
  24. static unsigned char rs_sub_rw_alog[1 << RS_SUB_RW_BITS];
  25. static unsigned char *log, *alog;
  26. static unsigned char mod;
  27. /* generate galois field log and antilog tables */
  28. static int init_rs_l12( void )
  29. {
  30.   unsigned char r;
  31.   int i;
  32.   r = RS_L12_PRIM_ELEM; /* primitive element a */
  33.   for (i = 1; i < (1 << RS_L12_BITS)-1; i++) {
  34.         r &= (1 << RS_L12_BITS)-1;
  35. rs_l12_alog[i] = r;
  36. rs_l12_log[r] = i;
  37. if (r & (1 << (RS_L12_BITS-1))) {
  38. r = (r << 1) ^ RS_L12_POLY;
  39. } else {
  40. r = r << 1;
  41. }
  42.   }
  43.   rs_l12_alog[0] = 1;
  44.   /* print tables on standard output */
  45.   printf("static unsigned char rs_l12_alog[%d] = {n", (1 << RS_L12_BITS)-1);
  46.   for (i = 0; i < (1 << RS_L12_BITS)-1; i++) {
  47.         printf("%2d,", rs_l12_alog[i]);
  48.   }
  49.   printf("};n");
  50.   printf("static unsigned char rs_l12_log[%d] = {n", (1 << RS_L12_BITS));
  51.   for (i = 0; i < (1 << RS_L12_BITS); i++) {
  52.         printf("%2d,", rs_l12_log[i]);
  53.   }
  54.   printf("};n");
  55.   return 0;
  56. }
  57. /* generate galois field log and antilog tables */
  58. static int init_rs_sub_rw( void )
  59. {
  60.   unsigned char r;
  61.   int i;
  62.   r = RS_SUB_RW_PRIM_ELEM; /* primitive element a */
  63.   for (i = 1; i < (1 << RS_SUB_RW_BITS)-1; i++) {
  64.         r &= (1 << RS_SUB_RW_BITS)-1;
  65. rs_sub_rw_alog[i] = r;
  66. rs_sub_rw_log[r] = i;
  67. if (r & (1 << (RS_SUB_RW_BITS-1))) {
  68. r = r << 1 ^ RS_SUB_RW_POLY;
  69. } else {
  70. r = r << 1;
  71. }
  72.   }
  73.   rs_sub_rw_alog[0] = 1;
  74.   /* print tables on standard output */
  75.   printf("static unsigned char rs_sub_rw_alog[%d] = {n", (1 << RS_SUB_RW_BITS)-1);
  76.   for (i = 0; i < (1 << RS_SUB_RW_BITS)-1; i++) {
  77.         printf("%2d,", rs_sub_rw_alog[i]);
  78.   }
  79.   printf("};n");
  80.   printf("static unsigned char rs_sub_rw_log[%d] = {n", (1 << RS_SUB_RW_BITS)-1);
  81.   for (i = 0; i < (1 << RS_SUB_RW_BITS)-1; i++) {
  82.         printf("%2d,", rs_sub_rw_log[i]);
  83.   }
  84.   printf("};n");
  85.   return 0;
  86. }
  87. static int debug = 0;
  88. #define DEBUG
  89. /* print coefficients of the current matrix */
  90. static void print_c(unsigned char **co, unsigned char datas, unsigned char parities)
  91. {
  92. #if defined(DEBUG)
  93.   unsigned char P, D;
  94.   if (debug != 1) return;
  95.   for (P = 0; P < parities; P++) {
  96.     fprintf(stderr,"%d:",P);
  97.     for (D = 0; D < datas+parities; D++) {
  98.       fprintf(stderr," %3d", co[P][D]);
  99.     }
  100.     fprintf(stderr,"n");
  101.   }
  102. #endif
  103. }
  104. /* routines to solve systems of equations */
  105. /* initialize matrix with 'parities' lines and 'datas+parities' columns
  106.  ^  ...
  107.  |  1 a^3 a^6 a^9 a^12  ...
  108.  |  1 a^2 a^4 a^6 a^8   ...
  109.  |  1 a^1 a^2 a^3 a^4   ...
  110.  |  1   1   1   1   1   ...
  111.  v  <- datas + parities  ->
  112.  */
  113. static unsigned char **init_matrix(int datas, int parities, 
  114.    unsigned char alog[], unsigned char mod)
  115. {
  116.   unsigned char P, D;
  117.   unsigned char **coeff = malloc(sizeof(unsigned char *)*parities);
  118.   if (coeff == NULL) {
  119.     fprintf(stderr, "sorry, no memory for table generation. Aborted.n");
  120.     exit(1);
  121.   }
  122.   /* initialize */
  123.   for (P = 0; P < parities; P++) {
  124.     coeff[P] = malloc(datas+parities);
  125.     if (coeff[P] == NULL) {
  126.       fprintf(stderr, "sorry, no memory for table generation. Aborted.n");
  127.       exit(1);
  128.     }
  129.     for (D = 0; D < datas+parities; D++) {
  130.       coeff[P][D] = alog[((parities-1-P) * D) % mod];
  131.     }
  132.   }
  133.   return coeff;
  134. }
  135. /* do gaussian elimination in order to bring the matrix into a form of
  136.    a  b  c ...
  137.    0  d  e ...
  138.    0  0  f ...
  139.    0  0  0 ...
  140.    ...
  141.  */
  142. static void gauss_elimination(int datas, int parities, unsigned char **coeff,
  143.       unsigned char mod, int shift)
  144. {
  145.   unsigned char P, D, E;
  146.   /* gaussian elimination */
  147.   for (E = 1; E < parities; E++) {
  148.     for (P = E; P < parities; P++) {
  149.       unsigned char fak = div(coeff[P][E-1+shift],coeff[E-1][E-1+shift], mod);
  150.       for (D = E-1; D < datas+parities; D++) {
  151.         coeff[P][D] = sub(coeff[P][D], mul(fak, coeff[E-1][D], mod));
  152.       }
  153.     }
  154.   }
  155. }
  156. /* solve the triangelized equation system by recursive substitution
  157.  */
  158. static void solve_triangelized(int datas, int parities, unsigned char **coeff,
  159.        char *name, unsigned char mod, int shift)
  160. {
  161.   unsigned char P, D, E;
  162.   unsigned char lower_bound = shift;
  163.   printf("static unsigned char %s[%d][%d] = {n", name, parities,datas);
  164.   /* down-counting loops with wrapped end values! */
  165.   for (P = parities-1; P < parities; P--) {
  166.     printf("{");
  167.     for (D = parities+datas-1; D < parities+datas && D >= P; D--) {
  168.       coeff[P][D] = div(neg(coeff[P][D]),coeff[P][P+shift], mod);
  169.       if (D < lower_bound || D >= (parities+shift))
  170.         printf("%d,", log[coeff[P][D]]);
  171.       if (P > 0) {
  172.         unsigned char fak = coeff[P][D];
  173.         for (E = P-1; E < P; E--) {
  174.           coeff[E][D] = sub(coeff[E][D],mul(fak,coeff[E][P+shift], mod));
  175.         }
  176.       }
  177.     }
  178.     printf("},n");
  179.   }
  180.   printf("};n");
  181. }
  182. static void solve_tail(int datas, int parities, char *name, unsigned char mod)
  183. {
  184.   unsigned char **coeff;
  185.   coeff = init_matrix(datas, parities, alog, mod);
  186. print_c(coeff, datas, parities);
  187.   gauss_elimination(datas, parities, coeff, mod, 0);
  188. print_c(coeff, datas, parities);
  189.   solve_triangelized(datas, parities, coeff, name, mod, 0);
  190. print_c(coeff, datas, parities);
  191. }
  192. static int solve_sub_tail(int datas, int parities, char *name)
  193. {
  194.   alog = rs_sub_rw_alog;
  195.   log = rs_sub_rw_log;
  196.   mod = (1 << RS_SUB_RW_BITS)-1;
  197.   solve_tail(datas, parities, name, mod);
  198.   return 0;
  199. }
  200. static int solve_rs_tail(int datas, int parities, char *name)
  201. {
  202.   alog = rs_l12_alog;
  203.   log = rs_l12_log;
  204.   mod = (1 << RS_L12_BITS)-1;
  205.   solve_tail(datas, parities, name, mod);
  206.   return 0;
  207. }
  208. static int solve_rs_centered(int datas, int parities, char *name)
  209. {
  210.   unsigned char **coeff;
  211.   alog = rs_l12_alog;
  212.   log = rs_l12_log;
  213.   mod = (1 << RS_L12_BITS)-1;
  214.   coeff = init_matrix(datas, parities, alog, mod);
  215. print_c(coeff, datas, parities);
  216.   gauss_elimination(datas, parities, coeff, mod, datas/2);
  217. print_c(coeff, datas, parities);
  218.   solve_triangelized(datas, parities, coeff, name, mod, datas/2);
  219. print_c(coeff, datas, parities);
  220.   return 0;
  221. }
  222. #define L2_SCRAMBLER_PRESET 0x1
  223. static void L2_scrambler(void)
  224. {
  225.   int i;
  226.   unsigned short scr;
  227.   unsigned char *l2_scrambler, *scrtabp;
  228.   /* initialize Yellow Book scrambler table */
  229.   l2_scrambler = calloc(2340 ,1);
  230.   if (l2_scrambler == NULL) {
  231.     fprintf(stderr, "sorry, no memory for scrambler table generation. Aborted.n");
  232.     exit(1);
  233.   }
  234.   scrtabp = l2_scrambler;
  235.   scr = L2_SCRAMBLER_PRESET;
  236.   printf("static unsigned char yellowbook_scrambler[2340] = {n  ");
  237.   for (i = 0; i < 2340; i++) {
  238.     int j;
  239.     for (j = 0; j < 8; j++) {
  240.       if (scr & 1) {
  241.         *scrtabp |= 1 << j;
  242.       }
  243.       if ((scr & 1) ^ ((scr >> 1) & 1)) {
  244.         scr |= 1 << 15;
  245.       }
  246.       scr = scr >> 1;
  247.     }
  248.     printf("%d,", *scrtabp);
  249.     if (((i+1) % 23) == 0) printf("n  ");
  250.     scrtabp++;
  251.   }
  252.   printf("n};n");
  253. }
  254. int main(int argc, char **argv)
  255. {
  256.   if (argc > 1) debug = 1;
  257.   init_rs_l12();
  258.   init_rs_sub_rw();
  259.   /* generate encoding table for Subchannel Q */
  260.   solve_sub_tail(2,2, "SQ");
  261.   /* generate encoding table for Subchannel P */
  262.   solve_sub_tail(20,4, "SP");
  263.   /* generate encoding table for audio sectors Q */
  264.   solve_rs_centered(24,4, "AQ");
  265.   /* generate encoding table for audio sectors P */
  266.   solve_rs_tail(32,4, "AP");
  267.   /* generate encoding table for data sectors Q */
  268.   solve_rs_tail(43,2, "DQ");
  269.   /* generate encoding table for data sectors P */
  270.   solve_rs_tail(24,2, "DP");
  271.   /* generate the scrambler table for data sectors */
  272.   L2_scrambler();
  273.   return 0;
  274. }