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