1 /* endian.c */
2 /*****************************************************************************/
3 /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
4 /* */
5 /* AS-Portierung */
6 /* */
7 /* Little/Big-Endian-Routinen */
8 /* */
9 /*****************************************************************************/
10
11 #include "stdinc.h"
12
13 #include <string.h>
14
15 #include "endian.h"
16
17 /*****************************************************************************/
18
19 Boolean BigEndian;
20
21 const char *Integ16Format, *Integ32Format, *Integ64Format;
22 const char *IntegerFormat, *LongIntFormat, *QuadIntFormat;
23 const char *LargeIntFormat, *LargeHIntFormat;
24
25 /*****************************************************************************/
26
WSwap(void * Field,int Cnt)27 void WSwap(void *Field, int Cnt)
28 {
29 register unsigned char *Run = (unsigned char *) Field, Swap;
30 register int z;
31
32 for (z = 0; z < Cnt / 2; z++, Run += 2)
33 {
34 Swap = Run[0];
35 Run[0] = Run[1];
36 Run[1] = Swap;
37 }
38 }
39
DSwap(void * Field,int Cnt)40 void DSwap(void *Field, int Cnt)
41 {
42 register unsigned char *Run = (unsigned char *) Field, Swap;
43 register int z;
44
45 for (z = 0; z < Cnt / 4; z++, Run += 4)
46 {
47 Swap = Run[0]; Run[0] = Run[3]; Run[3] = Swap;
48 Swap = Run[1]; Run[1] = Run[2]; Run[2] = Swap;
49 }
50 }
51
QSwap(void * Field,int Cnt)52 void QSwap(void *Field, int Cnt)
53 {
54 register unsigned char *Run = (unsigned char *) Field, Swap;
55 register int z;
56
57 for (z = 0; z < Cnt / 8; z++, Run += 8)
58 {
59 Swap = Run[0]; Run[0] = Run[7]; Run[7] = Swap;
60 Swap = Run[1]; Run[1] = Run[6]; Run[6] = Swap;
61 Swap = Run[2]; Run[2] = Run[5]; Run[5] = Swap;
62 Swap = Run[3]; Run[3] = Run[4]; Run[4] = Swap;
63 }
64 }
65
TSwap(void * Field,int Cnt)66 void TSwap(void *Field, int Cnt)
67 {
68 register unsigned char *Run = (unsigned char *) Field, Swap;
69 register int z;
70
71 for (z = 0; z < Cnt / 10; z++, Run += 10)
72 {
73 Swap = Run[0]; Run[0] = Run[9]; Run[9] = Swap;
74 Swap = Run[1]; Run[1] = Run[8]; Run[8] = Swap;
75 Swap = Run[2]; Run[2] = Run[7]; Run[7] = Swap;
76 Swap = Run[3]; Run[3] = Run[6]; Run[6] = Swap;
77 Swap = Run[4]; Run[4] = Run[5]; Run[5] = Swap;
78 }
79 }
80
DWSwap(void * Field,int Cnt)81 void DWSwap(void *Field, int Cnt)
82 {
83 register unsigned char *Run = (unsigned char *) Field, Swap;
84 register int z;
85
86 for (z = 0; z < Cnt / 4; z++, Run += 4)
87 {
88 Swap = Run[0]; Run[0] = Run[2]; Run[2] = Swap;
89 Swap = Run[1]; Run[1] = Run[3]; Run[3] = Swap;
90 }
91 }
92
QWSwap(void * Field,int Cnt)93 void QWSwap(void *Field, int Cnt)
94 {
95 register unsigned char *Run = (unsigned char *) Field, Swap;
96 register int z;
97
98 for (z = 0; z < Cnt / 8; z++, Run += 8)
99 {
100 Swap = Run[0]; Run[0] = Run[6]; Run[6] = Swap;
101 Swap = Run[1]; Run[1] = Run[7]; Run[7] = Swap;
102 Swap = Run[2]; Run[2] = Run[4]; Run[4] = Swap;
103 Swap = Run[3]; Run[3] = Run[5]; Run[5] = Swap;
104 }
105 }
106
Read2(FILE * file,void * Ptr)107 Boolean Read2(FILE *file, void *Ptr)
108 {
109 if (fread(Ptr, 1, 2, file) != 2)
110 return False;
111 if (BigEndian)
112 WSwap(Ptr, 2);
113 return True;
114 }
115
Read4(FILE * file,void * Ptr)116 Boolean Read4(FILE *file, void *Ptr)
117 {
118 if (fread(Ptr, 1, 4, file) != 4)
119 return False;
120 if (BigEndian)
121 DSwap(Ptr, 4);
122 return True;
123 }
124
Read8(FILE * file,void * Ptr)125 Boolean Read8(FILE *file, void *Ptr)
126 {
127 if (fread(Ptr, 1, 8, file) != 8)
128 return False;
129 if (BigEndian)
130 QSwap(Ptr, 8);
131 return True;
132 }
133
134
Write2(FILE * file,void * Ptr)135 Boolean Write2(FILE *file, void *Ptr)
136 {
137 Boolean OK;
138
139 if (BigEndian)
140 WSwap(Ptr, 2);
141 OK = (fwrite(Ptr, 1, 2, file) == 2);
142 if (BigEndian)
143 WSwap(Ptr, 2);
144 return OK;
145 }
146
Write4(FILE * file,void * Ptr)147 Boolean Write4(FILE *file, void *Ptr)
148 {
149 Boolean OK;
150
151 if (BigEndian)
152 DSwap(Ptr, 4);
153 OK = (fwrite(Ptr, 1, 4, file) == 4);
154 if (BigEndian)
155 DSwap(Ptr, 4);
156 return OK;
157 }
158
Write8(FILE * file,void * Ptr)159 Boolean Write8(FILE *file, void *Ptr)
160 {
161 Boolean OK;
162
163 if (BigEndian)
164 QSwap(Ptr, 8);
165 OK = (fwrite(Ptr, 1, 8, file) == 8);
166 if (BigEndian)
167 QSwap(Ptr, 8);
168 return OK;
169 }
170
171
MRead2L(Byte * Buffer)172 Word MRead2L(Byte *Buffer)
173 {
174 return (((Word) Buffer[1]) << 8) | Buffer[0];
175 }
176
MRead2B(Byte * Buffer)177 Word MRead2B(Byte *Buffer)
178 {
179 return (((Word) Buffer[0]) << 8) | Buffer[1];
180 }
181
MWrite2L(Byte * Buffer,Word Value)182 void MWrite2L(Byte *Buffer, Word Value)
183 {
184 Buffer[0] = Value & 0xff;
185 Buffer[1] = (Value >> 8) & 0xff;
186 }
187
MWrite2B(Byte * Buffer,Word Value)188 void MWrite2B(Byte *Buffer, Word Value)
189 {
190 Buffer[1] = Value & 0xff;
191 Buffer[0] = (Value >> 8) & 0xff;
192 }
193
MRead4L(Byte * Buffer)194 LongWord MRead4L(Byte *Buffer)
195 {
196 return (((LongWord) Buffer[3]) << 24) |
197 (((LongWord) Buffer[2]) << 16) |
198 (((LongWord) Buffer[1]) << 8) | Buffer[0];
199 }
200
MRead4B(Byte * Buffer)201 LongWord MRead4B(Byte *Buffer)
202 {
203 return (((LongWord) Buffer[0]) << 24) |
204 (((LongWord) Buffer[1]) << 16) |
205 (((LongWord) Buffer[2]) << 8) | Buffer[3];
206 }
207
MWrite4L(Byte * Buffer,LongWord Value)208 void MWrite4L(Byte *Buffer, LongWord Value)
209 {
210 Buffer[0] = Value & 0xff;
211 Buffer[1] = (Value >> 8) & 0xff;
212 Buffer[2] = (Value >> 16) & 0xff;
213 Buffer[3] = (Value >> 24) & 0xff;
214 }
215
MWrite4B(Byte * Buffer,LongWord Value)216 void MWrite4B(Byte *Buffer, LongWord Value)
217 {
218 Buffer[3] = Value & 0xff;
219 Buffer[2] = (Value >> 8) & 0xff;
220 Buffer[1] = (Value >> 16) & 0xff;
221 Buffer[0] = (Value >> 24) & 0xff;
222 }
223
224 #ifdef HAS64
MRead8L(Byte * Buffer)225 QuadWord MRead8L(Byte *Buffer)
226 {
227 return (((LargeWord) Buffer[7]) << 56) |
228 (((LargeWord) Buffer[6]) << 48) |
229 (((LargeWord) Buffer[5]) << 40) |
230 (((LargeWord) Buffer[4]) << 32) |
231 (((LargeWord) Buffer[3]) << 24) |
232 (((LargeWord) Buffer[2]) << 16) |
233 (((LargeWord) Buffer[1]) << 8) |
234 Buffer[0];
235 }
236
MRead8B(Byte * Buffer)237 QuadWord MRead8B(Byte *Buffer)
238 {
239 return (((LargeWord) Buffer[0]) << 56) |
240 (((LargeWord) Buffer[1]) << 48) |
241 (((LargeWord) Buffer[2]) << 40) |
242 (((LargeWord) Buffer[3]) << 32) |
243 (((LargeWord) Buffer[4]) << 24) |
244 (((LargeWord) Buffer[7]) << 16) |
245 (((LargeWord) Buffer[6]) << 8) |
246 Buffer[7];
247 }
248
MWrite8L(Byte * Buffer,QuadWord Value)249 void MWrite8L(Byte *Buffer, QuadWord Value)
250 {
251 Buffer[0] = Value & 0xff;
252 Buffer[1] = (Value >> 8) & 0xff;
253 Buffer[2] = (Value >> 16) & 0xff;
254 Buffer[3] = (Value >> 24) & 0xff;
255 Buffer[4] = (Value >> 32) & 0xff;
256 Buffer[5] = (Value >> 40) & 0xff;
257 Buffer[6] = (Value >> 48) & 0xff;
258 Buffer[7] = (Value >> 56) & 0xff;
259 }
260
MWrite8B(Byte * Buffer,QuadWord Value)261 void MWrite8B(Byte *Buffer, QuadWord Value)
262 {
263 Buffer[7] = Value & 0xff;
264 Buffer[6] = (Value >> 8) & 0xff;
265 Buffer[5] = (Value >> 16) & 0xff;
266 Buffer[4] = (Value >> 24) & 0xff;
267 Buffer[3] = (Value >> 32) & 0xff;
268 Buffer[2] = (Value >> 40) & 0xff;
269 Buffer[1] = (Value >> 48) & 0xff;
270 Buffer[0] = (Value >> 56) & 0xff;
271 }
272 #endif
273
274
CheckSingle(int Is,int Should,const char * Name)275 static void CheckSingle(int Is, int Should, const char *Name)
276 {
277 if (Is != Should)
278 {
279 fprintf(stderr, "Configuration error: Sizeof(%s) is %d, should be %d\n",
280 Name, Is, Should);
281 exit(255);
282 }
283 }
284
CheckDataTypes(void)285 static void CheckDataTypes(void)
286 {
287 int intsize = sizeof(int);
288
289 if (intsize < 2)
290 {
291 fprintf(stderr, "Configuration error: Sizeof(int) is %d, should be >=2\n",
292 (int) sizeof(int));
293 exit(255);
294 }
295 CheckSingle(sizeof(Byte), 1, "Byte");
296 CheckSingle(sizeof(ShortInt), 1, "ShortInt");
297 #ifdef HAS16
298 CheckSingle(sizeof(Word), 2, "Word");
299 CheckSingle(sizeof(Integer), 2, "Integer");
300 #endif
301 CheckSingle(sizeof(LongInt), 4, "LongInt");
302 CheckSingle(sizeof(LongWord), 4, "LongWord");
303 #ifdef HAS64
304 CheckSingle(sizeof(QuadInt), 8, "QuadInt");
305 CheckSingle(sizeof(QuadWord), 8, "QuadWord");
306 #endif
307 CheckSingle(sizeof(Single), 4, "Single");
308 CheckSingle(sizeof(Double), 8, "Double");
309 }
310
311
AssignSingle(int size)312 static const char *AssignSingle(int size)
313 {
314 if (size == sizeof(short))
315 return "%d";
316 else if (size == sizeof(int))
317 return "%d";
318 else if (size == sizeof(long))
319 return "%ld";
320 #ifndef NOLONGLONG
321 else if (size == sizeof(long long))
322 return "%lld";
323 #endif
324 else
325 {
326 fprintf(stderr,
327 "Configuration error: cannot assign format string for integer of size %d\n", size);
328 exit(255);
329 return "";
330 }
331 }
332
AssignHSingle(int size)333 static const char *AssignHSingle(int size)
334 {
335 if (size == sizeof(short))
336 return "%x";
337 else if (size == sizeof(int))
338 return "%x";
339 else if (size == sizeof(long))
340 return "%lx";
341 #ifndef NOLONGLONG
342 else if (size == sizeof(long long))
343 return "%llx";
344 #endif
345 else
346 {
347 fprintf(stderr,
348 "Configuration error: cannot assign format string for integer of size %d\n", size);
349 exit(255);
350 return "";
351 }
352 }
353
AssignFormats(void)354 static void AssignFormats(void)
355 {
356 #ifdef HAS16
357 IntegerFormat = Integ16Format = AssignSingle(2);
358 #endif
359 LongIntFormat = Integ32Format = AssignSingle(4);
360 #ifdef HAS64
361 QuadIntFormat = Integ64Format = AssignSingle(8);
362 #endif
363 LargeIntFormat = AssignSingle(sizeof(LargeInt));
364 LargeHIntFormat = AssignHSingle(sizeof(LargeInt));
365 }
366
endian_init(void)367 void endian_init(void)
368 {
369 union
370 {
371 unsigned char field[sizeof(int)];
372 int test;
373 } TwoFace;
374
375 CheckDataTypes();
376 AssignFormats();
377
378 memset(TwoFace.field, 0, sizeof(int));
379 TwoFace.field[0] = 1;
380 BigEndian = ((TwoFace.test) != 1);
381 }
382