aboutsummaryrefslogtreecommitdiff
path: root/SrcShared/Switches.h
blob: 0dc0ca83fb20fff7311af44b6cdce194d6838cd4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/* -*- mode: C++; tab-width: 4 -*- */
/* ===================================================================== *\
	Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries.
	All rights reserved.

	This file is part of the Palm OS Emulator.

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
\* ===================================================================== */

#ifndef _SWITCHES_H_
#define _SWITCHES_H_

// Use convention: for the preprocessor symbols in this file used to
// turn features on and off, we follow the "if 0 or not 0" convention,
// not the "if defined or not defined" convention.  Thus, to turn
// off a feature, set the symbol to 0.  To turn on a feature, set the
// symbol to 1.

// BYTESWAP is used by Byteswapping.h/.cpp to determine if
// byteswapping should actually occur.  If not, it's a NOP.

#if PLATFORM_WINDOWS || defined (HAVE_ENDIAN_H)

	#include <endian.h>

#elif PLATFORM_MAC || defined (HAVE_MACHINE_ENDIAN_H)

	#include <machine/endian.h>

#elif defined(HAVE_SYS_ISA_DEFS_H)

	// This should handle both Solaris/Sparc and Solaris/Intel
	#include <sys/isa_defs.h>	// Defines either _BIG_ENDIAN or _LITTLE_ENDIAN

#else

	#error "You need to define __BYTE_ORDER for this platform."

	// You can either define __BYTE_ORDER here, or you can provide
	// a file called endian.h.  If you take the latter course, rerun
	// the configure script so that it can rebuild the makefile with
	// HAVE_ENDIAN_H defined.

	#define	__LITTLE_ENDIAN	1234
	#define	__BIG_ENDIAN	4321
	#define	__PDP_ENDIAN	3412
	#define __BYTE_ORDER	<one of the above>

#endif

// Settle on a canonical name.

#if defined (__BYTE_ORDER)

	#define	EM_LITTLE_ENDIAN	__LITTLE_ENDIAN
	#define	EM_BIG_ENDIAN		__BIG_ENDIAN
	#define	EM_PDP_ENDIAN		__PDP_ENDIAN
	#define EM_HOST_BYTE_ORDER	__BYTE_ORDER

#elif defined (BYTE_ORDER)

	#define	EM_LITTLE_ENDIAN	LITTLE_ENDIAN
	#define	EM_BIG_ENDIAN		BIG_ENDIAN
	#define	EM_PDP_ENDIAN		PDP_ENDIAN
	#define EM_HOST_BYTE_ORDER	BYTE_ORDER

#elif defined (_BIG_ENDIAN) || defined (_LITTLE_ENDIAN)

	#define	EM_LITTLE_ENDIAN	1234
	#define	EM_BIG_ENDIAN		4321
	#define	EM_PDP_ENDIAN		3412

	#if defined (_BIG_ENDIAN)
		#define EM_HOST_BYTE_ORDER	EM_BIG_ENDIAN
	#else
		#define EM_HOST_BYTE_ORDER	EM_LITTLE_ENDIAN
	#endif

#else

	#error "Neither BYTE_ORDER nor __BYTE_ORDER defined for this platform."

#endif


#if (EM_HOST_BYTE_ORDER == EM_LITTLE_ENDIAN)
	#define BYTESWAP			1
	#define WORDSWAP_MEMORY		1		// Gives us 12% speedup.

	// (adam) When WORDSWAP_MEMORY is defined, a sequence of bytes which is stored in memory on
	// the Pilot in the sequence A, B, C, D is stored in Windows memory in the sequence B, A, D, C.
	// This means that if p is the address of a byte in Pilot memory, (p ^ 1) is its address in
	// Windows memory.  This is fast because we can load a 16-bit word from Windows memory without doing any
	// byte swapping and without having to mutate its address, and because we can load a 32-bit int
	// from Windows memory just by flipping the 16 high-order bits with the 16 low-order bits.
	//
	// I thought about whether we could store the above bytes in Windows memory in the "longswapped" sequence
	// D, C, B, A, which would allow us to load a 32-bit int without doing any byte swapping at all;
	// we would then have to mutate a pointer p to a 16-bit-word into (p ^ 2).  That would probably
	// be even better than word swapping if all 32-bit accesses were 32-bit aligned.  Since the 68000
	// allows 32-bit accesses on arbitrary 16-bit boundaries, however, this scheme won't work.  For
	// example, suppose that the 68000 contains a sequence of bytes starting at address 0x1000:
	//     1, 2, 3, 4, 5, 6, 7, 8
	// And suppose that we store these bytes in the emulator as
	//     4, 3, 2, 1, 8, 7, 6, 5
	// Now if we load a 32-bit int starting at 0x1000 simply by reading it from Intel memory, we get
	// the value 0x01020304, which is correct.
	// But if we load a 32-bit int starting at 0x1002, we get the value 0x07080102, whereas we wanted
	// the value 0x03040506.
	// We could still make this work if we checked for 32-bit accesses which were not aligned on
	// 32-bit boundaries, but I'm not sure whether it would be worth the performance gain.
	// I don't know whether the "12% speedup" listed above is a speedup over storing bytes in Windows
	// memory exactly as they are stored in 68000 memory, or over storing bytes in this "longswapped" way.
	//
	// (keith) The former.  I never implemented "longswapped" for the reasons you gave.
#else
	#define BYTESWAP			0
	#define WORDSWAP_MEMORY		0
#endif


// Define UNALIGNED_LONG_ACCESS to 1 if the host processor can
// access 32-bit values on all 16-bit boundaries.  Setting it to
// 0 will cause the emulator to fetch 32-bit values with two
// 16-bit operations.

#if defined (sparc)
	#define UNALIGNED_LONG_ACCESS	0
#else
	#define UNALIGNED_LONG_ACCESS	1
#endif

// Define a utility symbol that is guaranteed to be one in debug mode
// and zero in non-debug mode (I don't know what _DEBUG is actually
// defined to, so I'm not going to make any assumptions...)

#if defined (_DEBUG)
	#define ON_IN_DEBUG_MODE	1
#else
	#define ON_IN_DEBUG_MODE	0
#endif


// Define PROFILE_MEMORY to 1 to turn on profiling of memory access.
// Profiling means collecting how often various sections of memory
// are accessed and how they are accessed (read vs. write, byte vs.
// word vs. long.)

#define PROFILE_MEMORY			0


// Define REGISTER_HISTORY to 1 to keep a history of the last 512
// register states.

#define REGISTER_HISTORY		ON_IN_DEBUG_MODE


// Define EXCEPTION_HISTORY to 1 to keep a history of the last 512
// exceptions encountered.

#define EXCEPTION_HISTORY		ON_IN_DEBUG_MODE


// The number of ticks between calls to WaitNextEvent (Mac only).

#define EVENT_THRESHHOLD		6


// Define NATIVE_DISPATCHING to 1 to have the emulator manage
// the dispatching of SYSTRAP functions.  Otherwise, the ROM
// handles the dispatching.  The advantage of having the emulator
// do the dispatching is that it's faster.

#define NATIVE_DISPATCHING		1


// Define HAS_TRACER to 1 to include Tracer facility.

#if PLATFORM_MAC || PLATFORM_WINDOWS
	#define HAS_TRACER				1
#else
	#define HAS_TRACER				0
#endif


// Define HAS_OMNI_THREAD 1 to if this platform uses that facility
// for multi-threading.

#if PLATFORM_UNIX || PLATFORM_WINDOWS
	#define HAS_OMNI_THREAD			1
#else
	#define HAS_OMNI_THREAD			0
#endif


// Define sub-flags for specific internal features.



// The emulator can optionally check all access to memory to flag questionable
// or illegal accesses.  There are two ways this checking can be controlled.
//
// At the first level, there are runtime variables that turn on and off
// this checking.  The variables control a fine-grain level of checking:
// there are read and write flags for DRAM, SRAM, ROM, and "unmapped
// memory" (for 8 flags in all).  Additionally, we have flags for checking
// for accesses to Dragonballs registers and low-memory, for 12 flags in
// all.
//
// These flags can be turned on and off at runtime.  However, there is
// still the penalty of constantly checking these flags at runtime, even
// if they are turned off.  Therefore, we can opt to compile those checks
// out for maximum performance.  For each runtime flag, there is a
// corresponding compile time flag that controls whether or not the
// runtime check is made.  If the compile time flag is true, the check
// is made based on the value of the runtime flag.  If the compile time
// flag is false, then the code for the runtime check is removed.
//
// With the compile and runtime flags turned on, startup time on
// my Mac is about 1622 msecs.  With the compile-time flags turned
// off, startup time is about 1407 msecs.  With the compile-time flags
// turned on, but the runtime flags turned off, startup time is
// about 1508 msecs.

#define VALIDATE_DUMMY_GET					1
#define VALIDATE_DUMMY_SET					1
#define VALIDATE_REGISTER_GET				0
#define VALIDATE_REGISTER_SET				0
#define VALIDATE_DRAM_GET					1
#define VALIDATE_DRAM_SET					1
#define VALIDATE_SRAM_GET					0
#define VALIDATE_SRAM_SET					0
#define VALIDATE_ROM_GET					0
#define VALIDATE_ROM_SET					1

#define PREVENT_USER_LOWMEM_GET				1
#define PREVENT_USER_LOWMEM_SET				1
#define PREVENT_USER_GLOBAL_GET				1
#define PREVENT_USER_GLOBAL_SET				1
#define PREVENT_USER_SCREEN_GET				1
#define PREVENT_USER_SCREEN_SET				1
#define PREVENT_USER_SRAM_GET				0
#define PREVENT_USER_SRAM_SET				1
#define PREVENT_USER_ROM_GET				0
#define PREVENT_USER_ROM_SET				1
#define PREVENT_USER_REGISTER_GET			1
#define PREVENT_USER_REGISTER_SET			1

#define PREVENT_SYSTEM_LOWMEM_GET			1
#define PREVENT_SYSTEM_LOWMEM_SET			1
#define PREVENT_SYSTEM_ROM_GET				0
#define PREVENT_SYSTEM_ROM_SET				1

#define CHECK_FOR_ADDRESS_ERROR				1
#define CHECK_FOR_LOW_STACK_ACCESS			1
#define CHECK_CHUNK_ACCESS					0

#define MASTER_RUNTIME_VALIDATE_SWITCH		1
#define MASTER_RUNTIME_PREVENT_SWITCH		1

#endif /* _SWITCHES_H_ */