libsidplayfp
1.0.3
|
00001 /* 00002 * This file is part of libsidplayfp, a SID player engine. 00003 * 00004 * Copyright 2000 Simon White 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 */ 00020 00021 00022 #ifndef SIDENDIAN_H 00023 #define SIDENDIAN_H 00024 00025 #ifdef HAVE_CONFIG_H 00026 # include "config.h" 00027 #endif 00028 00029 // NOTE: The optimisations in this file rely on the structure of memory 00030 // e.g. 2 shorts being contained in 1 long. Although these sizes are 00031 // checked to make sure the optimisation is ok, gcc 2.96 (and above) 00032 // introduced better optimisations. This results in caching of values 00033 // in internal registers and therefore writes to ram through the aliases 00034 // not being reflected in the CPU regs. The use of the volatile keyword 00035 // fixes this. 00036 00037 #include <stdint.h> 00038 00039 /* 00040 Labeling: 00041 0 - LO 00042 1 - HI 00043 2 - HILO 00044 3 - HIHI 00045 */ 00046 00048 // INT16 FUNCTIONS 00050 // Set the lo byte (8 bit) in a word (16 bit) 00051 inline void endian_16lo8 (uint_least16_t &word, uint8_t byte) 00052 { 00053 word &= 0xff00; 00054 word |= byte; 00055 } 00056 00057 // Get the lo byte (8 bit) in a word (16 bit) 00058 inline uint8_t endian_16lo8 (uint_least16_t word) 00059 { 00060 return (uint8_t) word; 00061 } 00062 00063 // Set the hi byte (8 bit) in a word (16 bit) 00064 inline void endian_16hi8 (uint_least16_t &word, uint8_t byte) 00065 { 00066 word &= 0x00ff; 00067 word |= (uint_least16_t) byte << 8; 00068 } 00069 00070 // Set the hi byte (8 bit) in a word (16 bit) 00071 inline uint8_t endian_16hi8 (uint_least16_t word) 00072 { 00073 return (uint8_t) (word >> 8); 00074 } 00075 00076 // Swap word endian. 00077 inline void endian_16swap8 (uint_least16_t &word) 00078 { 00079 uint8_t lo = endian_16lo8 (word); 00080 uint8_t hi = endian_16hi8 (word); 00081 endian_16lo8 (word, hi); 00082 endian_16hi8 (word, lo); 00083 } 00084 00085 // Convert high-byte and low-byte to 16-bit word. 00086 inline uint_least16_t endian_16 (uint8_t hi, uint8_t lo) 00087 { 00088 uint_least16_t word = 0; 00089 endian_16lo8 (word, lo); 00090 endian_16hi8 (word, hi); 00091 return word; 00092 } 00093 00094 // Convert high-byte and low-byte to 16-bit little endian word. 00095 inline void endian_16 (uint8_t ptr[2], uint_least16_t word) 00096 { 00097 # if defined(WORDS_BIGENDIAN) 00098 ptr[0] = endian_16hi8 (word); 00099 ptr[1] = endian_16lo8 (word); 00100 # else 00101 ptr[0] = endian_16lo8 (word); 00102 ptr[1] = endian_16hi8 (word); 00103 # endif 00104 } 00105 00106 inline void endian_16 (char ptr[2], uint_least16_t word) 00107 { 00108 endian_16 ((uint8_t *) ptr, word); 00109 } 00110 00111 // Convert high-byte and low-byte to 16-bit little endian word. 00112 inline uint_least16_t endian_little16 (const uint8_t ptr[2]) 00113 { 00114 return endian_16 (ptr[1], ptr[0]); 00115 } 00116 00117 // Write a little-endian 16-bit word to two bytes in memory. 00118 inline void endian_little16 (uint8_t ptr[2], uint_least16_t word) 00119 { 00120 ptr[0] = endian_16lo8 (word); 00121 ptr[1] = endian_16hi8 (word); 00122 } 00123 00124 // Convert high-byte and low-byte to 16-bit big endian word. 00125 inline uint_least16_t endian_big16 (const uint8_t ptr[2]) 00126 { 00127 return endian_16 (ptr[0], ptr[1]); 00128 } 00129 00130 // Write a little-big 16-bit word to two bytes in memory. 00131 inline void endian_big16 (uint8_t ptr[2], uint_least16_t word) 00132 { 00133 ptr[0] = endian_16hi8 (word); 00134 ptr[1] = endian_16lo8 (word); 00135 } 00136 00137 00139 // INT32 FUNCTIONS 00141 // Set the lo word (16bit) in a dword (32 bit) 00142 inline void endian_32lo16 (uint_least32_t &dword, uint_least16_t word) 00143 { 00144 dword &= (uint_least32_t) 0xffff0000; 00145 dword |= word; 00146 } 00147 00148 // Get the lo word (16bit) in a dword (32 bit) 00149 inline uint_least16_t endian_32lo16 (uint_least32_t dword) 00150 { 00151 return (uint_least16_t) dword & 0xffff; 00152 } 00153 00154 // Set the hi word (16bit) in a dword (32 bit) 00155 inline void endian_32hi16 (uint_least32_t &dword, uint_least16_t word) 00156 { 00157 dword &= (uint_least32_t) 0x0000ffff; 00158 dword |= (uint_least32_t) word << 16; 00159 } 00160 00161 // Get the hi word (16bit) in a dword (32 bit) 00162 inline uint_least16_t endian_32hi16 (uint_least32_t dword) 00163 { 00164 return (uint_least16_t) (dword >> 16); 00165 } 00166 00167 // Set the lo byte (8 bit) in a dword (32 bit) 00168 inline void endian_32lo8 (uint_least32_t &dword, uint8_t byte) 00169 { 00170 dword &= (uint_least32_t) 0xffffff00; 00171 dword |= (uint_least32_t) byte; 00172 } 00173 00174 // Get the lo byte (8 bit) in a dword (32 bit) 00175 inline uint8_t endian_32lo8 (uint_least32_t dword) 00176 { 00177 return (uint8_t) dword; 00178 } 00179 00180 // Set the hi byte (8 bit) in a dword (32 bit) 00181 inline void endian_32hi8 (uint_least32_t &dword, uint8_t byte) 00182 { 00183 dword &= (uint_least32_t) 0xffff00ff; 00184 dword |= (uint_least32_t) byte << 8; 00185 } 00186 00187 // Get the hi byte (8 bit) in a dword (32 bit) 00188 inline uint8_t endian_32hi8 (uint_least32_t dword) 00189 { 00190 return (uint8_t) (dword >> 8); 00191 } 00192 00193 // Swap hi and lo words endian in 32 bit dword. 00194 inline void endian_32swap16 (uint_least32_t &dword) 00195 { 00196 uint_least16_t lo = endian_32lo16 (dword); 00197 uint_least16_t hi = endian_32hi16 (dword); 00198 endian_32lo16 (dword, hi); 00199 endian_32hi16 (dword, lo); 00200 } 00201 00202 // Swap word endian. 00203 inline void endian_32swap8 (uint_least32_t &dword) 00204 { 00205 uint_least16_t lo = 0, hi = 0; 00206 lo = endian_32lo16 (dword); 00207 hi = endian_32hi16 (dword); 00208 endian_16swap8 (lo); 00209 endian_16swap8 (hi); 00210 endian_32lo16 (dword, hi); 00211 endian_32hi16 (dword, lo); 00212 } 00213 00214 // Convert high-byte and low-byte to 32-bit word. 00215 inline uint_least32_t endian_32 (uint8_t hihi, uint8_t hilo, uint8_t hi, uint8_t lo) 00216 { 00217 uint_least32_t dword = 0; 00218 uint_least16_t word = 0; 00219 endian_32lo8 (dword, lo); 00220 endian_32hi8 (dword, hi); 00221 endian_16lo8 (word, hilo); 00222 endian_16hi8 (word, hihi); 00223 endian_32hi16 (dword, word); 00224 return dword; 00225 } 00226 00227 // Convert high-byte and low-byte to 32-bit little endian word. 00228 inline uint_least32_t endian_little32 (const uint8_t ptr[4]) 00229 { 00230 return endian_32 (ptr[3], ptr[2], ptr[1], ptr[0]); 00231 } 00232 00233 // Write a little-endian 32-bit word to four bytes in memory. 00234 inline void endian_little32 (uint8_t ptr[4], uint_least32_t dword) 00235 { 00236 uint_least16_t word = 0; 00237 ptr[0] = endian_32lo8 (dword); 00238 ptr[1] = endian_32hi8 (dword); 00239 word = endian_32hi16 (dword); 00240 ptr[2] = endian_16lo8 (word); 00241 ptr[3] = endian_16hi8 (word); 00242 } 00243 00244 // Convert high-byte and low-byte to 32-bit big endian word. 00245 inline uint_least32_t endian_big32 (const uint8_t ptr[4]) 00246 { 00247 return endian_32 (ptr[0], ptr[1], ptr[2], ptr[3]); 00248 } 00249 00250 // Write a big-endian 32-bit word to four bytes in memory. 00251 inline void endian_big32 (uint8_t ptr[4], uint_least32_t dword) 00252 { 00253 uint_least16_t word = 0; 00254 word = endian_32hi16 (dword); 00255 ptr[1] = endian_16lo8 (word); 00256 ptr[0] = endian_16hi8 (word); 00257 ptr[2] = endian_32hi8 (dword); 00258 ptr[3] = endian_32lo8 (dword); 00259 } 00260 00261 #endif // SIDENDIAN_H