1 //
2 // /home/ms/source/sidplay/libsidplay/include/RCS/myendian.h,v
3 //
4 
5 #ifndef SIDPLAY1_MYENDIAN_H
6 #define SIDPLAY1_MYENDIAN_H
7 
8 
9 #include "compconf.h"
10 #include "mytypes.h"
11 
12 // This should never be true.
13 #if defined(LO) || defined(HI) || defined(LOLO) || defined(LOHI) || defined(HILO) || defined(HIHI)
14   #error Redefinition of these values can cause trouble.
15 #endif
16 
17 // For optional direct memory access.
18 // First value in memory/array = index 0.
19 // Second value in memory/array = index 1.
20 
21 // For a pair of bytes/words/longwords.
22 #undef LO
23 #undef HI
24 
25 // For two pairs of bytes/words/longwords.
26 #undef LOLO
27 #undef LOHI
28 #undef HILO
29 #undef HIHI
30 
31 #if defined(SID_WORDS_BIGENDIAN)
32 // byte-order: HI..3210..LO
33   #define LO 1
34   #define HI 0
35   #define LOLO 3
36   #define LOHI 2
37   #define HILO 1
38   #define HIHI 0
39 #elif defined(SID_WORDS_LITTLEENDIAN)
40 // byte-order: LO..0123..HI
41   #define LO 0
42   #define HI 1
43   #define LOLO 0
44   #define LOHI 1
45   #define HILO 2
46   #define HIHI 3
47 #else
48   #error Please check header file libcfg.h!
49 #endif
50 
51 union cpuLword
52 {
53 	uword w[2];  // single 16-bit low and high word
54 	udword l;    // complete 32-bit longword
55 };
56 
57 union cpuWord
58 {
59 	ubyte b[2];  // single 8-bit low and high byte
60 	uword w;     // complete 16-bit word
61 };
62 
63 union cpuLBword
64 {
65 	ubyte b[4];  // single 8-bit bytes
66 	udword l;    // complete 32-bit longword
67 };
68 
69 // Convert high-byte and low-byte to 16-bit word.
70 // Used to read 16-bit words in little-endian order.
readEndian(ubyte hi,ubyte lo)71 inline uword readEndian(ubyte hi, ubyte lo)
72 {
73   return(( (uword)hi << 8 ) + (uword)lo );
74 }
75 
76 // Convert high bytes and low bytes of MSW and LSW to 32-bit word.
77 // Used to read 32-bit words in little-endian order.
readEndian(ubyte hihi,ubyte hilo,ubyte hi,ubyte lo)78 inline udword readEndian(ubyte hihi, ubyte hilo, ubyte hi, ubyte lo)
79 {
80   return(( (udword)hihi << 24 ) + ( (udword)hilo << 16 ) +
81 		 ( (udword)hi << 8 ) + (udword)lo );
82 }
83 
84 // Read a little-endian 16-bit word from two bytes in memory.
readLEword(const ubyte ptr[2])85 inline uword readLEword(const ubyte ptr[2])
86 {
87 #if defined(SID_WORDS_LITTLEENDIAN) && defined(OPTIMIZE_ENDIAN_ACCESS)
88 	return *((uword*)ptr);
89 #else
90 	return readEndian(ptr[1],ptr[0]);
91 #endif
92 }
93 
94 // Write a big-endian 16-bit word to two bytes in memory.
writeLEword(ubyte ptr[2],uword someWord)95 inline void writeLEword(ubyte ptr[2], uword someWord)
96 {
97 #if defined(SID_WORDS_LITTLEENDIAN) && defined(OPTIMIZE_ENDIAN_ACCESS)
98 	*((uword*)ptr) = someWord;
99 #else
100 	ptr[0] = (someWord & 0xFF);
101 	ptr[1] = (someWord >> 8);
102 #endif
103 }
104 
105 
106 
107 // Read a big-endian 16-bit word from two bytes in memory.
readBEword(const ubyte ptr[2])108 inline uword readBEword(const ubyte ptr[2])
109 {
110 #if defined(SID_WORDS_BIGENDIAN) && defined(OPTIMIZE_ENDIAN_ACCESS)
111 	return *((uword*)ptr);
112 #else
113 	return ( (((uword)ptr[0])<<8) + ((uword)ptr[1]) );
114 #endif
115 }
116 
117 // Read a big-endian 32-bit word from four bytes in memory.
readBEdword(const ubyte ptr[4])118 inline udword readBEdword(const ubyte ptr[4])
119 {
120 #if defined(SID_WORDS_BIGENDIAN) && defined(OPTIMIZE_ENDIAN_ACCESS)
121 	return *((udword*)ptr);
122 #else
123 	return ( (((udword)ptr[0])<<24) + (((udword)ptr[1])<<16)
124 			+ (((udword)ptr[2])<<8) + ((udword)ptr[3]) );
125 #endif
126 }
127 
128 // Write a big-endian 16-bit word to two bytes in memory.
writeBEword(ubyte ptr[2],uword someWord)129 inline void writeBEword(ubyte ptr[2], uword someWord)
130 {
131 #if defined(SID_WORDS_BIGENDIAN) && defined(OPTIMIZE_ENDIAN_ACCESS)
132 	*((uword*)ptr) = someWord;
133 #else
134 	ptr[0] = someWord >> 8;
135 	ptr[1] = someWord & 0xFF;
136 #endif
137 }
138 
139 // Write a big-endian 32-bit word to four bytes in memory.
writeBEdword(ubyte ptr[4],udword someDword)140 inline void writeBEdword(ubyte ptr[4], udword someDword)
141 {
142 #if defined(SID_WORDS_BIGENDIAN) && defined(OPTIMIZE_ENDIAN_ACCESS)
143 	*((udword*)ptr) = someDword;
144 #else
145 	ptr[0] = someDword >> 24;
146 	ptr[1] = (someDword>>16) & 0xFF;
147 	ptr[2] = (someDword>>8) & 0xFF;
148 	ptr[3] = someDword & 0xFF;
149 #endif
150 }
151 
152 
153 
154 // Convert 16-bit little-endian word to big-endian order or vice versa.
convertEndianess(uword intelword)155 inline uword convertEndianess( uword intelword )
156 {
157 	uword hi = intelword >> 8;
158 	uword lo = intelword & 255;
159 	return(( lo << 8 ) + hi );
160 }
161 
162 // Convert 32-bit little-endian word to big-endian order or vice versa.
convertEndianess(udword inteldword)163 inline udword convertEndianess( udword inteldword )
164 {
165 	udword hihi = inteldword >> 24;
166 	udword hilo = ( inteldword >> 16 ) & 0xFF;
167 	udword hi = ( inteldword >> 8 ) & 0xFF;
168 	udword lo = inteldword & 0xFF;
169 	return(( lo << 24 ) + ( hi << 16 ) + ( hilo << 8 ) + hihi );
170 }
171 
172 
173 #endif  /* SIDPLAY1_MYENDIAN_H */
174