Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/psx/octoshock/cdrom/galois.cpp
2 views
1
/* dvdisaster: Additional error correction for optical media.
2
* Copyright (C) 2004-2007 Carsten Gnoerlich.
3
* Project home page: http://www.dvdisaster.com
4
* Email: [email protected] -or- [email protected]
5
*
6
* The Reed-Solomon error correction draws a lot of inspiration - and even code -
7
* from Phil Karn's excellent Reed-Solomon library: http://www.ka9q.net/code/fec/
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
13
*
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA,
22
* or direct your browser at http://www.gnu.org.
23
*/
24
25
#include "dvdisaster.h"
26
27
#include "galois-inlines.h"
28
29
/***
30
*** Galois field arithmetic.
31
***
32
* Calculations are done over the extension field GF(2**n).
33
* Be careful not to overgeneralize these arithmetics;
34
* they only work for the case of GF(p**n) with p being prime.
35
*/
36
37
/* Initialize the Galois field tables */
38
39
40
GaloisTables* CreateGaloisTables(int32 gf_generator)
41
{
42
GaloisTables *gt = (GaloisTables *)calloc(1, sizeof(GaloisTables));
43
int32 b,log;
44
45
/* Allocate the tables.
46
The encoder uses a special version of alpha_to which has the mod_fieldmax()
47
folded into the table. */
48
49
gt->gfGenerator = gf_generator;
50
51
gt->indexOf = (int32 *)calloc(GF_FIELDSIZE, sizeof(int32));
52
gt->alphaTo = (int32 *)calloc(GF_FIELDSIZE, sizeof(int32));
53
gt->encAlphaTo = (int32 *)calloc(2*GF_FIELDSIZE, sizeof(int32));
54
55
/* create the log/ilog values */
56
57
for(b=1, log=0; log<GF_FIELDMAX; log++)
58
{ gt->indexOf[b] = log;
59
gt->alphaTo[log] = b;
60
b = b << 1;
61
if(b & GF_FIELDSIZE)
62
b = b ^ gf_generator;
63
}
64
65
if(b!=1)
66
{
67
printf("Failed to create the Galois field log tables!\n");
68
exit(1);
69
}
70
71
/* we're even closed using infinity (makes things easier) */
72
73
gt->indexOf[0] = GF_ALPHA0; /* log(0) = inf */
74
gt->alphaTo[GF_ALPHA0] = 0; /* and the other way around */
75
76
for(b=0; b<2*GF_FIELDSIZE; b++)
77
gt->encAlphaTo[b] = gt->alphaTo[mod_fieldmax(b)];
78
79
return gt;
80
}
81
82
void FreeGaloisTables(GaloisTables *gt)
83
{
84
if(gt->indexOf) free(gt->indexOf);
85
if(gt->alphaTo) free(gt->alphaTo);
86
if(gt->encAlphaTo) free(gt->encAlphaTo);
87
88
free(gt);
89
}
90
91
/***
92
*** Create the the Reed-Solomon generator polynomial
93
*** and some auxiliary data structures.
94
*/
95
96
ReedSolomonTables *CreateReedSolomonTables(GaloisTables *gt,
97
int32 first_consecutive_root,
98
int32 prim_elem,
99
int nroots_in)
100
{ ReedSolomonTables *rt = (ReedSolomonTables *)calloc(1, sizeof(ReedSolomonTables));
101
int32 i,j,root;
102
103
rt->gfTables = gt;
104
rt->fcr = first_consecutive_root;
105
rt->primElem = prim_elem;
106
rt->nroots = nroots_in;
107
rt->ndata = GF_FIELDMAX - rt->nroots;
108
109
rt->gpoly = (int32 *)calloc((rt->nroots+1), sizeof(int32));
110
111
/* Create the RS code generator polynomial */
112
113
rt->gpoly[0] = 1;
114
115
for(i=0, root=first_consecutive_root*prim_elem; i<rt->nroots; i++, root+=prim_elem)
116
{ rt->gpoly[i+1] = 1;
117
118
/* Multiply gpoly by alpha**(root+x) */
119
120
for(j=i; j>0; j--)
121
{
122
if(rt->gpoly[j] != 0)
123
rt->gpoly[j] = rt->gpoly[j-1] ^ gt->alphaTo[mod_fieldmax(gt->indexOf[rt->gpoly[j]] + root)];
124
else
125
rt->gpoly[j] = rt->gpoly[j-1];
126
}
127
128
rt->gpoly[0] = gt->alphaTo[mod_fieldmax(gt->indexOf[rt->gpoly[0]] + root)];
129
}
130
131
/* Store the polynomials index for faster encoding */
132
133
for(i=0; i<=rt->nroots; i++)
134
rt->gpoly[i] = gt->indexOf[rt->gpoly[i]];
135
136
#if 0
137
/* for the precalculated unrolled loops only */
138
139
for(i=gt->nroots-1; i>0; i--)
140
PrintCLI(
141
" par_idx[((++spk)&%d)] ^= enc_alpha_to[feedback + %3d];\n",
142
nroots-1,gt->gpoly[i]);
143
144
PrintCLI(" par_idx[sp] = enc_alpha_to[feedback + %3d];\n",
145
gt->gpoly[0]);
146
#endif
147
148
return rt;
149
}
150
151
void FreeReedSolomonTables(ReedSolomonTables *rt)
152
{
153
if(rt->gpoly) free(rt->gpoly);
154
155
free(rt);
156
}
157
158