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