visualboyadvance-m/Gb_Apu/blargg_endian.h

157 lines
4.6 KiB
C

// CPU Byte Order Utilities
// Game_Music_Emu 0.3.0
#ifndef BLARGG_ENDIAN
#define BLARGG_ENDIAN
#include "blargg_common.h"
#if 0
// Read 16/32-bit little-endian integer from memory
unsigned GET_LE16( void const* );
unsigned long GET_LE32( void const* );
// Read 16/32-bit big-endian integer from memory
unsigned GET_BE16( void const* );
unsigned long GET_BE32( void const* );
// Write 16/32-bit integer to memory in little-endian format
void SET_LE16( void*, unsigned );
void SET_LE32( void*, unsigned );
// Write 16/32-bit integer to memory in big-endian format
void SET_BE16( void*, unsigned long );
void SET_BE32( void*, unsigned long );
#endif
inline unsigned get_le16( void const* p )
{
return ((unsigned char*) p) [1] * 0x100 +
((unsigned char*) p) [0];
}
inline unsigned get_be16( void const* p )
{
return ((unsigned char*) p) [0] * 0x100 +
((unsigned char*) p) [1];
}
inline unsigned long get_le32( void const* p )
{
return ((unsigned char*) p) [3] * 0x01000000 +
((unsigned char*) p) [2] * 0x00010000 +
((unsigned char*) p) [1] * 0x00000100 +
((unsigned char*) p) [0];
}
inline unsigned long get_be32( void const* p )
{
return ((unsigned char*) p) [0] * 0x01000000 +
((unsigned char*) p) [1] * 0x00010000 +
((unsigned char*) p) [2] * 0x00000100 +
((unsigned char*) p) [3];
}
inline void set_le16( void* p, unsigned n )
{
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
((unsigned char*) p) [0] = (unsigned char) n;
}
inline void set_be16( void* p, unsigned n )
{
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
((unsigned char*) p) [1] = (unsigned char) n;
}
inline void set_le32( void* p, unsigned long n )
{
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
((unsigned char*) p) [0] = (unsigned char) n;
}
inline void set_be32( void* p, unsigned long n )
{
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
((unsigned char*) p) [3] = (unsigned char) n;
}
#ifndef GET_LE16
// Optimized implementation if byte order is known
#if BLARGG_NONPORTABLE && BLARGG_LITTLE_ENDIAN
#define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr))
#define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr))
#define SET_LE16( addr, data ) (void (*(BOOST::uint16_t*) (addr) = (data)))
#define SET_LE32( addr, data ) (void (*(BOOST::uint32_t*) (addr) = (data)))
#elif BLARGG_NONPORTABLE && BLARGG_CPU_POWERPC
// PowerPC has special byte-reversed instructions
// to do: assumes that PowerPC is running in big-endian mode
#define GET_LE16( addr ) (__lhbrx( (addr), 0 ))
#define GET_LE32( addr ) (__lwbrx( (addr), 0 ))
#define SET_LE16( addr, data ) (__sthbrx( (data), (addr), 0 ))
#define SET_LE32( addr, data ) (__stwbrx( (data), (addr), 0 ))
#define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr))
#define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
#define SET_BE16( addr, data ) (void (*(BOOST::uint16_t*) (addr) = (data)))
#define SET_BE32( addr, data ) (void (*(BOOST::uint32_t*) (addr) = (data)))
#endif
#endif
#ifndef GET_LE16
#define GET_LE16( addr ) get_le16( addr )
#endif
#ifndef GET_LE32
#define GET_LE32( addr ) get_le32( addr )
#endif
#ifndef SET_LE16
#define SET_LE16( addr, data ) set_le16( addr, data )
#endif
#ifndef SET_LE32
#define SET_LE32( addr, data ) set_le32( addr, data )
#endif
#ifndef GET_BE16
#define GET_BE16( addr ) get_be16( addr )
#endif
#ifndef GET_BE32
#define GET_BE32( addr ) get_be32( addr )
#endif
#ifndef SET_BE16
#define SET_BE16( addr, data ) set_be16( addr, data )
#endif
#ifndef SET_BE32
#define SET_BE32( addr, data ) set_be32( addr, data )
#endif
// auto-selecting versions
inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
inline void set_le( BOOST::uint32_t* p, unsigned long n ) { SET_LE32( p, n ); }
inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
inline void set_be( BOOST::uint32_t* p, unsigned long n ) { SET_BE32( p, n ); }
inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); }
inline unsigned long get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); }
inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); }
inline unsigned long get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); }
#endif