1 /*
2   * UAE - The Un*x Amiga Emulator
3   *
4   * Try to include the right system headers and get other system-specific
5   * stuff right & other collected kludges.
6   *
7   * If you think about modifying this, think twice. Some systems rely on
8   * the exact order of the #include statements. That's also the reason
9   * why everything gets included unconditionally regardless of whether
10   * it's actually needed by the .c file.
11   *
12   * Copyright 1996, 1997 Bernd Schmidt
13   */
14 #ifndef UAE_SYSDEPS_H
15 #define UAE_SYSDEPS_H
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 #include "sysconfig.h"
21 
22 #ifndef UAE
23 #define UAE
24 #endif
25 
26 #ifdef __cplusplus
27 #include <string>
28 using namespace std;
29 #else
30 #include <string.h>
31 #include <ctype.h>
32 #endif
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <errno.h>
36 #include <assert.h>
37 #include <limits.h>
38 
39 #ifndef UAE
40 #define UAE
41 #endif
42 
43 #if defined(__x86_64__) || defined(_M_AMD64)
44 #define CPU_x86_64 1
45 #define CPU_64_BIT 1
46 #elif defined(__i386__) || defined(_M_IX86)
47 #define CPU_i386 1
48 #elif defined(__arm__) || defined(_M_ARM)
49 #define CPU_arm 1
50 #elif defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)
51 #define CPU_powerpc 1
52 #else
53 #define CPU_unknown 1
54 #endif
55 
56 #ifdef _WIN32
57 /* Parameters are passed in ECX, EDX for both x86 and x86-64 (RCX, RDX).
58  * For x86-64, __fastcall is the default, so it isn't really required. */
59 #define JITCALL __fastcall
60 #elif defined(CPU_x86_64)
61 /* Parameters are passed in RDI, RSI by default (System V AMD64 ABI). */
62 #define JITCALL
63 #elif defined(HAVE_FUNC_ATTRIBUTE_REGPARM)
64 /* Parameters are passed in EAX, EDX on x86 with regparm(2). */
65 #define JITCALL __attribute__((regparm(2)))
66 /* This was originally regparm(3), but as far as I can see only two register
67  * params are supported by the JIT code. It probably just worked anyway
68  * if all functions used max two arguments. */
69 #elif !defined(JIT)
70 #define JITCALL
71 #endif
72 #define REGPARAM
73 #define REGPARAM2 JITCALL
74 #define REGPARAM3 JITCALL
75 
76 #ifdef FSUAE
77 #include "uae/types.h"
78 #else
79 #include <tchar.h>
80 #endif
81 
82 #ifndef __STDC__
83 #ifndef _MSC_VER
84 #error "Your compiler is not ANSI. Get a real one."
85 #endif
86 #endif
87 
88 #include <stdarg.h>
89 
90 #ifdef HAVE_SYS_TYPES_H
91 #include <sys/types.h>
92 #endif
93 
94 #ifdef HAVE_VALUES_H
95 #include <values.h>
96 #endif
97 
98 #ifdef HAVE_STRINGS_H
99 #include <strings.h>
100 #endif
101 #ifdef HAVE_STRING_H
102 #include <string.h>
103 #endif
104 
105 #ifdef HAVE_UNISTD_H
106 #include <unistd.h>
107 #endif
108 #ifdef HAVE_FCNTL_H
109 #include <fcntl.h>
110 #endif
111 
112 #ifdef HAVE_UTIME_H
113 #include <utime.h>
114 #endif
115 
116 #ifdef HAVE_SYS_STAT_H
117 #include <sys/stat.h>
118 #endif
119 
120 #if TIME_WITH_SYS_TIME
121 # include <sys/time.h>
122 # include <time.h>
123 #else
124 # if HAVE_SYS_TIME_H
125 #  include <sys/time.h>
126 # else
127 #  include <time.h>
128 # endif
129 #endif
130 
131 #if HAVE_DIRENT_H
132 # include <dirent.h>
133 #else
134 # define dirent direct
135 # if HAVE_SYS_NDIR_H
136 #  include <sys/ndir.h>
137 # endif
138 # if HAVE_SYS_DIR_H
139 #  include <sys/dir.h>
140 # endif
141 # if HAVE_NDIR_H
142 #  include <ndir.h>
143 # endif
144 #endif
145 
146 #ifdef HAVE_SYS_UTIME_H
147 # include <sys/utime.h>
148 #endif
149 
150 #include <errno.h>
151 #include <assert.h>
152 
153 #if EEXIST == ENOTEMPTY
154 #define BROKEN_OS_PROBABLY_AIX
155 #endif
156 
157 #ifdef __NeXT__
158 #define S_IRUSR S_IREAD
159 #define S_IWUSR S_IWRITE
160 #define S_IXUSR S_IEXEC
161 #define S_ISDIR(val) (S_IFDIR & val)
162 struct utimbuf
163 {
164     time_t actime;
165     time_t modtime;
166 };
167 #endif
168 
169 #ifndef L_tmpnam
170 #define L_tmpnam 128 /* ought to be safe */
171 #endif
172 
173 /* If char has more then 8 bits, good night. */
174 typedef unsigned char uae_u8;
175 typedef signed char uae_s8;
176 typedef char uae_char;
177 
178 typedef struct { uae_u8 RGB[3]; } RGB;
179 
180 #ifdef FSUAE
181 #define VAL64(a) (a ## LL)
182 #define UVAL64(a) (a ## uLL)
183 
184 #else
185 #if SIZEOF_SHORT == 2
186 typedef unsigned short uae_u16;
187 typedef short uae_s16;
188 #elif SIZEOF_INT == 2
189 typedef unsigned int uae_u16;
190 typedef int uae_s16;
191 #else
192 #error No 2 byte type, you lose.
193 #endif
194 
195 #if SIZEOF_INT == 4
196 typedef unsigned int uae_u32;
197 typedef int uae_s32;
198 #elif SIZEOF_LONG == 4
199 typedef unsigned long uae_u32;
200 typedef long uae_s32;
201 #else
202 #error No 4 byte type, you lose.
203 #endif
204 
205 typedef uae_u32 uaecptr;
206 
207 #undef uae_s64
208 #undef uae_u64
209 
210 #if SIZEOF_LONG_LONG == 8
211 #define uae_s64 long long
212 #define uae_u64 unsigned long long
213 #define VAL64(a) (a ## LL)
214 #define UVAL64(a) (a ## uLL)
215 #elif SIZEOF___INT64 == 8
216 #define uae_s64 __int64
217 #define uae_u64 unsigned __int64
218 #define VAL64(a) (a)
219 #define UVAL64(a) (a)
220 #elif SIZEOF_LONG == 8
221 #define uae_s64 long;
222 #define uae_u64 unsigned long;
223 #define VAL64(a) (a ## l)
224 #define UVAL64(a) (a ## ul)
225 #endif
226 #endif
227 
228 #ifdef HAVE_STRDUP
229 #define my_strdup _tcsdup
230 #else
231 extern TCHAR *my_strdup (const TCHAR*s);
232 #endif
233 extern TCHAR *my_strdup_ansi (const char*);
234 extern void my_trim (TCHAR*);
235 extern TCHAR *my_strdup_trim (const TCHAR*);
236 extern TCHAR *au (const char*);
237 extern char *ua (const TCHAR*);
238 extern TCHAR *aucp (const char *s, unsigned int cp);
239 extern char *uacp (const TCHAR *s, unsigned int cp);
240 extern TCHAR *au_fs (const char*);
241 extern char *ua_fs (const TCHAR*, int);
242 extern char *ua_copy (char *dst, int maxlen, const TCHAR *src);
243 extern TCHAR *au_copy (TCHAR *dst, int maxlen, const char *src);
244 extern char *ua_fs_copy (char *dst, int maxlen, const TCHAR *src, int defchar);
245 extern TCHAR *au_fs_copy (TCHAR *dst, int maxlen, const char *src);
246 extern char *uutf8 (const TCHAR *s);
247 extern TCHAR *utf8u (const char *s);
248 extern void unicode_init (void);
249 extern void to_lower (TCHAR *s, int len);
250 extern void to_upper (TCHAR *s, int len);
251 
252 /* We can only rely on GNU C getting enums right. Mickeysoft VSC++ is known
253  * to have problems, and it's likely that other compilers choke too. */
254 #ifdef __GNUC__
255 #define ENUMDECL typedef enum
256 #define ENUMNAME(name) name
257 
258 /* While we're here, make abort more useful.  */
259 #define abort() \
260   do { \
261     write_log ("Internal error; file %s, line %d\n", __FILE__, __LINE__); \
262     (abort) (); \
263 } while (0)
264 #else
265 #define ENUMDECL enum
266 #define ENUMNAME(name) ; typedef int name
267 #endif
268 
269 /*
270  * Porters to weird systems, look! This is the preferred way to get
271  * filesys.c (and other stuff) running on your system. Define the
272  * appropriate macros and implement wrappers in a machine-specific file.
273  *
274  * I guess the Mac port could use this (Ernesto?)
275  */
276 
277 #undef DONT_HAVE_POSIX
278 #undef DONT_HAVE_REAL_POSIX /* define if open+delete doesn't do what it should */
279 #undef DONT_HAVE_STDIO
280 #undef DONT_HAVE_MALLOC
281 
282 #if defined(WARPUP)
283 #define DONT_HAVE_POSIX
284 #endif
285 
286 #if !defined(FSUAE) && defined _WIN32
287 
288 //#ifdef FSUAE
289 //#error _WIN32 should not be defined here
290 //#endif
291 #if defined __WATCOMC__
292 
293 #define O_NDELAY 0
294 #include <direct.h>
295 #define dirent direct
296 #define mkdir(a,b) mkdir(a)
297 #define strcasecmp stricmp
298 
299 #elif defined __MINGW32__
300 
301 #include <winsock.h>
302 
303 #define O_NDELAY 0
304 
305 #define FILEFLAG_DIR     0x1
306 #define FILEFLAG_ARCHIVE 0x2
307 #define FILEFLAG_WRITE   0x4
308 #define FILEFLAG_READ    0x8
309 #define FILEFLAG_EXECUTE 0x10
310 #define FILEFLAG_SCRIPT  0x20
311 #define FILEFLAG_PURE    0x40
312 
313 #define mkdir(a,b) mkdir(a)
314 
315 #elif defined _MSC_VER
316 
317 #ifdef HAVE_GETTIMEOFDAY
318 #include <winsock.h> // for 'struct timeval' definition
319 extern void gettimeofday( struct timeval *tv, void *blah );
320 #endif
321 
322 #define O_NDELAY 0
323 
324 #define FILEFLAG_DIR     0x1
325 #define FILEFLAG_ARCHIVE 0x2
326 #define FILEFLAG_WRITE   0x4
327 #define FILEFLAG_READ    0x8
328 #define FILEFLAG_EXECUTE 0x10
329 #define FILEFLAG_SCRIPT  0x20
330 #define FILEFLAG_PURE    0x40
331 
332 #include <io.h>
333 #define O_BINARY _O_BINARY
334 #define O_WRONLY _O_WRONLY
335 #define O_RDONLY _O_RDONLY
336 #define O_RDWR   _O_RDWR
337 #define O_CREAT  _O_CREAT
338 #define O_TRUNC  _O_TRUNC
339 #define strcasecmp _tcsicmp
340 #define strncasecmp _tcsncicmp
341 #define W_OK 0x2
342 #define R_OK 0x4
343 #define STAT struct stat
344 #define DIR struct DIR
345 struct direct
346 {
347     TCHAR d_name[1];
348 };
349 #include <sys/utime.h>
350 #define utimbuf __utimbuf64
351 #define USE_ZFILE
352 
353 #undef S_ISDIR
354 #undef S_IWUSR
355 #undef S_IRUSR
356 #undef S_IXUSR
357 #define S_ISDIR(a) (a&FILEFLAG_DIR)
358 #define S_ISARC(a) (a&FILEFLAG_ARCHIVE)
359 #define S_IWUSR FILEFLAG_WRITE
360 #define S_IRUSR FILEFLAG_READ
361 #define S_IXUSR FILEFLAG_EXECUTE
362 
363 #endif
364 
365 #endif /* _WIN32 */
366 
367 #ifdef DONT_HAVE_POSIX
368 
369 #define access posixemu_access
370 extern int posixemu_access (const TCHAR *, int);
371 #define open posixemu_open
372 extern int posixemu_open (const TCHAR *, int, int);
373 #define close posixemu_close
374 extern void posixemu_close (int);
375 #define read posixemu_read
376 extern int posixemu_read (int, TCHAR *, int);
377 #define write posixemu_write
378 extern int posixemu_write (int, const TCHAR *, int);
379 #undef lseek
380 #define lseek posixemu_seek
381 extern int posixemu_seek (int, int, int);
382 #define stat(a,b) posixemu_stat ((a), (b))
383 extern int posixemu_stat (const TCHAR *, STAT *);
384 #define mkdir posixemu_mkdir
385 extern int mkdir (const TCHAR *, int);
386 #define rmdir posixemu_rmdir
387 extern int posixemu_rmdir (const TCHAR *);
388 #define unlink posixemu_unlink
389 extern int posixemu_unlink (const TCHAR *);
390 #define truncate posixemu_truncate
391 extern int posixemu_truncate (const TCHAR *, long int);
392 #define rename posixemu_rename
393 extern int posixemu_rename (const TCHAR *, const TCHAR *);
394 #define chmod posixemu_chmod
395 extern int posixemu_chmod (const TCHAR *, int);
396 #define tmpnam posixemu_tmpnam
397 extern void posixemu_tmpnam (TCHAR *);
398 #define utime posixemu_utime
399 extern int posixemu_utime (const TCHAR *, struct utimbuf *);
400 #define opendir posixemu_opendir
401 extern DIR * posixemu_opendir (const TCHAR *);
402 #define readdir posixemu_readdir
403 extern struct dirent* readdir (DIR *);
404 #define closedir posixemu_closedir
405 extern void closedir (DIR *);
406 
407 /* This isn't the best place for this, but it fits reasonably well. The logic
408  * is that you probably don't have POSIX errnos if you don't have the above
409  * functions. */
410 extern long dos_errno (void);
411 
412 #endif
413 
414 #ifdef DONT_HAVE_STDIO
415 
416 extern FILE *stdioemu_fopen (const TCHAR *, const TCHAR *);
417 #define fopen(a,b) stdioemu_fopen(a, b)
418 extern int stdioemu_fseek (FILE *, int, int);
419 #define fseek(a,b,c) stdioemu_fseek(a, b, c)
420 extern int stdioemu_fread (TCHAR *, int, int, FILE *);
421 #define fread(a,b,c,d) stdioemu_fread(a, b, c, d)
422 extern int stdioemu_fwrite (const TCHAR *, int, int, FILE *);
423 #define fwrite(a,b,c,d) stdioemu_fwrite(a, b, c, d)
424 extern int stdioemu_ftell (FILE *);
425 #define ftell(a) stdioemu_ftell(a)
426 extern int stdioemu_fclose (FILE *);
427 #define fclose(a) stdioemu_fclose(a)
428 
429 #endif
430 
431 #ifdef DONT_HAVE_MALLOC
432 
433 #define malloc(a) mallocemu_malloc(a)
434 extern void *mallocemu_malloc (int size);
435 #define free(a) mallocemu_free(a)
436 extern void mallocemu_free (void *ptr);
437 
438 #endif
439 
440 #ifdef FSUAE
441 #include "uae/asm.h"
442 #else
443 #ifdef X86_ASSEMBLY
444 #define ASM_SYM_FOR_FUNC(a) __asm__(a)
445 #else
446 #define ASM_SYM_FOR_FUNC(a)
447 #endif
448 #endif
449 
450 #include "target.h"
451 
452 #ifdef UAE_CONSOLE
453 #undef write_log
454 #define write_log write_log_standard
455 #endif
456 
457 #ifdef FSUAE
458 #include "uae/log.h"
459 #else
460 #if __GNUC__ - 1 > 1 || __GNUC_MINOR__ - 1 > 6
461 extern void write_log (const TCHAR *, ...);
462 extern void write_log (const char *, ...) __attribute__ ((format (printf, 1, 2)));
463 #else
464 extern void write_log (const TCHAR *, ...);
465 extern void write_log (const char *, ...);
466 #endif
467 #endif
468 extern void write_dlog (const TCHAR *, ...);
469 extern int read_log(void);
470 
471 extern void flush_log (void);
472 extern TCHAR *setconsolemode (TCHAR *buffer, int maxlen);
473 extern void close_console (void);
474 extern void reopen_console (void);
475 extern void activate_console (void);
476 extern void console_out (const TCHAR *);
477 extern void console_out_f (const TCHAR *, ...);
478 extern void console_flush (void);
479 extern int console_get (TCHAR *, int);
480 extern bool console_isch (void);
481 extern TCHAR console_getch (void);
482 extern void f_out (void *, const TCHAR *, ...);
483 extern TCHAR* buf_out (TCHAR *buffer, int *bufsize, const TCHAR *format, ...);
484 extern void gui_message (const TCHAR *,...);
485 extern int gui_message_multibutton (int flags, const TCHAR *format,...);
486 #define write_log_err write_log
487 extern void logging_init (void);
488 extern FILE *log_open (const TCHAR *name, int append, int bootlog, TCHAR*);
489 extern void log_close (FILE *f);
490 
491 
492 #ifndef O_BINARY
493 #define O_BINARY 0
494 #endif
495 
496 #ifdef FSUAE
497 #include "uae/inline.h"
498 #else
499 #ifndef STATIC_INLINE
500 #if __GNUC__ - 1 > 1 && __GNUC_MINOR__ - 1 >= 0
501 #define STATIC_INLINE static __inline__ __attribute__ ((always_inline))
502 #define NOINLINE __attribute__ ((noinline))
503 #define NORETURN __attribute__ ((noreturn))
504 #elif _MSC_VER
505 #define STATIC_INLINE static __forceinline
506 #define NOINLINE __declspec(noinline)
507 #define NORETURN __declspec(noreturn)
508 #else
509 #define STATIC_INLINE static __inline__
510 #define NOINLINE
511 #define NORETURN
512 #endif
513 #endif
514 #endif
515 
516 #ifdef FSUAE // NL
517 #include "uae/cycleunit.h"
518 #else
519 /* Every Amiga hardware clock cycle takes this many "virtual" cycles.  This
520    used to be hardcoded as 1, but using higher values allows us to time some
521    stuff more precisely.
522    512 is the official value from now on - it can't change, unless we want
523    _another_ config option "finegrain2_m68k_speed".
524 
525    We define this value here rather than in events.h so that gencpu.c sees
526    it.  */
527 #define CYCLE_UNIT 512
528 
529 /* This one is used by cfgfile.c.  We could reduce the CYCLE_UNIT back to 1,
530    I'm not 100% sure this code is bug free yet.  */
531 #define OFFICIAL_CYCLE_UNIT 512
532 #endif
533 
534 /*
535  * You can specify numbers from 0 to 5 here. It is possible that higher
536  * numbers will make the CPU emulation slightly faster, but if the setting
537  * is too high, you will run out of memory while compiling.
538  * Best to leave this as it is.
539  */
540 #define CPU_EMU_SIZE 0
541 
542 /*
543  * Byte-swapping functions
544  */
545 
546 /* Try to use system bswap_16/bswap_32 functions. */
547 #if defined HAVE_BSWAP_16 && defined HAVE_BSWAP_32
548 # include <byteswap.h>
549 #  ifdef HAVE_BYTESWAP_H
550 #  include <byteswap.h>
551 # endif
552 #else
553 /* Else, if using SDL, try SDL's endian functions. */
554 # ifdef USE_SDL
555 #  include <SDL_endian.h>
556 #  define bswap_16(x) SDL_Swap16(x)
557 #  define bswap_32(x) SDL_Swap32(x)
558 # else
559 /* Otherwise, we'll roll our own. */
560 #  define bswap_16(x) (((x) >> 8) | (((x) & 0xFF) << 8))
561 #  define bswap_32(x) (((x) << 24) | (((x) << 8) & 0x00FF0000) | (((x) >> 8) & 0x0000FF00) | ((x) >> 24))
562 # endif
563 #endif
564 
565 #ifndef __cplusplus
566 
567 #define xmalloc(T, N) malloc(sizeof (T) * (N))
568 #define xcalloc(T, N) calloc(sizeof (T), N)
569 #define xfree(T) free(T)
570 #define xrealloc(T, TP, N) realloc(TP, sizeof (T) * (N))
571 
572 #if 0
573 extern void *xmalloc (size_t);
574 extern void *xcalloc (size_t, size_t);
575 extern void xfree (const void*);
576 #endif
577 
578 #else
579 
580 #define xmalloc(T, N) static_cast<T*>(malloc (sizeof (T) * (N)))
581 #define xcalloc(T, N) static_cast<T*>(calloc (sizeof (T), N))
582 #define xrealloc(T, TP, N) static_cast<T*>(realloc (TP, sizeof (T) * (N)))
583 #define xfree(T) free(T)
584 
585 #endif
586 
587 #define DBLEQU(f, i) (abs ((f) - (i)) < 0.000001)
588 
589 #ifdef HAVE_VAR_ATTRIBUTE_UNUSED
590 #define NOWARN_UNUSED(x) __attribute__((unused)) x
591 #else
592 #define NOWARN_UNUSED(x) x
593 #endif
594 
595 #endif /* UAE_SYSDEPS_H */
596