File: /usr/src/linux/drivers/isdn/tpam/tpam_hdlc.c

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