1 /* $Id: tpam_hdlc.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
2 *
3 * Turbo PAM ISDN driver for Linux. (Kernel Driver - HDLC encoding)
4 *
5 * Copyright 1998-2000 AUVERTECH T�l�com
6 * Copyright 2001 Stelian Pop <stelian.pop@fr.alcove.com>, Alc�ve
7 *
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
10 *
11 * For all support questions please contact: <support@auvertech.fr>
12 *
13 */
14
15 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
16
17 Module Name:
18
19 hdlc.c
20
21 Abstract:
22
23 stuff0 : array necessary for the bit stuffing algorithm
24 stuff1 : array necessary for the bit stuffing algorithm
25 stuff2 : array necessary for the bit stuffing algorithm
26 stuff3 : array necessary for the bit stuffing algorithm
27 stuff4 : array necessary for the bit stuffing algorithm
28 stuff5 : array necessary for the bit stuffing algorithm
29 stuffs[] : array conaining the previous 6 arrays
30 destuff0 : array necessary for the bit destuffing algorithm
31 destuff1 : array necessary for the bit destuffing algorithm
32 destuff2 : array necessary for the bit destuffing algorithm
33 destuff3 : array necessary for the bit destuffing algorithm
34 destuff4 : array necessary for the bit destuffing algorithm
35 destuff5 : array necessary for the bit destuffing algorithm
36 destuffs[] : array conaining the previous 6 arrays
37
38 tpam_hdlc_encode : bit stuffing of a byte array, with the addition
39 of a start and end flag, using the bit shift given in
40 parameter (which is updated at the end of encoding).
41 tpam_hdlc_decode : bit de-stuffing of a byte array with detection of
42 possible ABORTs.
43
44 Revision History:
45
46 ---------------------------------------------------------------------------*/
47
48 /* The arrays are used as follows:
49
50 For the bit stuffing :
51
52 stuff0 = used if the previous byte ended with '0'
53 stuff1 = used if the previous byte ended with '10'
54 stuff2 = used if the previous byte ended with '110'
55 stuff3 = used if the previous byte ended with '1110'
56 stuff4 = used if the previous byte ended with '11110'
57 stuff5 = used if the previous byte ended with '111110'
58
59 those arrays are indexed by the byte to stuff.
60
61 the data of those arrays are of the form (in binary):
62 "bbbbaaaa cccccccc"
63 with "cccccccc" : byte stuffed
64 "aaaa" : "0000" --> no insertion of '0'
65 "0100" --> 1 '0' inserted, carry = '0'
66 "0101" --> 1 '0' inserted, carry = '1'
67 "1000" --> 2 '0' inserted, carry = '00'
68 "1001" --> 2 '0' inserted, carry = '01'
69 "1010" --> 2 '0' inserted, carry = '10'
70 "1011" --> 2 '0' inserted, carry = '11'
71 "bbbb" : count of '1' at the end of "cccccccc"
72
73
74
75 For the bit de-stuffing :
76
77 destuff0 = used if the previous byte ended with '0'
78 destuff1 = used if the previous byte ended with '10'
79 destuff2 = used if the previous byte ended with '110'
80 destuff3 = used if the previous byte ended with '1110'
81 destuff4 = used if the previous byte ended with '11110'
82 destuff5 = used if the previous byte ended with '111110'
83
84 those arrays are indexed by the byte to de-stuff.
85
86 the data of those arrays are of the form (in binary):
87 "dbbbaaaa cccccccc"
88 with "cccccccc" : byte destuffed
89 "aaaa" : count of '1' at the end of the byte non destuffed
90 "bbb" : count of bits to use in the destuffed byte (8 less the count
91 of '0' deleted) less 1 (can be only 7, 6 or 5)
92 "d" : '1' if the byte non destuffed has more than 5 consecutive '1'
93 (flag or abort)
94 */
95
96 #include <linux/types.h>
97 #include "tpam.h"
98
99 typedef u8 BYTE;
100 typedef u16 WORD;
101 typedef u32 DWORD;
102 typedef u8 BOOL;
103
104 #define TRUE 1
105 #define FALSE 0
106
107 static WORD stuff0[] =
108 {
109 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
110 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
111 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
112 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x041F,
113 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
114 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
115 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
116 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x043E, 0x045F,
117 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
118 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
119 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
120 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x149F,
121 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
122 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
123 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
124 0x0078, 0x0079, 0x007A, 0x007B, 0x047C, 0x047D, 0x14BE, 0x24DF,
125 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
126 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x108F,
127 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
128 0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x051F,
129 0x10A0, 0x10A1, 0x10A2, 0x10A3, 0x10A4, 0x10A5, 0x10A6, 0x10A7,
130 0x10A8, 0x10A9, 0x10AA, 0x10AB, 0x10AC, 0x10AD, 0x10AE, 0x10AF,
131 0x10B0, 0x10B1, 0x10B2, 0x10B3, 0x10B4, 0x10B5, 0x10B6, 0x10B7,
132 0x10B8, 0x10B9, 0x10BA, 0x10BB, 0x10BC, 0x10BD, 0x053E, 0x055F,
133 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x20C7,
134 0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x20CF,
135 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7,
136 0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x159F,
137 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7,
138 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF,
139 0x40F0, 0x40F1, 0x40F2, 0x40F3, 0x40F4, 0x40F5, 0x40F6, 0x40F7,
140 0x50F8, 0x50F9, 0x50FA, 0x50FB, 0x057C, 0x057D, 0x15BE, 0x25DF,
141 };
142
143
144 static WORD stuff1[] =
145 {
146 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
147 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x040F,
148 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
149 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x042F,
150 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
151 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x044F,
152 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
153 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x043E, 0x046F,
154 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
155 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x148F,
156 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
157 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x14AF,
158 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
159 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x24CF,
160 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
161 0x0078, 0x0079, 0x007A, 0x007B, 0x047C, 0x047D, 0x14BE, 0x34EF,
162 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087,
163 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x050F,
164 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097,
165 0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x052F,
166 0x10A0, 0x10A1, 0x10A2, 0x10A3, 0x10A4, 0x10A5, 0x10A6, 0x10A7,
167 0x10A8, 0x10A9, 0x10AA, 0x10AB, 0x10AC, 0x10AD, 0x10AE, 0x054F,
168 0x10B0, 0x10B1, 0x10B2, 0x10B3, 0x10B4, 0x10B5, 0x10B6, 0x10B7,
169 0x10B8, 0x10B9, 0x10BA, 0x10BB, 0x10BC, 0x10BD, 0x053E, 0x056F,
170 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x20C7,
171 0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x158F,
172 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7,
173 0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x15AF,
174 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7,
175 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x25CF,
176 0x40F0, 0x40F1, 0x40F2, 0x40F3, 0x40F4, 0x40F5, 0x40F6, 0x40F7,
177 0x50F8, 0x50F9, 0x50FA, 0x50FB, 0x057C, 0x057D, 0x15BE, 0x35EF,
178 };
179
180
181 static WORD stuff2[] =
182 {
183 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0407,
184 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x0417,
185 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0427,
186 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x0437,
187 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0447,
188 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x0457,
189 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0467,
190 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x043E, 0x0477,
191 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x1487,
192 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x1497,
193 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x14A7,
194 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x14B7,
195 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x24C7,
196 0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x24D7,
197 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x34E7,
198 0x0078, 0x0079, 0x007A, 0x007B, 0x047C, 0x047D, 0x14BE, 0x44F7,
199 0x1080, 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x0507,
200 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D, 0x108E, 0x0517,
201 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x0527,
202 0x1098, 0x1099, 0x109A, 0x109B, 0x109C, 0x109D, 0x109E, 0x0537,
203 0x10A0, 0x10A1, 0x10A2, 0x10A3, 0x10A4, 0x10A5, 0x10A6, 0x0547,
204 0x10A8, 0x10A9, 0x10AA, 0x10AB, 0x10AC, 0x10AD, 0x10AE, 0x0557,
205 0x10B0, 0x10B1, 0x10B2, 0x10B3, 0x10B4, 0x10B5, 0x10B6, 0x0567,
206 0x10B8, 0x10B9, 0x10BA, 0x10BB, 0x10BC, 0x10BD, 0x053E, 0x0577,
207 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5, 0x20C6, 0x1587,
208 0x20C8, 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD, 0x20CE, 0x1597,
209 0x20D0, 0x20D1, 0x20D2, 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x15A7,
210 0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC, 0x20DD, 0x20DE, 0x15B7,
211 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x25C7,
212 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x25D7,
213 0x40F0, 0x40F1, 0x40F2, 0x40F3, 0x40F4, 0x40F5, 0x40F6, 0x35E7,
214 0x50F8, 0x50F9, 0x50FA, 0x50FB, 0x057C, 0x057D, 0x15BE, 0x45F7,
215 };
216
217
218 static WORD stuff3[] =
219 {
220 0x0000, 0x0001, 0x0002, 0x0403, 0x0004, 0x0005, 0x0006, 0x040B,
221 0x0008, 0x0009, 0x000A, 0x0413, 0x000C, 0x000D, 0x000E, 0x041B,
222 0x0010, 0x0011, 0x0012, 0x0423, 0x0014, 0x0015, 0x0016, 0x042B,
223 0x0018, 0x0019, 0x001A, 0x0433, 0x001C, 0x001D, 0x001E, 0x043B,
224 0x0020, 0x0021, 0x0022, 0x0443, 0x0024, 0x0025, 0x0026, 0x044B,
225 0x0028, 0x0029, 0x002A, 0x0453, 0x002C, 0x002D, 0x002E, 0x045B,
226 0x0030, 0x0031, 0x0032, 0x0463, 0x0034, 0x0035, 0x0036, 0x046B,
227 0x0038, 0x0039, 0x003A, 0x0473, 0x003C, 0x003D, 0x043E, 0x047B,
228 0x0040, 0x0041, 0x0042, 0x1483, 0x0044, 0x0045, 0x0046, 0x148B,
229 0x0048, 0x0049, 0x004A, 0x1493, 0x004C, 0x004D, 0x004E, 0x149B,
230 0x0050, 0x0051, 0x0052, 0x14A3, 0x0054, 0x0055, 0x0056, 0x14AB,
231 0x0058, 0x0059, 0x005A, 0x14B3, 0x005C, 0x005D, 0x005E, 0x14BB,
232 0x0060, 0x0061, 0x0062, 0x24C3, 0x0064, 0x0065, 0x0066, 0x24CB,
233 0x0068, 0x0069, 0x006A, 0x24D3, 0x006C, 0x006D, 0x006E, 0x24DB,
234 0x0070, 0x0071, 0x0072, 0x34E3, 0x0074, 0x0075, 0x0076, 0x34EB,
235 0x0078, 0x0079, 0x007A, 0x44F3, 0x047C, 0x047D, 0x14BE, 0x54FB,
236 0x1080, 0x1081, 0x1082, 0x0503, 0x1084, 0x1085, 0x1086, 0x050B,
237 0x1088, 0x1089, 0x108A, 0x0513, 0x108C, 0x108D, 0x108E, 0x051B,
238 0x1090, 0x1091, 0x1092, 0x0523, 0x1094, 0x1095, 0x1096, 0x052B,
239 0x1098, 0x1099, 0x109A, 0x0533, 0x109C, 0x109D, 0x109E, 0x053B,
240 0x10A0, 0x10A1, 0x10A2, 0x0543, 0x10A4, 0x10A5, 0x10A6, 0x054B,
241 0x10A8, 0x10A9, 0x10AA, 0x0553, 0x10AC, 0x10AD, 0x10AE, 0x055B,
242 0x10B0, 0x10B1, 0x10B2, 0x0563, 0x10B4, 0x10B5, 0x10B6, 0x056B,
243 0x10B8, 0x10B9, 0x10BA, 0x0573, 0x10BC, 0x10BD, 0x053E, 0x057B,
244 0x20C0, 0x20C1, 0x20C2, 0x1583, 0x20C4, 0x20C5, 0x20C6, 0x158B,
245 0x20C8, 0x20C9, 0x20CA, 0x1593, 0x20CC, 0x20CD, 0x20CE, 0x159B,
246 0x20D0, 0x20D1, 0x20D2, 0x15A3, 0x20D4, 0x20D5, 0x20D6, 0x15AB,
247 0x20D8, 0x20D9, 0x20DA, 0x15B3, 0x20DC, 0x20DD, 0x20DE, 0x15BB,
248 0x30E0, 0x30E1, 0x30E2, 0x25C3, 0x30E4, 0x30E5, 0x30E6, 0x25CB,
249 0x30E8, 0x30E9, 0x30EA, 0x25D3, 0x30EC, 0x30ED, 0x30EE, 0x25DB,
250 0x40F0, 0x40F1, 0x40F2, 0x35E3, 0x40F4, 0x40F5, 0x40F6, 0x35EB,
251 0x50F8, 0x50F9, 0x50FA, 0x45F3, 0x057C, 0x057D, 0x15BE, 0x55FB,
252 };
253
254
255 static WORD stuff4[] =
256 {
257 0x0000, 0x0401, 0x0002, 0x0405, 0x0004, 0x0409, 0x0006, 0x040D,
258 0x0008, 0x0411, 0x000A, 0x0415, 0x000C, 0x0419, 0x000E, 0x041D,
259 0x0010, 0x0421, 0x0012, 0x0425, 0x0014, 0x0429, 0x0016, 0x042D,
260 0x0018, 0x0431, 0x001A, 0x0435, 0x001C, 0x0439, 0x001E, 0x043D,
261 0x0020, 0x0441, 0x0022, 0x0445, 0x0024, 0x0449, 0x0026, 0x044D,
262 0x0028, 0x0451, 0x002A, 0x0455, 0x002C, 0x0459, 0x002E, 0x045D,
263 0x0030, 0x0461, 0x0032, 0x0465, 0x0034, 0x0469, 0x0036, 0x046D,
264 0x0038, 0x0471, 0x003A, 0x0475, 0x003C, 0x0479, 0x043E, 0x087D,
265 0x0040, 0x1481, 0x0042, 0x1485, 0x0044, 0x1489, 0x0046, 0x148D,
266 0x0048, 0x1491, 0x004A, 0x1495, 0x004C, 0x1499, 0x004E, 0x149D,
267 0x0050, 0x14A1, 0x0052, 0x14A5, 0x0054, 0x14A9, 0x0056, 0x14AD,
268 0x0058, 0x14B1, 0x005A, 0x14B5, 0x005C, 0x14B9, 0x005E, 0x14BD,
269 0x0060, 0x24C1, 0x0062, 0x24C5, 0x0064, 0x24C9, 0x0066, 0x24CD,
270 0x0068, 0x24D1, 0x006A, 0x24D5, 0x006C, 0x24D9, 0x006E, 0x24DD,
271 0x0070, 0x34E1, 0x0072, 0x34E5, 0x0074, 0x34E9, 0x0076, 0x34ED,
272 0x0078, 0x44F1, 0x007A, 0x44F5, 0x047C, 0x54F9, 0x14BE, 0x097D,
273 0x1080, 0x0501, 0x1082, 0x0505, 0x1084, 0x0509, 0x1086, 0x050D,
274 0x1088, 0x0511, 0x108A, 0x0515, 0x108C, 0x0519, 0x108E, 0x051D,
275 0x1090, 0x0521, 0x1092, 0x0525, 0x1094, 0x0529, 0x1096, 0x052D,
276 0x1098, 0x0531, 0x109A, 0x0535, 0x109C, 0x0539, 0x109E, 0x053D,
277 0x10A0, 0x0541, 0x10A2, 0x0545, 0x10A4, 0x0549, 0x10A6, 0x054D,
278 0x10A8, 0x0551, 0x10AA, 0x0555, 0x10AC, 0x0559, 0x10AE, 0x055D,
279 0x10B0, 0x0561, 0x10B2, 0x0565, 0x10B4, 0x0569, 0x10B6, 0x056D,
280 0x10B8, 0x0571, 0x10BA, 0x0575, 0x10BC, 0x0579, 0x053E, 0x0A7D,
281 0x20C0, 0x1581, 0x20C2, 0x1585, 0x20C4, 0x1589, 0x20C6, 0x158D,
282 0x20C8, 0x1591, 0x20CA, 0x1595, 0x20CC, 0x1599, 0x20CE, 0x159D,
283 0x20D0, 0x15A1, 0x20D2, 0x15A5, 0x20D4, 0x15A9, 0x20D6, 0x15AD,
284 0x20D8, 0x15B1, 0x20DA, 0x15B5, 0x20DC, 0x15B9, 0x20DE, 0x15BD,
285 0x30E0, 0x25C1, 0x30E2, 0x25C5, 0x30E4, 0x25C9, 0x30E6, 0x25CD,
286 0x30E8, 0x25D1, 0x30EA, 0x25D5, 0x30EC, 0x25D9, 0x30EE, 0x25DD,
287 0x40F0, 0x35E1, 0x40F2, 0x35E5, 0x40F4, 0x35E9, 0x40F6, 0x35ED,
288 0x50F8, 0x45F1, 0x50FA, 0x45F5, 0x057C, 0x55F9, 0x15BE, 0x0B7D,
289 };
290
291
292 static WORD stuff5[] =
293 {
294 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040A, 0x040C, 0x040E,
295 0x0410, 0x0412, 0x0414, 0x0416, 0x0418, 0x041A, 0x041C, 0x041E,
296 0x0420, 0x0422, 0x0424, 0x0426, 0x0428, 0x042A, 0x042C, 0x042E,
297 0x0430, 0x0432, 0x0434, 0x0436, 0x0438, 0x043A, 0x043C, 0x083E,
298 0x0440, 0x0442, 0x0444, 0x0446, 0x0448, 0x044A, 0x044C, 0x044E,
299 0x0450, 0x0452, 0x0454, 0x0456, 0x0458, 0x045A, 0x045C, 0x045E,
300 0x0460, 0x0462, 0x0464, 0x0466, 0x0468, 0x046A, 0x046C, 0x046E,
301 0x0470, 0x0472, 0x0474, 0x0476, 0x0478, 0x047A, 0x087C, 0x18BE,
302 0x1480, 0x1482, 0x1484, 0x1486, 0x1488, 0x148A, 0x148C, 0x148E,
303 0x1490, 0x1492, 0x1494, 0x1496, 0x1498, 0x149A, 0x149C, 0x149E,
304 0x14A0, 0x14A2, 0x14A4, 0x14A6, 0x14A8, 0x14AA, 0x14AC, 0x14AE,
305 0x14B0, 0x14B2, 0x14B4, 0x14B6, 0x14B8, 0x14BA, 0x14BC, 0x093E,
306 0x24C0, 0x24C2, 0x24C4, 0x24C6, 0x24C8, 0x24CA, 0x24CC, 0x24CE,
307 0x24D0, 0x24D2, 0x24D4, 0x24D6, 0x24D8, 0x24DA, 0x24DC, 0x24DE,
308 0x34E0, 0x34E2, 0x34E4, 0x34E6, 0x34E8, 0x34EA, 0x34EC, 0x34EE,
309 0x44F0, 0x44F2, 0x44F4, 0x44F6, 0x54F8, 0x54FA, 0x097C, 0x19BE,
310 0x0500, 0x0502, 0x0504, 0x0506, 0x0508, 0x050A, 0x050C, 0x050E,
311 0x0510, 0x0512, 0x0514, 0x0516, 0x0518, 0x051A, 0x051C, 0x051E,
312 0x0520, 0x0522, 0x0524, 0x0526, 0x0528, 0x052A, 0x052C, 0x052E,
313 0x0530, 0x0532, 0x0534, 0x0536, 0x0538, 0x053A, 0x053C, 0x0A3E,
314 0x0540, 0x0542, 0x0544, 0x0546, 0x0548, 0x054A, 0x054C, 0x054E,
315 0x0550, 0x0552, 0x0554, 0x0556, 0x0558, 0x055A, 0x055C, 0x055E,
316 0x0560, 0x0562, 0x0564, 0x0566, 0x0568, 0x056A, 0x056C, 0x056E,
317 0x0570, 0x0572, 0x0574, 0x0576, 0x0578, 0x057A, 0x0A7C, 0x1ABE,
318 0x1580, 0x1582, 0x1584, 0x1586, 0x1588, 0x158A, 0x158C, 0x158E,
319 0x1590, 0x1592, 0x1594, 0x1596, 0x1598, 0x159A, 0x159C, 0x159E,
320 0x15A0, 0x15A2, 0x15A4, 0x15A6, 0x15A8, 0x15AA, 0x15AC, 0x15AE,
321 0x15B0, 0x15B2, 0x15B4, 0x15B6, 0x15B8, 0x15BA, 0x15BC, 0x0B3E,
322 0x25C0, 0x25C2, 0x25C4, 0x25C6, 0x25C8, 0x25CA, 0x25CC, 0x25CE,
323 0x25D0, 0x25D2, 0x25D4, 0x25D6, 0x25D8, 0x25DA, 0x25DC, 0x25DE,
324 0x35E0, 0x35E2, 0x35E4, 0x35E6, 0x35E8, 0x35EA, 0x35EC, 0x35EE,
325 0x45F0, 0x45F2, 0x45F4, 0x45F6, 0x55F8, 0x55FA, 0x0B7C, 0x1BBE,
326 };
327
328 static WORD destuff0[] =
329 {
330 0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x7007,
331 0x7008, 0x7009, 0x700A, 0x700B, 0x700C, 0x700D, 0x700E, 0x700F,
332 0x7010, 0x7011, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x7017,
333 0x7018, 0x7019, 0x701A, 0x701B, 0x701C, 0x701D, 0x701E, 0x601F,
334 0x7020, 0x7021, 0x7022, 0x7023, 0x7024, 0x7025, 0x7026, 0x7027,
335 0x7028, 0x7029, 0x702A, 0x702B, 0x702C, 0x702D, 0x702E, 0x702F,
336 0x7030, 0x7031, 0x7032, 0x7033, 0x7034, 0x7035, 0x7036, 0x7037,
337 0x7038, 0x7039, 0x703A, 0x703B, 0x703C, 0x703D, 0x603E, 0xF03F,
338 0x7040, 0x7041, 0x7042, 0x7043, 0x7044, 0x7045, 0x7046, 0x7047,
339 0x7048, 0x7049, 0x704A, 0x704B, 0x704C, 0x704D, 0x704E, 0x704F,
340 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056, 0x7057,
341 0x7058, 0x7059, 0x705A, 0x705B, 0x705C, 0x705D, 0x705E, 0x603F,
342 0x7060, 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x7067,
343 0x7068, 0x7069, 0x706A, 0x706B, 0x706C, 0x706D, 0x706E, 0x706F,
344 0x7070, 0x7071, 0x7072, 0x7073, 0x7074, 0x7075, 0x7076, 0x7077,
345 0x7078, 0x7079, 0x707A, 0x707B, 0x607C, 0x607D, 0xF07E, 0xF07F,
346 0x7180, 0x7181, 0x7182, 0x7183, 0x7184, 0x7185, 0x7186, 0x7187,
347 0x7188, 0x7189, 0x718A, 0x718B, 0x718C, 0x718D, 0x718E, 0x718F,
348 0x7190, 0x7191, 0x7192, 0x7193, 0x7194, 0x7195, 0x7196, 0x7197,
349 0x7198, 0x7199, 0x719A, 0x719B, 0x719C, 0x719D, 0x719E, 0x615F,
350 0x71A0, 0x71A1, 0x71A2, 0x71A3, 0x71A4, 0x71A5, 0x71A6, 0x71A7,
351 0x71A8, 0x71A9, 0x71AA, 0x71AB, 0x71AC, 0x71AD, 0x71AE, 0x71AF,
352 0x71B0, 0x71B1, 0x71B2, 0x71B3, 0x71B4, 0x71B5, 0x71B6, 0x71B7,
353 0x71B8, 0x71B9, 0x71BA, 0x71BB, 0x71BC, 0x71BD, 0x617E, 0xF1BF,
354 0x72C0, 0x72C1, 0x72C2, 0x72C3, 0x72C4, 0x72C5, 0x72C6, 0x72C7,
355 0x72C8, 0x72C9, 0x72CA, 0x72CB, 0x72CC, 0x72CD, 0x72CE, 0x72CF,
356 0x72D0, 0x72D1, 0x72D2, 0x72D3, 0x72D4, 0x72D5, 0x72D6, 0x72D7,
357 0x72D8, 0x72D9, 0x72DA, 0x72DB, 0x72DC, 0x72DD, 0x72DE, 0x627F,
358 0x73E0, 0x73E1, 0x73E2, 0x73E3, 0x73E4, 0x73E5, 0x73E6, 0x73E7,
359 0x73E8, 0x73E9, 0x73EA, 0x73EB, 0x73EC, 0x73ED, 0x73EE, 0x73EF,
360 0x74F0, 0x74F1, 0x74F2, 0x74F3, 0x74F4, 0x74F5, 0x74F6, 0x74F7,
361 0x75F8, 0x75F9, 0x75FA, 0x75FB, 0xF6FC, 0xF6FD, 0xF7FE, 0xF8FF,
362 };
363
364
365 static WORD destuff1[] =
366 {
367 0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x7007,
368 0x7008, 0x7009, 0x700A, 0x700B, 0x700C, 0x700D, 0x700E, 0x600F,
369 0x7010, 0x7011, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x7017,
370 0x7018, 0x7019, 0x701A, 0x701B, 0x701C, 0x701D, 0x701E, 0xF01F,
371 0x7020, 0x7021, 0x7022, 0x7023, 0x7024, 0x7025, 0x7026, 0x7027,
372 0x7028, 0x7029, 0x702A, 0x702B, 0x702C, 0x702D, 0x702E, 0x601F,
373 0x7030, 0x7031, 0x7032, 0x7033, 0x7034, 0x7035, 0x7036, 0x7037,
374 0x7038, 0x7039, 0x703A, 0x703B, 0x703C, 0x703D, 0x603E, 0xF03F,
375 0x7040, 0x7041, 0x7042, 0x7043, 0x7044, 0x7045, 0x7046, 0x7047,
376 0x7048, 0x7049, 0x704A, 0x704B, 0x704C, 0x704D, 0x704E, 0x602F,
377 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056, 0x7057,
378 0x7058, 0x7059, 0x705A, 0x705B, 0x705C, 0x705D, 0x705E, 0xF05F,
379 0x7060, 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x7067,
380 0x7068, 0x7069, 0x706A, 0x706B, 0x706C, 0x706D, 0x706E, 0x603F,
381 0x7070, 0x7071, 0x7072, 0x7073, 0x7074, 0x7075, 0x7076, 0x7077,
382 0x7078, 0x7079, 0x707A, 0x707B, 0x607C, 0x607D, 0xF07E, 0xF07F,
383 0x7180, 0x7181, 0x7182, 0x7183, 0x7184, 0x7185, 0x7186, 0x7187,
384 0x7188, 0x7189, 0x718A, 0x718B, 0x718C, 0x718D, 0x718E, 0x614F,
385 0x7190, 0x7191, 0x7192, 0x7193, 0x7194, 0x7195, 0x7196, 0x7197,
386 0x7198, 0x7199, 0x719A, 0x719B, 0x719C, 0x719D, 0x719E, 0xF19F,
387 0x71A0, 0x71A1, 0x71A2, 0x71A3, 0x71A4, 0x71A5, 0x71A6, 0x71A7,
388 0x71A8, 0x71A9, 0x71AA, 0x71AB, 0x71AC, 0x71AD, 0x71AE, 0x615F,
389 0x71B0, 0x71B1, 0x71B2, 0x71B3, 0x71B4, 0x71B5, 0x71B6, 0x71B7,
390 0x71B8, 0x71B9, 0x71BA, 0x71BB, 0x71BC, 0x71BD, 0x617E, 0xF1BF,
391 0x72C0, 0x72C1, 0x72C2, 0x72C3, 0x72C4, 0x72C5, 0x72C6, 0x72C7,
392 0x72C8, 0x72C9, 0x72CA, 0x72CB, 0x72CC, 0x72CD, 0x72CE, 0x626F,
393 0x72D0, 0x72D1, 0x72D2, 0x72D3, 0x72D4, 0x72D5, 0x72D6, 0x72D7,
394 0x72D8, 0x72D9, 0x72DA, 0x72DB, 0x72DC, 0x72DD, 0x72DE, 0xF2DF,
395 0x73E0, 0x73E1, 0x73E2, 0x73E3, 0x73E4, 0x73E5, 0x73E6, 0x73E7,
396 0x73E8, 0x73E9, 0x73EA, 0x73EB, 0x73EC, 0x73ED, 0x73EE, 0x637F,
397 0x74F0, 0x74F1, 0x74F2, 0x74F3, 0x74F4, 0x74F5, 0x74F6, 0x74F7,
398 0x75F8, 0x75F9, 0x75FA, 0x75FB, 0xF6FC, 0xF6FD, 0xF7FE, 0xF9FF,
399 };
400
401
402 static WORD destuff2[] =
403 {
404 0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x6007,
405 0x7008, 0x7009, 0x700A, 0x700B, 0x700C, 0x700D, 0x700E, 0xF00F,
406 0x7010, 0x7011, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x600F,
407 0x7018, 0x7019, 0x701A, 0x701B, 0x701C, 0x701D, 0x701E, 0xF01F,
408 0x7020, 0x7021, 0x7022, 0x7023, 0x7024, 0x7025, 0x7026, 0x6017,
409 0x7028, 0x7029, 0x702A, 0x702B, 0x702C, 0x702D, 0x702E, 0xF02F,
410 0x7030, 0x7031, 0x7032, 0x7033, 0x7034, 0x7035, 0x7036, 0x601F,
411 0x7038, 0x7039, 0x703A, 0x703B, 0x703C, 0x703D, 0x603E, 0xF03F,
412 0x7040, 0x7041, 0x7042, 0x7043, 0x7044, 0x7045, 0x7046, 0x6027,
413 0x7048, 0x7049, 0x704A, 0x704B, 0x704C, 0x704D, 0x704E, 0xF04F,
414 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056, 0x602F,
415 0x7058, 0x7059, 0x705A, 0x705B, 0x705C, 0x705D, 0x705E, 0xF05F,
416 0x7060, 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x6037,
417 0x7068, 0x7069, 0x706A, 0x706B, 0x706C, 0x706D, 0x706E, 0xF06F,
418 0x7070, 0x7071, 0x7072, 0x7073, 0x7074, 0x7075, 0x7076, 0x603F,
419 0x7078, 0x7079, 0x707A, 0x707B, 0x607C, 0x607D, 0xF07E, 0xF07F,
420 0x7180, 0x7181, 0x7182, 0x7183, 0x7184, 0x7185, 0x7186, 0x6147,
421 0x7188, 0x7189, 0x718A, 0x718B, 0x718C, 0x718D, 0x718E, 0xF18F,
422 0x7190, 0x7191, 0x7192, 0x7193, 0x7194, 0x7195, 0x7196, 0x614F,
423 0x7198, 0x7199, 0x719A, 0x719B, 0x719C, 0x719D, 0x719E, 0xF19F,
424 0x71A0, 0x71A1, 0x71A2, 0x71A3, 0x71A4, 0x71A5, 0x71A6, 0x6157,
425 0x71A8, 0x71A9, 0x71AA, 0x71AB, 0x71AC, 0x71AD, 0x71AE, 0xF1AF,
426 0x71B0, 0x71B1, 0x71B2, 0x71B3, 0x71B4, 0x71B5, 0x71B6, 0x615F,
427 0x71B8, 0x71B9, 0x71BA, 0x71BB, 0x71BC, 0x71BD, 0x617E, 0xF1BF,
428 0x72C0, 0x72C1, 0x72C2, 0x72C3, 0x72C4, 0x72C5, 0x72C6, 0x6267,
429 0x72C8, 0x72C9, 0x72CA, 0x72CB, 0x72CC, 0x72CD, 0x72CE, 0xF2CF,
430 0x72D0, 0x72D1, 0x72D2, 0x72D3, 0x72D4, 0x72D5, 0x72D6, 0x626F,
431 0x72D8, 0x72D9, 0x72DA, 0x72DB, 0x72DC, 0x72DD, 0x72DE, 0xF2DF,
432 0x73E0, 0x73E1, 0x73E2, 0x73E3, 0x73E4, 0x73E5, 0x73E6, 0x6377,
433 0x73E8, 0x73E9, 0x73EA, 0x73EB, 0x73EC, 0x73ED, 0x73EE, 0xF3EF,
434 0x74F0, 0x74F1, 0x74F2, 0x74F3, 0x74F4, 0x74F5, 0x74F6, 0x647F,
435 0x75F8, 0x75F9, 0x75FA, 0x75FB, 0xF6FC, 0xF6FD, 0xF7FE, 0xFAFF,
436 };
437
438
439 static WORD destuff3[] =
440 {
441 0x7000, 0x7001, 0x7002, 0x6003, 0x7004, 0x7005, 0x7006, 0xF007,
442 0x7008, 0x7009, 0x700A, 0x6007, 0x700C, 0x700D, 0x700E, 0xF00F,
443 0x7010, 0x7011, 0x7012, 0x600B, 0x7014, 0x7015, 0x7016, 0xF017,
444 0x7018, 0x7019, 0x701A, 0x600F, 0x701C, 0x701D, 0x701E, 0xF01F,
445 0x7020, 0x7021, 0x7022, 0x6013, 0x7024, 0x7025, 0x7026, 0xF027,
446 0x7028, 0x7029, 0x702A, 0x6017, 0x702C, 0x702D, 0x702E, 0xF02F,
447 0x7030, 0x7031, 0x7032, 0x601B, 0x7034, 0x7035, 0x7036, 0xF037,
448 0x7038, 0x7039, 0x703A, 0x601F, 0x703C, 0x703D, 0x603E, 0xF03F,
449 0x7040, 0x7041, 0x7042, 0x6023, 0x7044, 0x7045, 0x7046, 0xF047,
450 0x7048, 0x7049, 0x704A, 0x6027, 0x704C, 0x704D, 0x704E, 0xF04F,
451 0x7050, 0x7051, 0x7052, 0x602B, 0x7054, 0x7055, 0x7056, 0xF057,
452 0x7058, 0x7059, 0x705A, 0x602F, 0x705C, 0x705D, 0x705E, 0xF05F,
453 0x7060, 0x7061, 0x7062, 0x6033, 0x7064, 0x7065, 0x7066, 0xF067,
454 0x7068, 0x7069, 0x706A, 0x6037, 0x706C, 0x706D, 0x706E, 0xF06F,
455 0x7070, 0x7071, 0x7072, 0x603B, 0x7074, 0x7075, 0x7076, 0xF077,
456 0x7078, 0x7079, 0x707A, 0x603F, 0x607C, 0x607D, 0xF07E, 0xF07F,
457 0x7180, 0x7181, 0x7182, 0x6143, 0x7184, 0x7185, 0x7186, 0xF187,
458 0x7188, 0x7189, 0x718A, 0x6147, 0x718C, 0x718D, 0x718E, 0xF18F,
459 0x7190, 0x7191, 0x7192, 0x614B, 0x7194, 0x7195, 0x7196, 0xF197,
460 0x7198, 0x7199, 0x719A, 0x614F, 0x719C, 0x719D, 0x719E, 0xF19F,
461 0x71A0, 0x71A1, 0x71A2, 0x6153, 0x71A4, 0x71A5, 0x71A6, 0xF1A7,
462 0x71A8, 0x71A9, 0x71AA, 0x6157, 0x71AC, 0x71AD, 0x71AE, 0xF1AF,
463 0x71B0, 0x71B1, 0x71B2, 0x615B, 0x71B4, 0x71B5, 0x71B6, 0xF1B7,
464 0x71B8, 0x71B9, 0x71BA, 0x615F, 0x71BC, 0x71BD, 0x617E, 0xF1BF,
465 0x72C0, 0x72C1, 0x72C2, 0x6263, 0x72C4, 0x72C5, 0x72C6, 0xF2C7,
466 0x72C8, 0x72C9, 0x72CA, 0x6267, 0x72CC, 0x72CD, 0x72CE, 0xF2CF,
467 0x72D0, 0x72D1, 0x72D2, 0x626B, 0x72D4, 0x72D5, 0x72D6, 0xF2D7,
468 0x72D8, 0x72D9, 0x72DA, 0x626F, 0x72DC, 0x72DD, 0x72DE, 0xF2DF,
469 0x73E0, 0x73E1, 0x73E2, 0x6373, 0x73E4, 0x73E5, 0x73E6, 0xF3E7,
470 0x73E8, 0x73E9, 0x73EA, 0x6377, 0x73EC, 0x73ED, 0x73EE, 0xF3EF,
471 0x74F0, 0x74F1, 0x74F2, 0x647B, 0x74F4, 0x74F5, 0x74F6, 0xF4F7,
472 0x75F8, 0x75F9, 0x75FA, 0x657F, 0xF6FC, 0xF6FD, 0xF7FE, 0xFBFF,
473 };
474
475
476 static WORD destuff4[] =
477 {
478 0x7000, 0x6001, 0x7002, 0xF003, 0x7004, 0x6003, 0x7006, 0xF007,
479 0x7008, 0x6005, 0x700A, 0xF00B, 0x700C, 0x6007, 0x700E, 0xF00F,
480 0x7010, 0x6009, 0x7012, 0xF013, 0x7014, 0x600B, 0x7016, 0xF017,
481 0x7018, 0x600D, 0x701A, 0xF01B, 0x701C, 0x600F, 0x701E, 0xF01F,
482 0x7020, 0x6011, 0x7022, 0xF023, 0x7024, 0x6013, 0x7026, 0xF027,
483 0x7028, 0x6015, 0x702A, 0xF02B, 0x702C, 0x6017, 0x702E, 0xF02F,
484 0x7030, 0x6019, 0x7032, 0xF033, 0x7034, 0x601B, 0x7036, 0xF037,
485 0x7038, 0x601D, 0x703A, 0xF03B, 0x703C, 0x601F, 0x603E, 0xF03F,
486 0x7040, 0x6021, 0x7042, 0xF043, 0x7044, 0x6023, 0x7046, 0xF047,
487 0x7048, 0x6025, 0x704A, 0xF04B, 0x704C, 0x6027, 0x704E, 0xF04F,
488 0x7050, 0x6029, 0x7052, 0xF053, 0x7054, 0x602B, 0x7056, 0xF057,
489 0x7058, 0x602D, 0x705A, 0xF05B, 0x705C, 0x602F, 0x705E, 0xF05F,
490 0x7060, 0x6031, 0x7062, 0xF063, 0x7064, 0x6033, 0x7066, 0xF067,
491 0x7068, 0x6035, 0x706A, 0xF06B, 0x706C, 0x6037, 0x706E, 0xF06F,
492 0x7070, 0x6039, 0x7072, 0xF073, 0x7074, 0x603B, 0x7076, 0xF077,
493 0x7078, 0x603D, 0x707A, 0xF07B, 0x607C, 0x503F, 0xF07E, 0xF07F,
494 0x7180, 0x6141, 0x7182, 0xF183, 0x7184, 0x6143, 0x7186, 0xF187,
495 0x7188, 0x6145, 0x718A, 0xF18B, 0x718C, 0x6147, 0x718E, 0xF18F,
496 0x7190, 0x6149, 0x7192, 0xF193, 0x7194, 0x614B, 0x7196, 0xF197,
497 0x7198, 0x614D, 0x719A, 0xF19B, 0x719C, 0x614F, 0x719E, 0xF19F,
498 0x71A0, 0x6151, 0x71A2, 0xF1A3, 0x71A4, 0x6153, 0x71A6, 0xF1A7,
499 0x71A8, 0x6155, 0x71AA, 0xF1AB, 0x71AC, 0x6157, 0x71AE, 0xF1AF,
500 0x71B0, 0x6159, 0x71B2, 0xF1B3, 0x71B4, 0x615B, 0x71B6, 0xF1B7,
501 0x71B8, 0x615D, 0x71BA, 0xF1BB, 0x71BC, 0x615F, 0x617E, 0xF1BF,
502 0x72C0, 0x6261, 0x72C2, 0xF2C3, 0x72C4, 0x6263, 0x72C6, 0xF2C7,
503 0x72C8, 0x6265, 0x72CA, 0xF2CB, 0x72CC, 0x6267, 0x72CE, 0xF2CF,
504 0x72D0, 0x6269, 0x72D2, 0xF2D3, 0x72D4, 0x626B, 0x72D6, 0xF2D7,
505 0x72D8, 0x626D, 0x72DA, 0xF2DB, 0x72DC, 0x626F, 0x72DE, 0xF2DF,
506 0x73E0, 0x6371, 0x73E2, 0xF3E3, 0x73E4, 0x6373, 0x73E6, 0xF3E7,
507 0x73E8, 0x6375, 0x73EA, 0xF3EB, 0x73EC, 0x6377, 0x73EE, 0xF3EF,
508 0x74F0, 0x6479, 0x74F2, 0xF4F3, 0x74F4, 0x647B, 0x74F6, 0xF4F7,
509 0x75F8, 0x657D, 0x75FA, 0xF5FB, 0xF6FC, 0xE67F, 0xF7FE, 0xFCFF,
510 };
511
512
513 static WORD destuff5[] =
514 {
515 0x6000, 0xF001, 0x6001, 0xF003, 0x6002, 0xF005, 0x6003, 0xF007,
516 0x6004, 0xF009, 0x6005, 0xF00B, 0x6006, 0xF00D, 0x6007, 0xF00F,
517 0x6008, 0xF011, 0x6009, 0xF013, 0x600A, 0xF015, 0x600B, 0xF017,
518 0x600C, 0xF019, 0x600D, 0xF01B, 0x600E, 0xF01D, 0x600F, 0xF01F,
519 0x6010, 0xF021, 0x6011, 0xF023, 0x6012, 0xF025, 0x6013, 0xF027,
520 0x6014, 0xF029, 0x6015, 0xF02B, 0x6016, 0xF02D, 0x6017, 0xF02F,
521 0x6018, 0xF031, 0x6019, 0xF033, 0x601A, 0xF035, 0x601B, 0xF037,
522 0x601C, 0xF039, 0x601D, 0xF03B, 0x601E, 0xF03D, 0x501F, 0xF03F,
523 0x6020, 0xF041, 0x6021, 0xF043, 0x6022, 0xF045, 0x6023, 0xF047,
524 0x6024, 0xF049, 0x6025, 0xF04B, 0x6026, 0xF04D, 0x6027, 0xF04F,
525 0x6028, 0xF051, 0x6029, 0xF053, 0x602A, 0xF055, 0x602B, 0xF057,
526 0x602C, 0xF059, 0x602D, 0xF05B, 0x602E, 0xF05D, 0x602F, 0xF05F,
527 0x6030, 0xF061, 0x6031, 0xF063, 0x6032, 0xF065, 0x6033, 0xF067,
528 0x6034, 0xF069, 0x6035, 0xF06B, 0x6036, 0xF06D, 0x6037, 0xF06F,
529 0x6038, 0xF071, 0x6039, 0xF073, 0x603A, 0xF075, 0x603B, 0xF077,
530 0x603C, 0xF079, 0x603D, 0xF07B, 0x503E, 0xE07D, 0xE03F, 0xF07F,
531 0x6140, 0xF181, 0x6141, 0xF183, 0x6142, 0xF185, 0x6143, 0xF187,
532 0x6144, 0xF189, 0x6145, 0xF18B, 0x6146, 0xF18D, 0x6147, 0xF18F,
533 0x6148, 0xF191, 0x6149, 0xF193, 0x614A, 0xF195, 0x614B, 0xF197,
534 0x614C, 0xF199, 0x614D, 0xF19B, 0x614E, 0xF19D, 0x614F, 0xF19F,
535 0x6150, 0xF1A1, 0x6151, 0xF1A3, 0x6152, 0xF1A5, 0x6153, 0xF1A7,
536 0x6154, 0xF1A9, 0x6155, 0xF1AB, 0x6156, 0xF1AD, 0x6157, 0xF1AF,
537 0x6158, 0xF1B1, 0x6159, 0xF1B3, 0x615A, 0xF1B5, 0x615B, 0xF1B7,
538 0x615C, 0xF1B9, 0x615D, 0xF1BB, 0x615E, 0xF1BD, 0x513F, 0xF1BF,
539 0x6260, 0xF2C1, 0x6261, 0xF2C3, 0x6262, 0xF2C5, 0x6263, 0xF2C7,
540 0x6264, 0xF2C9, 0x6265, 0xF2CB, 0x6266, 0xF2CD, 0x6267, 0xF2CF,
541 0x6268, 0xF2D1, 0x6269, 0xF2D3, 0x626A, 0xF2D5, 0x626B, 0xF2D7,
542 0x626C, 0xF2D9, 0x626D, 0xF2DB, 0x626E, 0xF2DD, 0x626F, 0xF2DF,
543 0x6370, 0xF3E1, 0x6371, 0xF3E3, 0x6372, 0xF3E5, 0x6373, 0xF3E7,
544 0x6374, 0xF3E9, 0x6375, 0xF3EB, 0x6376, 0xF3ED, 0x6377, 0xF3EF,
545 0x6478, 0xF4F1, 0x6479, 0xF4F3, 0x647A, 0xF4F5, 0x647B, 0xF4F7,
546 0x657C, 0xF5F9, 0x657D, 0xF5FB, 0xE67E, 0xF6FD, 0xE77F, 0xFDFF,
547 };
548
549
550 static WORD * stuffs[] = { stuff0, stuff1, stuff2, stuff3, stuff4, stuff5 };
551 WORD * destuffs[] = { destuff0, destuff1, destuff2, destuff3, destuff4, destuff5 };
552
553
554 /*- AuverTech Telecom -------------------------------------------------------+
555 | |
556 | @Function : tpam_hdlc_encode |
557 | @Author : Cyrille Boudon |
558 | |
559 +---------------------------------------------------------------------------+
560 | |
561 | @Param : BYTE *pbyBuffIn IN, array of bytes to encode |
562 | @Param : BYTE *pbyBuffOut OUT, array of bytes encoded |
563 | @Param : DWORD *pdwInitialShift INOUT, initial shift |
564 | @Param : DWORD dwLength IN, count of bytes to encode |
565 | |
566 | @Return : DWORD count of bytes encoded |
567 | |
568 +------------------------------- @Abstract ---------------------------------+
569 | |
570 | Bit stuffing of thz array pbyBuffIn with the insertion of a flag at the |
571 | beginning and the end, using the initial shift (due to the emission of |
572 | previous frames). The last byte can be used to insert flags (by outputting|
573 | the flag N times) before the next frame. The initial shift is updated at |
574 | the end of the algorithm for the next frame. Its signification is: for the|
575 | flags shifted like "1100111111001111" *pdwInitialShift = 3. At the |
576 | beginning (for the first frame), the shift must be initialized to 0. |
577 | |
578 +---------------------------------------------------------------------------*/
tpam_hdlc_encode(BYTE * pbyBuffIn,BYTE * pbyBuffOut,DWORD * pdwInitialShift,DWORD dwLength)579 DWORD tpam_hdlc_encode(BYTE *pbyBuffIn, BYTE *pbyBuffOut,
580 DWORD *pdwInitialShift, DWORD dwLength)
581 {
582 DWORD dwShifter; // temporary variable
583 DWORD dwShiftNb; // shift due to the insertion of '0'
584 DWORD dwState; // count of '1' at the end of the current byte
585 DWORD dwNb; // length of the encoded array
586 BYTE byCarry; // carry due to the shift
587 BYTE byNewCarry; // temporary variable
588 BYTE byCharIn; // byte being encoded
589 BYTE byCarryMSB; // lost bit of the carry if dwShiftNb=7 and 2 '0' inserted
590 WORD woDecal; // temporary variable
591 WORD woInfo; // data read in the arrays
592 BOOL bContinue; // true until the two last bytes
593 BOOL bContinue2; // true until the last byte
594
595 bContinue = TRUE;
596 bContinue2 = TRUE;
597 dwShiftNb = 0;
598 byCarry = 0;
599 dwState = 0;
600 woDecal = 0x7E;
601 byCarryMSB = 0xFF;
602 dwNb = 1; // length to 1 to account for the first flag
603
604 /*-----------------------------
605 | insert the flag using the
606 | shift given by
607 | *pdwInitialShift)
608 +-----------------------------*/
609 * pbyBuffOut ++ = 0x7E7E >> *pdwInitialShift;
610
611 /*-----------------------------
612 | main loop
613 +-----------------------------*/
614 while (dwLength--)
615 {
616 byCharIn = *pbyBuffIn ++;
617
618 /*-----------------------------
619 | go back here to treat the
620 | carry when its length
621 | is over 7 and for the first
622 | byte (with flag)
623 +-----------------------------*/
624 carry:
625
626 dwNb ++;
627
628 /*-----------------------------
629 | shift the byte to get the
630 | byte to encode (without
631 | taking into account the
632 | initial shift)
633 +-----------------------------*/
634 if (dwShiftNb)
635 {
636 dwShifter = byCharIn << dwShiftNb;
637 byNewCarry = dwShifter >> 8;
638 byCharIn = dwShifter | byCarry;
639 byCarry = byNewCarry;
640 }
641
642 /*-----------------------------
643 | get the data from the arrays
644 | and take into account the
645 | initial shift for the byte
646 | to encode
647 +-----------------------------*/
648 woInfo = stuffs[dwState][byCharIn];
649 woDecal |= (woInfo & 0x00FF) << 8;
650 * pbyBuffOut ++ = woDecal >> *pdwInitialShift;
651 woDecal = woInfo & 0x00FF;
652 dwState = woInfo >> 12;
653
654 /*-----------------------------
655 | treat the lost bit if we had
656 | a carry overflow
657 +-----------------------------*/
658 if (byCarryMSB != 0xFF)
659 {
660 if (!dwShiftNb)
661 {
662 if(byCarryMSB)
663 byCarry = 1;
664 dwShiftNb = 1;
665 }
666 byCarryMSB = 0xFF;
667 }
668
669 /*-----------------------------
670 | if one '0' get inserted, we
671 | have to calculate the new
672 | carry and the new shift
673 +-----------------------------*/
674 if (woInfo & 0x0F00)
675 {
676 byCarryMSB = byCarry & 0x40;
677 byCarry <<= (woInfo & 0x0C00) >> 10;
678 byCarry |= (woInfo & 0x0300) >> 8;
679 dwShiftNb += (woInfo & 0x0C00) >> 10;
680 }
681
682 /*-----------------------------
683 | if the carry is a whole byte
684 | we use it as a byte to encode
685 +-----------------------------*/
686 if (dwShiftNb > 7)
687 {
688 if (dwShiftNb == 8)
689 byCarryMSB = 0xFF;
690 dwShiftNb = 0;
691 byCharIn = byCarry;
692 byCarry = 0;
693 goto carry;
694 }
695
696 /*-----------------------------
697 | at the end of the array
698 +-----------------------------*/
699 if (!dwLength)
700 {
701 /*-----------------------------
702 | take into account the bits
703 | set in the carry
704 +-----------------------------*/
705 if (bContinue)
706 {
707 bContinue = FALSE;
708 byCharIn = 0;
709 goto carry;
710 }
711
712 /*-----------------------------
713 | treat the last byte if we
714 | had a carry overflow
715 +-----------------------------*/
716 if (bContinue2 && ((8 - *pdwInitialShift) + dwShiftNb) > 7)
717 {
718 bContinue2 = FALSE;
719 byCharIn = 0;
720 goto carry;
721 }
722
723 /*-----------------------------
724 | Calculate the new shift
725 +-----------------------------*/
726 *pdwInitialShift = ((8 - *pdwInitialShift) + dwShiftNb)%8;
727
728 /*-----------------------------
729 | Add a flag at the end of the
730 | carry and a full flag
731 +-----------------------------*/
732 pbyBuffOut--;
733 *pbyBuffOut++ |= 0x7E << *pdwInitialShift;
734 byCarry = 0x7E7E >> (8 - *pdwInitialShift);
735 *pbyBuffOut++ = byCarry;
736 *pbyBuffOut++ = byCarry;
737 dwNb += 2;
738 }
739 }
740
741 /*-------------------------------
742 | Pad the array to a multiple
743 | of 64 bytes.
744 +-------------------------------*/
745 for(;dwNb%64;dwNb++)
746 *pbyBuffOut ++ = byCarry;
747
748 *pdwInitialShift = (8 - *pdwInitialShift)%8;
749
750 return dwNb;
751 }
752
753
754
755 /*- AuverTech Telecom -------------------------------------------------------+
756 | |
757 | @Function : tpam_hdlc_decode |
758 | @Author : Cyrille Boudon |
759 | |
760 +---------------------------------------------------------------------------+
761 | |
762 | @Param : BYTE * pbyBuffIn IN, array of bytes to decode |
763 | @Param : BYTE * pbyBuffOut OUT, array of decoded bytes |
764 | @Param : DWORD dwLength IN, count of bytes to decode |
765 | |
766 | @Return : DWORD count of decoded bytes |
767 | |
768 +------------------------------- @Abstract ---------------------------------+
769 | |
770 | Bit de-stuffing of the array pbyBuffIn. There has to be at least 1 full |
771 | flag at the beginning. At the end there has to be a flag or an abort (more|
772 | than 6 consecutive '1'). |
773 | If an abort is encountered, the returned count is '0'. |
774 | |
775 +---------------------------------------------------------------------------*/
tpam_hdlc_decode(BYTE * pbyBuffIn,BYTE * pbyBuffOut,DWORD dwLength)776 DWORD tpam_hdlc_decode(BYTE * pbyBuffIn, BYTE * pbyBuffOut, DWORD dwLength)
777 {
778 BYTE byCharIn; // byte being decoded
779 BYTE byCarry; // current carry
780 WORD woInfo; // data read in the arrays
781 WORD woNb1; // count of '1' at the end of the previous byte
782 BYTE byShift; // shift of the first flag
783 DWORD dwInit; // temporary variable
784 DWORD dwLengthOut; // count of the decoded bytes
785 BYTE byLgCarry; // count of used bits in the carry
786 BYTE byLgByte; // count of used bits in the decoded byte
787
788 /*-----------------------------
789 | Find the 1st flag. At the end
790 | of the loop dwShift is the count
791 | of bits to reach the 1st bit
792 | of the 1st flag.
793 +-----------------------------*/
794 dwInit = *pbyBuffIn | (*(pbyBuffIn+1)<<8) | (*(pbyBuffIn+2)<<16);
795 for (byShift=0;byShift<17;byShift++)
796 {
797 if (!(((dwInit>>byShift)&0xFF)^0x7E))
798 {
799 break;
800 }
801 }
802
803 /*-----------------------------
804 | If at the end of the previous
805 | loop dwShift = 17, it means
806 | that no flag was found in the
807 | first 3 bytes (normally
808 | impossible impossible with the
809 | DSP algorithm)
810 +-----------------------------*/
811 if (byShift == 17)
812 return 0;
813
814 /*-----------------------------
815 | Plase the array pointer after
816 | the first flag. Update the
817 | shift.
818 +-----------------------------*/
819 pbyBuffIn += byShift/8 + 1;
820 dwLength -= byShift/8 + 1;
821 byShift %= 8;
822
823 /*-----------------------------
824 | Walk through the frame to
825 | find the first data byte
826 +-----------------------------*/
827 dwInit = *pbyBuffIn | (*(pbyBuffIn+1)<<8);
828 while (!(((dwInit>>byShift)&0xFF)^0x7E))
829 {
830 pbyBuffIn ++;
831 dwLength --;
832 dwInit = *pbyBuffIn | (*(pbyBuffIn+1)<<8);
833 }
834
835 dwLengthOut = 0;
836 byCarry = 0;
837 byLgCarry = 0;
838 byLgByte = 0;
839
840 /*-------------------------------
841 | Treat the first byte
842 +-------------------------------*/
843 byCharIn = (*pbyBuffIn >> byShift) << byShift;
844 woInfo = destuffs[0][byCharIn];
845 byLgByte = ((woInfo & 0x7000) >> 12) + 1;
846 woNb1 = (woInfo & 0x0F00) >> 8;
847 dwLength --;
848 pbyBuffIn++;
849
850 if (woNb1 > 5)
851 return 0;
852
853 if (byLgByte - byShift == 8)
854 {
855 *pbyBuffOut ++ = woInfo;
856 dwLengthOut ++;
857 }
858 else
859 {
860 byCarry = woInfo << (8 - byLgByte);
861 byLgCarry = byLgByte - byShift;
862 }
863
864 /*-------------------------------
865 | main loop
866 +-------------------------------*/
867 while(dwLength --)
868 {
869 byCharIn = *pbyBuffIn ++;
870
871 woInfo = destuffs[woNb1][byCharIn];
872 byLgByte = ((woInfo & 0x7000) >> 12) + 1;
873
874 /*-------------------------------
875 | if the used bits in the carry
876 | and the current byte makes
877 | possible to output a full byte
878 +-------------------------------*/
879 if (byLgByte + byLgCarry >= 8)
880 {
881 *pbyBuffOut ++ = ( (woInfo << 8) | byCarry) >> (8 - byLgCarry);
882 dwLengthOut ++;
883 byLgCarry += byLgByte - 8;
884 byCarry = woInfo << (8-byLgByte);
885 }
886 /*-------------------------------
887 | if the used bits in the carry
888 | and the current byte doesn't
889 | make possible to output a full
890 | byte
891 +-------------------------------*/
892 else
893 {
894 dwInit = (woInfo << 8) | byCarry;
895 byLgCarry += byLgByte;
896 byCarry = dwInit >> byLgByte;
897 }
898
899 woNb1 = (woInfo & 0x0F00) >> 8;
900
901 /*-------------------------------
902 | if the current byte contains
903 | six or more consecutive '1'
904 +-------------------------------*/
905 if (woInfo & 0x8000)
906 {
907 byCarry = ((byCharIn << 8) | *(pbyBuffIn-2)) >> (8 - byLgCarry);
908 if (byCarry == 0x7E)
909 return dwLengthOut-1;
910 else
911 if (woNb1 > 6)
912 return 0;
913 else
914 if ((!(*pbyBuffIn & 1)) && (byLgCarry == 7))
915 return dwLengthOut;
916 else
917 return 0;
918 }
919 }
920
921 return dwLengthOut;
922 }
923
924