Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
emutools_basicdefs.h
Go to the documentation of this file.
1 /* Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
2  Copyright (C)2016-2022 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
3 
4  The goal of emutools.c is to provide a relative simple solution
5  for relative simple emulators using SDL2.
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20 
21 #ifndef XEMU_COMMON_EMUTOOLS_BASICDEFS_H_INCLUDED
22 #define XEMU_COMMON_EMUTOOLS_BASICDEFS_H_INCLUDED
23 
24 #define COPYRIGHT_YEARS "2016-2022"
25 
26 #include <stdio.h>
27 #include <limits.h>
28 #include <stdlib.h>
29 
30 #define USE_REGPARM
31 
32 // In case of RELEASE build, we don't support debugging (ie write detailed log file),
33 // since it introduces some overhead in form of many if's at critical places, even
34 // if it's not used.
35 #ifdef XEMU_RELEASE_BUILD
36 #define DISABLE_DEBUG
37 #endif
38 
39 #ifndef XEMU_DISABLE_SDL
40 #ifndef XEMU_HAS_SDL2
41 #error "We require SDL2, but XEMU_HAS_SDL2 was not defined: SDL2 cannot be detected?"
42 #endif
43 #include <SDL_types.h>
44 #include <SDL_endian.h>
45 #else
46 #ifdef XEMU_HAS_SDL2
47 #error "This build does not want SDL2, but XEMU_HAS_SDL2 was specified?"
48 #endif
49 #include <stdint.h>
50 typedef int8_t Sint8;
51 typedef uint8_t Uint8;
52 typedef int16_t Sint16;
53 typedef uint16_t Uint16;
54 typedef int32_t Sint32;
55 typedef uint32_t Uint32;
56 typedef int64_t Sint64;
57 typedef uint64_t Uint64;
58 /* this part is taken from SDL2 header ... */
59 #define SDL_LIL_ENDIAN 1234
60 #define SDL_BIG_ENDIAN 4321
61 #ifdef __linux__
62 #include <endian.h>
63 #define SDL_BYTEORDER __BYTE_ORDER
64 #elif defined(__OpenBSD__)
65 #include <endian.h>
66 #define SDL_BYTEORDER BYTE_ORDER
67 #elif defined(__FreeBSD__)
68 #include <sys/endian.h>
69 #define SDL_BYTEORDER BYTE_ORDER
70 #else /* __linux__ */
71 #if defined(__hppa__) || \
72  defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
73  (defined(__MIPS__) && defined(__MISPEB__)) || \
74  defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
75  defined(__sparc__)
76 #define SDL_BYTEORDER SDL_BIG_ENDIAN
77 #else
78 #define SDL_BYTEORDER SDL_LIL_ENDIAN
79 #endif
80 #endif /* __linux__ */
81 #endif
82 
83 #if UINTPTR_MAX == 0xffffffffU
84 # define ARCH_32BIT
85 # define ARCH_BITS 32
86 # define ARCH_BITS_AS_TEXT "32"
87 #else
88 # define ARCH_64BIT
89 # define ARCH_BITS 64
90 # define ARCH_BITS_AS_TEXT "64"
91 #endif
92 
93 #if defined(__EMSCRIPTEN__)
94 # define CC_TYPE "clang-emscripten"
95 #elif defined(__clang__)
96 # define CC_TYPE "clang"
97 #elif defined(__MINGW64__)
98 # define CC_TYPE "gcc-mingw64"
99 #elif defined(__MINGW32__)
100 # define CC_TYPE "gcc-mingw32"
101 #elif defined(__GNUC__)
102 # define CC_TYPE "gcc-compatible"
103 #else
104 # define CC_TYPE "UNKNOWN-COMPILER"
105 # warning "Unrecognizable C compiler"
106 #endif
107 
108 #define XEMU_UNREACHABLE_FATAL_ERROR() do { fprintf(stderr, "*** Unreachable code point hit in function %s\n", __func__); exit(1); } while(0)
109 
110 #ifdef __GNUC__
111 # define XEMU_LIKELY(__x__) __builtin_expect(!!(__x__), 1)
112 # define XEMU_UNLIKELY(__x__) __builtin_expect(!!(__x__), 0)
113 # ifdef DO_NOT_FORCE_UNREACHABLE
114 # define XEMU_UNREACHABLE() XEMU_UNREACHABLE_FATAL_ERROR()
115 # else
116 # define XEMU_UNREACHABLE() __builtin_unreachable()
117 # endif
118 # ifdef DO_NOT_FORCE_INLINE
119 # define XEMU_INLINE inline
120 # else
121 # define XEMU_INLINE __attribute__ ((__always_inline__)) inline
122 # endif
123 #else
124 # define XEMU_LIKELY(__x__) (__x__)
125 # define XEMU_UNLIKELY(__x__) (__x__)
126 # define XEMU_INLINE inline
127 # define XEMU_UNREACHABLE() XEMU_UNREACHABLE_FATAL_ERROR()
128 #endif
129 
130 #if defined(USE_REGPARM) && defined(__GNUC__) && !defined(__EMSCRIPTEN__)
131 #define REGPARM(__n__) __attribute__ ((__regparm__ (__n__)))
132 #else
133 #define REGPARM(__n__)
134 #endif
135 
136 /* Note: O_BINARY is a must for Windows for opening binary files, odd enough, I know ...
137  So we always use O_BINARY in the code, and defining O_BINARY as zero for non-Windows systems, so it won't hurt at all.
138  Surely, SDL has some kind of file abstraction layer, but I seem to get used to some "native" code as well :-) */
139 #ifndef XEMU_ARCH_WIN
140 # define O_BINARY 0
141 # define DIRSEP_STR "/"
142 # define DIRSEP_CHR '/'
143 # define NL "\n"
144 # define NL_LENGTH 1
145 # define PRINTF_LLD "%lld"
146 # define PRINTF_LLU "%llu"
147 # define MKDIR(__n) mkdir((__n), 0777)
148 # define NULL_DEVICE "/dev/null"
149 #else
150 # define DIRSEP_STR "\\"
151 # define DIRSEP_CHR '\\'
152 # define NL "\r\n"
153 # define NL_LENGTH 2
154 # define PRINTF_LLD "%I64d"
155 # define PRINTF_LLU "%I64u"
156 # define MKDIR(__n) mkdir(__n)
157 # define NULL_DEVICE "NUL:"
158 #endif
159 
160 extern FILE *debug_fp;
161 extern int chatty_xemu;
162 
163 #ifdef DISABLE_DEBUG
164 #define DEBUG(...)
165 #define DEBUGPRINT(...) printf(__VA_ARGS__)
166 #else
167 #define DEBUG(...) do { \
168  if (XEMU_UNLIKELY(debug_fp)) \
169  fprintf(debug_fp, __VA_ARGS__); \
170 } while (0)
171 #define DEBUGPRINT(...) do { \
172  if (chatty_xemu) \
173  printf(__VA_ARGS__); \
174  DEBUG(__VA_ARGS__); \
175 } while (0)
176 #endif
177 
178 #ifndef __BIGGEST_ALIGNMENT__
179 # define __BIGGEST_ALIGNMENT__ 16
180 # define XEMU_MISSING_BIGGEST_ALIGNMENT_WORKAROUND
181 #elif __BIGGEST_ALIGNMENT__ > 256
182 # undef __BIGGEST_ALIGNMENT__
183 # define __BIGGEST_ALIGNMENT__ 256
184 # define XEMU_OVERSIZED_BIGGEST_ALIGNMENT_WORKAROUND
185 #endif
186 
187 #define ALIGNED(n) __attribute__ ((aligned (n)))
188 #define MAXALIGNED ALIGNED(__BIGGEST_ALIGNMENT__)
189 
190 /* ---- BYTE ORDER RELATED STUFFS ---- */
191 
192 #ifndef SDL_BYTEORDER
193 # error "SDL_BYTEORDER is not defined!"
194 #endif
195 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
196 # ifdef Z80EX_WORDS_BIG_ENDIAN
197 # undef Z80EX_WORDS_BIG_ENDIAN
198 # endif
199 # define ENDIAN_NAME "LE"
200 # define ENDIAN_GOOD
201 # define ENDIAN_CHECKER_BYTE_L 0x01
202 # define ENDIAN_CHECKER_BYTE_H 0x23
203 # define ENDIAN_CHECKER_WORD 0x2301
204 # define ENDIAN_CHECKER_DWORD 0x67452301
205 typedef union {
206  Uint8 _raw[4]; // 01 23 45 67
207  struct { Uint8 l,h,_un1,_un2; } b;
208  struct { Uint16 w,_unw; } w;
210 } RegPair;
211 #elif SDL_BYTEORDER == SDL_BIG_ENDIAN
212 # ifndef Z80EX_WORDS_BIG_ENDIAN
213 # define Z80EX_WORDS_BIG_ENDIAN
214 # endif
215 # define ENDIAN_NAME "BE"
216 # define ENDIAN_UGLY
217 # define ENDIAN_CHECKER_BYTE_L 0x67
218 # define ENDIAN_CHECKER_BYTE_H 0x45
219 # define ENDIAN_CHECKER_WORD 0x4567
220 # define ENDIAN_CHECKER_DWORD 0x01234567
221 typedef union {
222  Uint8 _raw[4];
223  struct { Uint8 _un1,_un2,h,l; } b;
224  struct { Uint16 _unw,w; } w;
225  Uint32 d;
226 } RegPair;
227 #else
228 # error "SDL_BYTEORDER is not SDL_LIL_ENDIAN neither SDL_BIG_ENDIAN"
229 #endif
230 static inline int xemu_byte_order_test ( void )
231 {
232  static volatile RegPair r;
233  volatile RegPair *w = &r;
234  w->_raw[0] = 0x01;
235  w->_raw[1] = 0x23;
236  w->_raw[2] = 0x45;
237  w->_raw[3] = 0x67;
238  return (r.b.l != ENDIAN_CHECKER_BYTE_L || r.b.h != ENDIAN_CHECKER_BYTE_H || r.w.w != ENDIAN_CHECKER_WORD || r.d != ENDIAN_CHECKER_DWORD);
239 }
240 
241 #ifdef __EMSCRIPTEN__
242 #include <emscripten.h>
243 #define XEMUEXIT(n) do { emscripten_cancel_main_loop(); emscripten_force_exit(n); exit(n); } while (0)
244 #else
245 #include <stdlib.h>
246 #define XEMUEXIT(n) exit(n)
247 #endif
248 
249 #define BOOLEAN_VALUE(n) (!!(n))
250 
252 extern const char emulators_disclaimer[];
253 extern void xemu_dump_version ( FILE *fp, const char *slogan );
254 extern int xemu_is_official_build ( void );
255 
256 static XEMU_INLINE unsigned char XEMU_BYTE_TO_BCD ( unsigned char b ) {
257  return ((b / 10) << 4) + (b % 10);
258 }
259 
260 // this function is similar to strcpy() however:
261 // * it does not copy the final '\0'
262 // * it returns with the _updated_ 'target' pointer, not the original!
263 static inline void *xemu_strcpy_special ( void *target, const void *source )
264 {
265  while (*(char *)source)
266  *(char *)target++ = *(char *)source++;
267  return target;
268 }
269 
270 #define VOIDPTR_TO_INT(x) ((int)(intptr_t)(void*)(x))
271 #define VOIDPTR_TO_UINT(x) ((unsigned int)(uintptr_t)(void*)(x))
272 
273 // Stringification
274 #define TO_STR_LEVEL1_(x) #x // stringification argument
275 #define STRINGIFY(x) TO_STR_LEVEL1_(x) // level of indirection to be able to expand argument given as macros
276 
277 #endif
ENDIAN_CHECKER_DWORD
#define ENDIAN_CHECKER_DWORD
Definition: emutools_basicdefs.h:204
ENDIAN_CHECKER_BYTE_H
#define ENDIAN_CHECKER_BYTE_H
Definition: emutools_basicdefs.h:202
XEMU_BUILDINFO_GIT
const char XEMU_BUILDINFO_GIT[]
Definition: emutools_basicdefs.h:251
XEMU_INLINE
#define XEMU_INLINE
Definition: emutools_basicdefs.h:126
Uint32
uint32_t Uint32
Definition: fat32.c:49
Uint8
uint8_t Uint8
Definition: fat32.c:51
XEMU_BUILDINFO_CC
const char XEMU_BUILDINFO_CC[]
Definition: emutools_basicdefs.h:251
chatty_xemu
int chatty_xemu
Definition: main.c:68
ENDIAN_CHECKER_WORD
#define ENDIAN_CHECKER_WORD
Definition: emutools_basicdefs.h:203
xemu_is_official_build
int xemu_is_official_build(void)
Definition: emutools_buildinfo.c:33
ENDIAN_CHECKER_BYTE_L
#define ENDIAN_CHECKER_BYTE_L
Definition: emutools_basicdefs.h:201
XEMU_BUILDINFO_TARGET
const char XEMU_BUILDINFO_TARGET[]
Definition: emutools_basicdefs.h:251
compress_sd_image.r
def r
Definition: compress_sd_image.py:76
RegPair::d
Uint32 d
Definition: emutools_basicdefs.h:209
RegPair::l
Uint8 l
Definition: emutools_basicdefs.h:207
XEMU_BUILDINFO_CDATE
const char XEMU_BUILDINFO_CDATE[]
Definition: emutools_basicdefs.h:251
emulators_disclaimer
const char emulators_disclaimer[]
Definition: emutools_buildinfo.c:25
XEMU_BUILDINFO_ON
const char XEMU_BUILDINFO_ON[]
debug_fp
FILE * debug_fp
Definition: configuration.c:87
Uint16
uint16_t Uint16
Definition: fat32.c:50
xemu_dump_version
void xemu_dump_version(FILE *fp, const char *slogan)
Definition: emutools_buildinfo.c:45
RegPair::_raw
Uint8 _raw[4]
Definition: emutools_basicdefs.h:206
RegPair
Definition: emutools_basicdefs.h:205
XEMU_BUILDINFO_AT
const char XEMU_BUILDINFO_AT[]
Definition: emutools_basicdefs.h:251
RegPair::w
Uint16 w
Definition: emutools_basicdefs.h:208