diff options
Diffstat (limited to 'trunk/src/emu/emucore.h')
-rw-r--r-- | trunk/src/emu/emucore.h | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/trunk/src/emu/emucore.h b/trunk/src/emu/emucore.h new file mode 100644 index 00000000000..8ea6c5a7ccb --- /dev/null +++ b/trunk/src/emu/emucore.h @@ -0,0 +1,455 @@ +/*************************************************************************** + + emucore.h + + General core utilities and macros used throughout the emulator. + + Copyright Nicola Salmoria and the MAME Team. + Visit http://mamedev.org for licensing and usage restrictions. + +***************************************************************************/ + +#pragma once + +#ifndef __EMUCORE_H__ +#define __EMUCORE_H__ + +// standard C includes +#include <math.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> + +// some cleanups for Solaris for things defined in stdlib.h +#ifdef SDLMAME_SOLARIS +#undef si_status +#undef WWORD +#endif + +// standard C++ includes +#include <exception> +#include <typeinfo> + +// core system includes +#include "osdcomm.h" +#include "astring.h" +#include "emualloc.h" +#include "corestr.h" +#include "bitmap.h" +#include "tagmap.h" + + + +//************************************************************************** +// COMPILER-SPECIFIC NASTINESS +//************************************************************************** + +// Suppress warnings about redefining the macro 'PPC' on LinuxPPC. +#undef PPC + +// Suppress warnings about redefining the macro 'ARM' on ARM. +#undef ARM + + + +//************************************************************************** +// FUNDAMENTAL TYPES +//************************************************************************** + +// genf is a generic function pointer; cast function pointers to this instead of void * +typedef void genf(void); + +// FPTR is used to cast a pointer to a scalar +#ifdef PTR64 +typedef UINT64 FPTR; +#else +typedef UINT32 FPTR; +#endif + +// pen_t is used to represent pixel values in bitmaps +typedef UINT32 pen_t; + +// stream_sample_t is used to represent a single sample in a sound stream +typedef INT32 stream_sample_t; + +// running_machine is core to pretty much everything +class running_machine; + + + +//************************************************************************** +// USEFUL COMPOSITE TYPES +//************************************************************************** + +// generic_ptr is a union of pointers to various sizes +union generic_ptr +{ + void * v; + INT8 * i8; + UINT8 * u8; + INT16 * i16; + UINT16 * u16; + INT32 * i32; + UINT32 * u32; + INT64 * i64; + UINT64 * u64; +}; + + +// PAIR is an endian-safe union useful for representing 32-bit CPU registers +union PAIR +{ +#ifdef LSB_FIRST + struct { UINT8 l,h,h2,h3; } b; + struct { UINT16 l,h; } w; + struct { INT8 l,h,h2,h3; } sb; + struct { INT16 l,h; } sw; +#else + struct { UINT8 h3,h2,h,l; } b; + struct { INT8 h3,h2,h,l; } sb; + struct { UINT16 h,l; } w; + struct { INT16 h,l; } sw; +#endif + UINT32 d; + INT32 sd; +}; + + +// PAIR64 is a 64-bit extension of a PAIR +union PAIR64 +{ +#ifdef LSB_FIRST + struct { UINT8 l,h,h2,h3,h4,h5,h6,h7; } b; + struct { UINT16 l,h,h2,h3; } w; + struct { UINT32 l,h; } d; + struct { INT8 l,h,h2,h3,h4,h5,h6,h7; } sb; + struct { INT16 l,h,h2,h3; } sw; + struct { INT32 l,h; } sd; +#else + struct { UINT8 h7,h6,h5,h4,h3,h2,h,l; } b; + struct { UINT16 h3,h2,h,l; } w; + struct { UINT32 h,l; } d; + struct { INT8 h7,h6,h5,h4,h3,h2,h,l; } sb; + struct { INT16 h3,h2,h,l; } sw; + struct { INT32 h,l; } sd; +#endif + UINT64 q; + INT64 sq; +}; + + + +//************************************************************************** +// COMMON CONSTANTS +//************************************************************************** + +// constants for expression endianness +enum endianness_t +{ + ENDIANNESS_LITTLE, + ENDIANNESS_BIG +}; + + +// declare native endianness to be one or the other +#ifdef LSB_FIRST +const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_LITTLE; +#else +const endianness_t ENDIANNESS_NATIVE = ENDIANNESS_BIG; +#endif + + +// M_PI is not part of the C/C++ standards and is not present on +// strict ANSI compilers or when compiling under GCC with -ansi +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + + +// orientation of bitmaps +#define ORIENTATION_FLIP_X 0x0001 /* mirror everything in the X direction */ +#define ORIENTATION_FLIP_Y 0x0002 /* mirror everything in the Y direction */ +#define ORIENTATION_SWAP_XY 0x0004 /* mirror along the top-left/bottom-right diagonal */ + +#define ROT0 0 +#define ROT90 (ORIENTATION_SWAP_XY | ORIENTATION_FLIP_X) /* rotate clockwise 90 degrees */ +#define ROT180 (ORIENTATION_FLIP_X | ORIENTATION_FLIP_Y) /* rotate 180 degrees */ +#define ROT270 (ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y) /* rotate counter-clockwise 90 degrees */ + + + +//************************************************************************** +// COMMON MACROS +//************************************************************************** + +// macro for defining a copy constructor and assignment operator to prevent copying +#define DISABLE_COPYING(_Type) \ +private: \ + _Type(const _Type &); \ + _Type &operator=(const _Type &) \ + + +// macro for declaring enumerator operators that increment/decrement like plain old C +#define DECLARE_ENUM_OPERATORS(_Type) \ +inline void operator++(_Type &value) { value = (_Type)((int)value + 1); } \ +inline void operator++(_Type &value, int) { value = (_Type)((int)value + 1); } \ +inline void operator--(_Type &value) { value = (_Type)((int)value - 1); } \ +inline void operator--(_Type &value, int) { value = (_Type)((int)value - 1); } + + +// this macro passes an item followed by a string version of itself as two consecutive parameters +#define NAME(x) x, #x + +// this macro wraps a function 'x' and can be used to pass a function followed by its name +#define FUNC(x) &x, #x +#define FUNC_NULL NULL, "(null)" + + +// standard assertion macros +#undef assert +#undef assert_always + +#ifdef MAME_DEBUG +#define assert(x) do { if (!(x)) throw emu_fatalerror("assert: %s:%d: %s", __FILE__, __LINE__, #x); } while (0) +#define assert_always(x, msg) do { if (!(x)) throw emu_fatalerror("Fatal error: %s\nCaused by assert: %s:%d: %s", msg, __FILE__, __LINE__, #x); } while (0) +#else +#define assert(x) do { } while (0) +#define assert_always(x, msg) do { if (!(x)) throw emu_fatalerror("Fatal error: %s (%s:%d)", msg, __FILE__, __LINE__); } while (0) +#endif + + +// map mame_* helpers to core_* helpers */ +#define mame_stricmp core_stricmp +#define mame_strnicmp core_strnicmp +#define mame_strdup core_strdup +#define mame_strwildcmp core_strwildcmp + + +// macros to convert radians to degrees and degrees to radians +#define RADIAN_TO_DEGREE(x) ((180.0 / M_PI) * (x)) +#define DEGREE_TO_RADIAN(x) ((M_PI / 180.0) * (x)) + + +// endian-based value: first value is if 'endian' is little-endian, second is if 'endian' is big-endian +#define ENDIAN_VALUE_LE_BE(endian,leval,beval) (((endian) == ENDIANNESS_LITTLE) ? (leval) : (beval)) + +// endian-based value: first value is if native endianness is little-endian, second is if native is big-endian +#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ENDIAN_VALUE_LE_BE(ENDIANNESS_NATIVE, leval, beval) + +// endian-based value: first value is if 'endian' matches native, second is if 'endian' doesn't match native +#define ENDIAN_VALUE_NE_NNE(endian,leval,beval) (((endian) == ENDIANNESS_NATIVE) ? (neval) : (nneval)) + + +// useful macros to deal with bit shuffling encryptions +#define BIT(x,n) (((x)>>(n))&1) + +#define BITSWAP8(val,B7,B6,B5,B4,B3,B2,B1,B0) \ + ((BIT(val,B7) << 7) | (BIT(val,B6) << 6) | (BIT(val,B5) << 5) | (BIT(val,B4) << 4) | \ + (BIT(val,B3) << 3) | (BIT(val,B2) << 2) | (BIT(val,B1) << 1) | (BIT(val,B0) << 0)) + +#define BITSWAP16(val,B15,B14,B13,B12,B11,B10,B9,B8,B7,B6,B5,B4,B3,B2,B1,B0) \ + ((BIT(val,B15) << 15) | (BIT(val,B14) << 14) | (BIT(val,B13) << 13) | (BIT(val,B12) << 12) | \ + (BIT(val,B11) << 11) | (BIT(val,B10) << 10) | (BIT(val, B9) << 9) | (BIT(val, B8) << 8) | \ + (BIT(val, B7) << 7) | (BIT(val, B6) << 6) | (BIT(val, B5) << 5) | (BIT(val, B4) << 4) | \ + (BIT(val, B3) << 3) | (BIT(val, B2) << 2) | (BIT(val, B1) << 1) | (BIT(val, B0) << 0)) + +#define BITSWAP24(val,B23,B22,B21,B20,B19,B18,B17,B16,B15,B14,B13,B12,B11,B10,B9,B8,B7,B6,B5,B4,B3,B2,B1,B0) \ + ((BIT(val,B23) << 23) | (BIT(val,B22) << 22) | (BIT(val,B21) << 21) | (BIT(val,B20) << 20) | \ + (BIT(val,B19) << 19) | (BIT(val,B18) << 18) | (BIT(val,B17) << 17) | (BIT(val,B16) << 16) | \ + (BIT(val,B15) << 15) | (BIT(val,B14) << 14) | (BIT(val,B13) << 13) | (BIT(val,B12) << 12) | \ + (BIT(val,B11) << 11) | (BIT(val,B10) << 10) | (BIT(val, B9) << 9) | (BIT(val, B8) << 8) | \ + (BIT(val, B7) << 7) | (BIT(val, B6) << 6) | (BIT(val, B5) << 5) | (BIT(val, B4) << 4) | \ + (BIT(val, B3) << 3) | (BIT(val, B2) << 2) | (BIT(val, B1) << 1) | (BIT(val, B0) << 0)) + +#define BITSWAP32(val,B31,B30,B29,B28,B27,B26,B25,B24,B23,B22,B21,B20,B19,B18,B17,B16,B15,B14,B13,B12,B11,B10,B9,B8,B7,B6,B5,B4,B3,B2,B1,B0) \ + ((BIT(val,B31) << 31) | (BIT(val,B30) << 30) | (BIT(val,B29) << 29) | (BIT(val,B28) << 28) | \ + (BIT(val,B27) << 27) | (BIT(val,B26) << 26) | (BIT(val,B25) << 25) | (BIT(val,B24) << 24) | \ + (BIT(val,B23) << 23) | (BIT(val,B22) << 22) | (BIT(val,B21) << 21) | (BIT(val,B20) << 20) | \ + (BIT(val,B19) << 19) | (BIT(val,B18) << 18) | (BIT(val,B17) << 17) | (BIT(val,B16) << 16) | \ + (BIT(val,B15) << 15) | (BIT(val,B14) << 14) | (BIT(val,B13) << 13) | (BIT(val,B12) << 12) | \ + (BIT(val,B11) << 11) | (BIT(val,B10) << 10) | (BIT(val, B9) << 9) | (BIT(val, B8) << 8) | \ + (BIT(val, B7) << 7) | (BIT(val, B6) << 6) | (BIT(val, B5) << 5) | (BIT(val, B4) << 4) | \ + (BIT(val, B3) << 3) | (BIT(val, B2) << 2) | (BIT(val, B1) << 1) | (BIT(val, B0) << 0)) + + + +//************************************************************************** +// EXCEPTION CLASSES +//************************************************************************** + +// emu_exception is the base class for all emu-related exceptions +class emu_exception : public std::exception { }; + + +// emu_fatalerror is a generic fatal exception that provides an error string +class emu_fatalerror : public emu_exception +{ +public: + emu_fatalerror(const char *format, ...) + : code(0) + { + va_list ap; + va_start(ap, format); + vsprintf(text, format, ap); + va_end(ap); + osd_break_into_debugger(text); + } + + emu_fatalerror(const char *format, va_list ap) + : code(0) + { + vsprintf(text, format, ap); + osd_break_into_debugger(text); + } + + emu_fatalerror(int _exitcode, const char *format, ...) + : code(_exitcode) + { + va_list ap; + va_start(ap, format); + vsprintf(text, format, ap); + va_end(ap); + } + + emu_fatalerror(int _exitcode, const char *format, va_list ap) + : code(_exitcode) + { + vsprintf(text, format, ap); + } + + const char *string() const { return text; } + int exitcode() const { return code; } + +private: + char text[1024]; + int code; +}; + + + +//************************************************************************** +// CASTING TEMPLATES +//************************************************************************** + +// template function for casting from a base class to a derived class that is checked +// in debug builds and fast in release builds +template<class _Dest, class _Source> +inline _Dest downcast(_Source *src) +{ + assert(dynamic_cast<_Dest>(src) == src); + return static_cast<_Dest>(src); +} + +template<class _Dest, class _Source> +inline _Dest downcast(_Source &src) +{ + assert(&dynamic_cast<_Dest>(src) == &src); + return static_cast<_Dest>(src); +} + + +// template function for cross-casting from one class to another that throws a bad_cast +// exception instead of returning NULL +template<class _Dest, class _Source> +inline _Dest crosscast(_Source *src) +{ + _Dest result = dynamic_cast<_Dest>(src); + assert(result != NULL); + if (result == NULL) + throw std::bad_cast(); + return result; +} + + + +//************************************************************************** +// FUNCTION PROTOTYPES +//************************************************************************** + +DECL_NORETURN void fatalerror(const char *format, ...) ATTR_PRINTF(1,2) ATTR_NORETURN; +DECL_NORETURN void fatalerror_exitcode(running_machine &machine, int exitcode, const char *format, ...) ATTR_PRINTF(3,4) ATTR_NORETURN; + +inline void fatalerror(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + throw emu_fatalerror(format, ap); + va_end(ap); +} + +inline void fatalerror_exitcode(running_machine &machine, int exitcode, const char *format, ...) +{ + va_list ap; + va_start(ap, format); + throw emu_fatalerror(exitcode, format, ap); + va_end(ap); +} + + + +//************************************************************************** +// INLINE FUNCTIONS +//************************************************************************** + +// population count +#ifndef SDLMAME_NETBSD +inline int popcount(UINT32 val) +{ + int count; + + for (count = 0; val != 0; count++) + val &= val - 1; + return count; +} +#endif + + +// convert a series of 32 bits into a float +inline float u2f(UINT32 v) +{ + union { + float ff; + UINT32 vv; + } u; + u.vv = v; + return u.ff; +} + + +// convert a float into a series of 32 bits +inline UINT32 f2u(float f) +{ + union { + float ff; + UINT32 vv; + } u; + u.ff = f; + return u.vv; +} + + +// convert a series of 64 bits into a double +inline double u2d(UINT64 v) +{ + union { + double dd; + UINT64 vv; + } u; + u.vv = v; + return u.dd; +} + + +// convert a double into a series of 64 bits +inline UINT64 d2u(double d) +{ + union { + double dd; + UINT64 vv; + } u; + u.dd = d; + return u.vv; +} + +#endif /* __EMUCORE_H__ */ |