Browse code

update for C++17 compliance, update to latest 2sf, add WINE cross-compile makefiles

Adam Higerd authored on 2021/02/11 15:36:17
Showing 1 changed files
... ...
@@ -139,7 +139,7 @@ uint32_t armcpu_switchMode(armcpu_t *armcpu, uint8_t mode)
139 139
 			armcpu->SPSR_und = armcpu->SPSR;
140 140
 			break;
141 141
 		default:
142
-			printf("switchMode: WRONG mode %02X\n",mode);
142
+			fprintf(stderr, "switchMode: WRONG mode %02X\n",mode);
143 143
 	}
144 144
 
145 145
 	switch (mode)
... ...
@@ -275,7 +275,7 @@ void armcpu_exception(armcpu_t *cpu, uint32_t number)
275 275
 	cpu->changeCPSR();
276 276
 	cpu->R[15] = cpu->intVector + number;
277 277
 	cpu->next_instruction = cpu->R[15];
278
-	printf("armcpu_exception!\n");
278
+	fprintf(stderr, "armcpu_exception!\n");
279 279
 
280 280
 	// HOW DOES THIS WORTK WITHOUT A PREFETCH, LIKE IRQ BELOW?
281 281
 	// I REALLY WISH WE DIDNT PREFETCH BEFORE EXECUTING
... ...
@@ -329,7 +329,7 @@ template<int PROCNUM> uint32_t armcpu_exec()
329 329
 
330 330
 	//cFetch = armcpu_prefetch(&ARMPROC);
331 331
 
332
-	//printf("%d: %08X\n",PROCNUM,ARMPROC.instruct_adr);
332
+	//fprintf(stderr, "%d: %08X\n",PROCNUM,ARMPROC.instruct_adr);
333 333
 
334 334
 	if (!ARMPROC.CPSR.bits.T)
335 335
 	{
Browse code

* Fixes for gcc and clang (while they can compile the code, the DLLs made aren't functional, but oh well).

* [2SF] Used more up-to-date asmjit, despite the ugly looking code.

Naram Qashat authored on 2014/09/17 19:51:45
Showing 1 changed files
... ...
@@ -71,7 +71,7 @@ void armcpu_init(armcpu_t *armcpu, uint32_t adr)
71 71
 #if defined(_M_X64) || defined(__x86_64__)
72 72
 	memcpy(&armcpu->cond_table[0], &arm_cond_table[0], sizeof(arm_cond_table));
73 73
 #endif
74
-	
74
+
75 75
 	armcpu->LDTBit = !armcpu->proc_ID; // Si ARM9 utiliser le syte v5 pour le load
76 76
 	armcpu->intVector = 0xFFFF0000 * !armcpu->proc_ID;
77 77
 	armcpu->waitIRQ = false;
Browse code

Updating in_2sf to use a newish version of DeSmuME, 0.9.9 from SVN. Somewhat cleaned up as well, but not everything because it's a pain in the ass.

Naram Qashat authored on 2013/04/18 17:22:55
Showing 1 changed files
... ...
@@ -16,196 +16,40 @@
16 16
 	along with the this software.  If not, see <http://www.gnu.org/licenses/>.
17 17
 */
18 18
 
19
+#include <algorithm>
19 20
 #include <cstdlib>
20 21
 #include <cstdio>
21 22
 #include <cassert>
22
-#include <algorithm>
23
-
24 23
 #include "types.h"
25
-#include "arm_instructions.h"
26
-#include "thumb_instructions.h"
24
+#include "instructions.h"
27 25
 #include "cp15.h"
28 26
 #include "bios.h"
29
-//#include "debug.h"
30
-//#include "Disassembler.h"
31 27
 #include "NDSSystem.h"
32 28
 #include "MMU_timing.h"
33 29
 #ifdef HAVE_LUA
34 30
 #include "lua-engine.h"
35 31
 #endif
32
+#ifdef HAVE_JIT
33
+#include "arm_jit.h"
34
+#endif
36 35
 
37 36
 template<uint32_t> static uint32_t armcpu_prefetch();
38 37
 
39
-inline uint32_t armcpu_prefetch(armcpu_t *armcpu) {
40
-	if(armcpu->proc_ID==0) return armcpu_prefetch<0>();
41
-	else return armcpu_prefetch<1>();
38
+static inline uint32_t armcpu_prefetch(armcpu_t *armcpu)
39
+{
40
+	if (!armcpu->proc_ID)
41
+		return armcpu_prefetch<0>();
42
+	else
43
+		return armcpu_prefetch<1>();
42 44
 }
43 45
 
44
-const unsigned char arm_cond_table[16*16] = {
45
-    /* N=0, Z=0, C=0, V=0 */
46
-    0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
47
-    0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
48
-    /* N=0, Z=0, C=0, V=1 */
49
-    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00,
50
-    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
51
-    /* N=0, Z=0, C=1, V=0 */
52
-    0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,
53
-    0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
54
-    /* N=0, Z=0, C=1, V=1 */
55
-    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,
56
-    0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
57
-    /* N=0, Z=1, C=0, V=0 */
58
-    0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,
59
-    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
60
-    /* N=0, Z=1, C=0, V=1 */
61
-    0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00,
62
-    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
63
-    /* N=0, Z=1, C=1, V=0 */
64
-    0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF,
65
-    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
66
-    /* N=0, Z=1, C=1, V=1 */
67
-    0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00,
68
-    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
69
-    /* N=1, Z=0, C=0, V=0 */
70
-    0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF,
71
-    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
72
-    /* N=1, Z=0, C=0, V=1 */
73
-    0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00,
74
-    0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
75
-    /* N=1, Z=0, C=1, V=0 */
76
-    0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF,
77
-    0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
78
-    /* N=1, Z=0, C=1, V=1 */
79
-    0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00,
80
-    0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
81
-    /* N=1, Z=1, C=0, V=0 */
82
-    0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,
83
-    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
84
-    /* N=1, Z=1, C=0, V=1 */
85
-    0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00,
86
-    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
87
-    /* N=1, Z=1, C=1, V=0 */
88
-    0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF,
89
-    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
90
-    /* N=1, Z=1, C=1, V=1 */
91
-    0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
92
-    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
93
-};
94
-
95 46
 armcpu_t NDS_ARM7;
96 47
 armcpu_t NDS_ARM9;
97 48
 
98
-/*#define SWAP(a, b, c) do      \
99
-	              {       \
100
-                         c=a; \
101
-                         a=b; \
102
-                         b=c; \
103
-		      }       \
104
-                      while(0)*/
105
-template<typename T> static inline void SWAP(T &a, T &b)
106
-{
107
-	T c = a;
108
-	a = b;
109
-	b = c;
110
-}
111
-
112
-#ifdef GDB_STUB
113
-
114
-#define STALLED_CYCLE_COUNT 10
115
-
116
-static void
117
-stall_cpu( void *instance) {
118
-  armcpu_t *armcpu = (armcpu_t *)instance;
119
-  printf("UNSTALL\n");
120
-  armcpu->stalled = 1;
121
-}
122
-
123
-static void
124
-unstall_cpu( void *instance) {
125
-  armcpu_t *armcpu = (armcpu_t *)instance;
126
-  printf("UNSTALL\n");
127
-  armcpu->stalled = 0;
128
-}
129
-
130
-static void
131
-install_post_exec_fn( void *instance,
132
-                      void (*ex_fn)( void *, uint32_t adr, int thumb),
133
-                      void *fn_data) {
134
-  armcpu_t *armcpu = (armcpu_t *)instance;
135
-
136
-
137
-  armcpu->post_ex_fn = ex_fn;
138
-  armcpu->post_ex_fn_data = fn_data;
139
-}
140
-
141
-static void
142
-remove_post_exec_fn( void *instance) {
143
-  armcpu_t *armcpu = (armcpu_t *)instance;
144
-
145
-  armcpu->post_ex_fn = NULL;
146
-}
147
-#endif
148
-
149
-#ifdef GDB_STUB
150
-static uint32_t read_cpu_reg( void *instance, uint32_t reg_num)
151
-{
152
-	armcpu_t *armcpu = (armcpu_t *)instance;
153
-
154
-	if ( reg_num <= 14) {
155
-	  return armcpu->R[reg_num];
156
-	}
157
-	else if ( reg_num == 15) {
158
-	  return armcpu->instruct_adr;
159
-	}
160
-	else if ( reg_num == 16) {
161
-	  //CPSR
162
-	  return armcpu->CPSR.val;
163
-	}
164
-}
165
-
166
-static void
167
-set_cpu_reg( void *instance, uint32_t reg_num, uint32_t value) {
168
-  armcpu_t *armcpu = (armcpu_t *)instance;
169
-
170
-  if ( reg_num <= 14) {
171
-    armcpu->R[reg_num] = value;
172
-  }
173
-  else if ( reg_num == 15) {
174
-    armcpu->next_instruction = value;
175
-  }
176
-  else if ( reg_num == 16) {
177
-    /* FIXME: setting the CPSR */
178
-  }
179
-}
180
-#endif
181
-
182
-#ifdef GDB_STUB
183
-int armcpu_new( armcpu_t *armcpu, uint32_t id,
184
-                struct armcpu_memory_iface *mem_if,
185
-                struct armcpu_ctrl_iface **ctrl_iface_ret)
186
-#else
187
-int armcpu_new( armcpu_t *armcpu, uint32_t id)
188
-#endif
49
+int armcpu_new(armcpu_t *armcpu, uint32_t id)
189 50
 {
190 51
 	armcpu->proc_ID = id;
191 52
 
192
-#ifdef GDB_STUB
193
-	armcpu->mem_if = mem_if;
194
-
195
-	/* populate the control interface */
196
-	armcpu->ctrl_iface.stall = stall_cpu;
197
-	armcpu->ctrl_iface.unstall = unstall_cpu;
198
-	armcpu->ctrl_iface.read_reg = read_cpu_reg;
199
-	armcpu->ctrl_iface.set_reg = set_cpu_reg;
200
-	armcpu->ctrl_iface.install_post_ex_fn = install_post_exec_fn;
201
-	armcpu->ctrl_iface.remove_post_ex_fn = remove_post_exec_fn;
202
-	armcpu->ctrl_iface.data = armcpu;
203
-
204
-	*ctrl_iface_ret = &armcpu->ctrl_iface;
205
-
206
-	armcpu->post_ex_fn = NULL;
207
-#endif
208
-
209 53
 	armcpu->stalled = 0;
210 54
 
211 55
 	armcpu_init(armcpu, 0);
... ...
@@ -213,33 +57,29 @@ int armcpu_new( armcpu_t *armcpu, uint32_t id)
213 57
 	return 0;
214 58
 }
215 59
 
216
-//call this whenever CPSR is changed (other than CNVZQ or T flags); interrupts may need to be unleashed
60
+// call this whenever CPSR is changed (other than CNVZQ or T flags); interrupts may need to be unleashed
217 61
 void armcpu_t::changeCPSR()
218 62
 {
219
-	//but all it does is give them a chance to unleash by forcing an immediate reschedule
220
-	//TODO - we could actually set CPSR through here and look for a change in the I bit
221
-	//that would be a little optimization as well as a safety measure if we prevented setting CPSR directly
63
+	// but all it does is give them a chance to unleash by forcing an immediate reschedule
64
+	// TODO - we could actually set CPSR through here and look for a change in the I bit
65
+	// that would be a little optimization as well as a safety measure if we prevented setting CPSR directly
222 66
 	NDS_Reschedule();
223 67
 }
224 68
 
225 69
 void armcpu_init(armcpu_t *armcpu, uint32_t adr)
226 70
 {
227
-	armcpu->LDTBit = (armcpu->proc_ID==0); //Si ARM9 utiliser le syte v5 pour le load
228
-	armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0);
71
+#if defined(_M_X64) || defined(__x86_64__)
72
+	memcpy(&armcpu->cond_table[0], &arm_cond_table[0], sizeof(arm_cond_table));
73
+#endif
74
+	
75
+	armcpu->LDTBit = !armcpu->proc_ID; // Si ARM9 utiliser le syte v5 pour le load
76
+	armcpu->intVector = 0xFFFF0000 * !armcpu->proc_ID;
229 77
 	armcpu->waitIRQ = false;
230 78
 	armcpu->halt_IE_and_IF = false;
231 79
 	armcpu->intrWaitARM_state = 0;
232 80
 
233
-//#ifdef GDB_STUB
234
-//    armcpu->irq_flag = 0;
235
-//#endif
236
-
237
-	for(int i = 0; i < 16; ++i)
238
-	{
81
+	for (int i = 0; i < 16; ++i)
239 82
 		armcpu->R[i] = 0;
240
-		if(armcpu->coproc[i]) free(armcpu->coproc[i]);
241
-		armcpu->coproc[i] = NULL;
242
-	}
243 83
 
244 84
 	armcpu->CPSR.val = armcpu->SPSR.val = SYS;
245 85
 
... ...
@@ -252,125 +92,96 @@ void armcpu_init(armcpu_t *armcpu, uint32_t adr)
252 92
 
253 93
 	armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0;
254 94
 
255
-//#ifdef GDB_STUB
256
-//    armcpu->instruct_adr = adr;
257
-//	armcpu->R[15] = adr + 8;
258
-//#else
259
-	//armcpu->R[15] = adr;
260
-//#endif
261
-
262 95
 	armcpu->next_instruction = adr;
263 96
 
264
-	// only ARM9 have co-processor
265
-	if (armcpu->proc_ID==0)
266
-		armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu);
267
-
268
-//#ifndef GDB_STUB
269 97
 	armcpu_prefetch(armcpu);
270
-//#endif
271 98
 }
272 99
 
273 100
 uint32_t armcpu_switchMode(armcpu_t *armcpu, uint8_t mode)
274 101
 {
275 102
 	uint32_t oldmode = armcpu->CPSR.bits.mode;
276 103
 
277
-	switch(oldmode)
104
+	switch (oldmode)
278 105
 	{
279
-		case USR :
280
-		case SYS :
106
+		case USR:
107
+		case SYS:
281 108
 			armcpu->R13_usr = armcpu->R[13];
282 109
 			armcpu->R14_usr = armcpu->R[14];
283 110
 			break;
284
-
285
-		case FIQ :
286
-			{
287
-                                //uint32_t tmp;
288
-				SWAP(armcpu->R[8], armcpu->R8_fiq/*, tmp*/);
289
-				SWAP(armcpu->R[9], armcpu->R9_fiq/*, tmp*/);
290
-				SWAP(armcpu->R[10], armcpu->R10_fiq/*, tmp*/);
291
-				SWAP(armcpu->R[11], armcpu->R11_fiq/*, tmp*/);
292
-				SWAP(armcpu->R[12], armcpu->R12_fiq/*, tmp*/);
293
-				armcpu->R13_fiq = armcpu->R[13];
294
-				armcpu->R14_fiq = armcpu->R[14];
295
-				armcpu->SPSR_fiq = armcpu->SPSR;
296
-				break;
297
-			}
298
-		case IRQ :
111
+		case FIQ:
112
+			std::swap(armcpu->R[8], armcpu->R8_fiq);
113
+			std::swap(armcpu->R[9], armcpu->R9_fiq);
114
+			std::swap(armcpu->R[10], armcpu->R10_fiq);
115
+			std::swap(armcpu->R[11], armcpu->R11_fiq);
116
+			std::swap(armcpu->R[12], armcpu->R12_fiq);
117
+			armcpu->R13_fiq = armcpu->R[13];
118
+			armcpu->R14_fiq = armcpu->R[14];
119
+			armcpu->SPSR_fiq = armcpu->SPSR;
120
+			break;
121
+		case IRQ:
299 122
 			armcpu->R13_irq = armcpu->R[13];
300 123
 			armcpu->R14_irq = armcpu->R[14];
301 124
 			armcpu->SPSR_irq = armcpu->SPSR;
302 125
 			break;
303
-
304
-		case SVC :
126
+		case SVC:
305 127
 			armcpu->R13_svc = armcpu->R[13];
306 128
 			armcpu->R14_svc = armcpu->R[14];
307 129
 			armcpu->SPSR_svc = armcpu->SPSR;
308 130
 			break;
309
-
310
-		case ABT :
131
+		case ABT:
311 132
 			armcpu->R13_abt = armcpu->R[13];
312 133
 			armcpu->R14_abt = armcpu->R[14];
313 134
 			armcpu->SPSR_abt = armcpu->SPSR;
314 135
 			break;
315
-
316
-		case UND :
136
+		case UND:
317 137
 			armcpu->R13_und = armcpu->R[13];
318 138
 			armcpu->R14_und = armcpu->R[14];
319 139
 			armcpu->SPSR_und = armcpu->SPSR;
320 140
 			break;
321
-		default :
322
-			break;
323
-		}
141
+		default:
142
+			printf("switchMode: WRONG mode %02X\n",mode);
143
+	}
324 144
 
325
-		switch(mode)
326
-		{
327
-			case USR :
328
-			case SYS :
329
-				armcpu->R[13] = armcpu->R13_usr;
330
-				armcpu->R[14] = armcpu->R14_usr;
331
-				//SPSR = CPSR;
332
-				break;
333
-
334
-			case FIQ :
335
-				{
336
-					//uint32_t tmp;
337
-					SWAP(armcpu->R[8], armcpu->R8_fiq/*, tmp*/);
338
-					SWAP(armcpu->R[9], armcpu->R9_fiq/*, tmp*/);
339
-					SWAP(armcpu->R[10], armcpu->R10_fiq/*, tmp*/);
340
-					SWAP(armcpu->R[11], armcpu->R11_fiq/*, tmp*/);
341
-					SWAP(armcpu->R[12], armcpu->R12_fiq/*, tmp*/);
342
-					armcpu->R[13] = armcpu->R13_fiq;
343
-					armcpu->R[14] = armcpu->R14_fiq;
344
-					armcpu->SPSR = armcpu->SPSR_fiq;
345
-					break;
346
-				}
347
-
348
-			case IRQ :
349
-				armcpu->R[13] = armcpu->R13_irq;
350
-				armcpu->R[14] = armcpu->R14_irq;
351
-				armcpu->SPSR = armcpu->SPSR_irq;
352
-				break;
353
-
354
-			case SVC :
355
-				armcpu->R[13] = armcpu->R13_svc;
356
-				armcpu->R[14] = armcpu->R14_svc;
357
-				armcpu->SPSR = armcpu->SPSR_svc;
358
-				break;
359
-
360
-			case ABT :
361
-				armcpu->R[13] = armcpu->R13_abt;
362
-				armcpu->R[14] = armcpu->R14_abt;
363
-				armcpu->SPSR = armcpu->SPSR_abt;
364
-				break;
365
-
366
-          case UND :
367
-				armcpu->R[13] = armcpu->R13_und;
368
-				armcpu->R[14] = armcpu->R14_und;
369
-				armcpu->SPSR = armcpu->SPSR_und;
370
-				break;
371
-
372
-				default :
373
-					break;
145
+	switch (mode)
146
+	{
147
+		case USR:
148
+		case SYS:
149
+			armcpu->R[13] = armcpu->R13_usr;
150
+			armcpu->R[14] = armcpu->R14_usr;
151
+			//SPSR = CPSR;
152
+			break;
153
+		case FIQ:
154
+			std::swap(armcpu->R[8], armcpu->R8_fiq);
155
+			std::swap(armcpu->R[9], armcpu->R9_fiq);
156
+			std::swap(armcpu->R[10], armcpu->R10_fiq);
157
+			std::swap(armcpu->R[11], armcpu->R11_fiq);
158
+			std::swap(armcpu->R[12], armcpu->R12_fiq);
159
+			armcpu->R[13] = armcpu->R13_fiq;
160
+			armcpu->R[14] = armcpu->R14_fiq;
161
+			armcpu->SPSR = armcpu->SPSR_fiq;
162
+			break;
163
+		case IRQ:
164
+			armcpu->R[13] = armcpu->R13_irq;
165
+			armcpu->R[14] = armcpu->R14_irq;
166
+			armcpu->SPSR = armcpu->SPSR_irq;
167
+			break;
168
+		case SVC:
169
+			armcpu->R[13] = armcpu->R13_svc;
170
+			armcpu->R[14] = armcpu->R14_svc;
171
+			armcpu->SPSR = armcpu->SPSR_svc;
172
+			break;
173
+		case ABT:
174
+			armcpu->R[13] = armcpu->R13_abt;
175
+			armcpu->R[14] = armcpu->R14_abt;
176
+			armcpu->SPSR = armcpu->SPSR_abt;
177
+			break;
178
+		case UND:
179
+			armcpu->R[13] = armcpu->R13_und;
180
+			armcpu->R[14] = armcpu->R14_und;
181
+			armcpu->SPSR = armcpu->SPSR_und;
182
+			break;
183
+		default:
184
+			break;
374 185
 	}
375 186
 
376 187
 	armcpu->CPSR.bits.mode = mode & 0x1F;
... ...
@@ -385,217 +196,127 @@ uint32_t armcpu_Wait4IRQ(armcpu_t *cpu)
385 196
 	return 1;
386 197
 }
387 198
 
388
-template<uint32_t PROCNUM>
389
-inline static uint32_t armcpu_prefetch()
199
+template<uint32_t PROCNUM> static inline uint32_t armcpu_prefetch()
390 200
 {
391
-	armcpu_t* const armcpu = &ARMPROC;
392
-//#ifdef GDB_STUB
393
-//	uint32_t temp_instruction;
394
-//#endif
201
+	armcpu_t *const armcpu = &ARMPROC;
395 202
 	uint32_t curInstruction = armcpu->next_instruction;
396 203
 
397
-	if(armcpu->CPSR.bits.T == 0)
204
+	if (!armcpu->CPSR.bits.T)
398 205
 	{
399
-//#ifdef GDB_STUB
400
-//		temp_instruction =
401
-//			armcpu->mem_if->prefetch32( armcpu->mem_if->data,
402
-//			armcpu->next_instruction);
403
-//
404
-//		if ( !armcpu->stalled) {
405
-//			armcpu->instruction = temp_instruction;
406
-//			armcpu->instruct_adr = armcpu->next_instruction;
407
-//			armcpu->next_instruction += 4;
408
-//			armcpu->R[15] = armcpu->next_instruction + 4;
409
-//		}
410
-//#else
411
-		curInstruction &= 0xFFFFFFFC; //please don't change this to 0x0FFFFFFC -- the NDS will happily run on 0xF******* addresses all day long
412
-		//please note that we must setup R[15] before reading the instruction since there is a protection
413
-		//which prevents PC > 0x3FFF from reading the bios region
206
+		curInstruction &= 0xFFFFFFFC; // please don't change this to 0x0FFFFFFC -- the NDS will happily run on 0xF******* addresses all day long
207
+		// please note that we must setup R[15] before reading the instruction since there is a protection
208
+		// which prevents PC > 0x3FFF from reading the bios region
414 209
 		armcpu->instruct_adr = curInstruction;
415 210
 		armcpu->next_instruction = curInstruction + 4;
416 211
 		armcpu->R[15] = curInstruction + 8;
417 212
 		armcpu->instruction = _MMU_read32<PROCNUM, MMU_AT_CODE>(curInstruction);
418
-//#endif
419 213
 
420
-		return MMU_codeFetchCycles<PROCNUM,32>(curInstruction);
214
+		return MMU_codeFetchCycles<PROCNUM, 32>(curInstruction);
421 215
 	}
422
-
423
-//#ifdef GDB_STUB
424
-//	temp_instruction =
425
-//		armcpu->mem_if->prefetch16( armcpu->mem_if->data,
426
-//		armcpu->next_instruction);
427
-//
428
-//	if ( !armcpu->stalled) {
429
-//		armcpu->instruction = temp_instruction;
430
-//		armcpu->instruct_adr = armcpu->next_instruction;
431
-//		armcpu->next_instruction = armcpu->next_instruction + 2;
432
-//		armcpu->R[15] = armcpu->next_instruction + 2;
433
-//	}
434
-//#else
435
-	curInstruction &= 0xFFFFFFFE; //please don't change this to 0x0FFFFFFE -- the NDS will happily run on 0xF******* addresses all day long
436
-	//please note that we must setup R[15] before reading the instruction since there is a protection
437
-	//which prevents PC > 0x3FFF from reading the bios region
216
+	curInstruction &= 0xFFFFFFFE; // please don't change this to 0x0FFFFFFE -- the NDS will happily run on 0xF******* addresses all day long
217
+	// please note that we must setup R[15] before reading the instruction since there is a protection
218
+	// which prevents PC > 0x3FFF from reading the bios region
438 219
 	armcpu->instruct_adr = curInstruction;
439 220
 	armcpu->next_instruction = curInstruction + 2;
440 221
 	armcpu->R[15] = curInstruction + 4;
441 222
 	armcpu->instruction = _MMU_read16<PROCNUM, MMU_AT_CODE>(curInstruction);
442
-//#endif
443 223
 
444
-	if(PROCNUM==0)
224
+	if (!PROCNUM)
445 225
 	{
446 226
 		// arm9 fetches 2 instructions at a time in thumb mode
447
-		if(!(curInstruction == armcpu->instruct_adr + 2 && (curInstruction & 2)))
448
-			return MMU_codeFetchCycles<PROCNUM,32>(curInstruction);
227
+		if (!(curInstruction == armcpu->instruct_adr + 2 && (curInstruction & 2)))
228
+			return MMU_codeFetchCycles<PROCNUM, 32>(curInstruction);
449 229
 		else
450 230
 			return 0;
451 231
 	}
452 232
 
453
-	return MMU_codeFetchCycles<PROCNUM,16>(curInstruction);
233
+	return MMU_codeFetchCycles<PROCNUM, 16>(curInstruction);
454 234
 }
455 235
 
456
-#if 0 /* not used */
457
-static bool FASTCALL test_EQ(Status_Reg CPSR) { return CPSR.bits.Z; }
458
-static bool FASTCALL test_NE(Status_Reg CPSR) { return !CPSR.bits.Z; }
459
-static bool FASTCALL test_CS(Status_Reg CPSR) { return CPSR.bits.C; }
460
-static bool FASTCALL test_CC(Status_Reg CPSR) { return !CPSR.bits.C; }
461
-static bool FASTCALL test_MI(Status_Reg CPSR) { return CPSR.bits.N; }
462
-static bool FASTCALL test_PL(Status_Reg CPSR) { return !CPSR.bits.N; }
463
-static bool FASTCALL test_VS(Status_Reg CPSR) { return CPSR.bits.V; }
464
-static bool FASTCALL test_VC(Status_Reg CPSR) { return !CPSR.bits.V; }
465
-static bool FASTCALL test_HI(Status_Reg CPSR) { return CPSR.bits.C && !CPSR.bits.Z; }
466
-static bool FASTCALL test_LS(Status_Reg CPSR) { return CPSR.bits.Z || !CPSR.bits.C; }
467
-static bool FASTCALL test_GE(Status_Reg CPSR) { return CPSR.bits.N==CPSR.bits.V; }
468
-static bool FASTCALL test_LT(Status_Reg CPSR) { return CPSR.bits.N!=CPSR.bits.V; }
469
-static bool FASTCALL test_GT(Status_Reg CPSR) { return !CPSR.bits.Z && CPSR.bits.N==CPSR.bits.V; }
470
-static bool FASTCALL test_LE(Status_Reg CPSR) { return CPSR.bits.Z || CPSR.bits.N!=CPSR.bits.V; }
471
-static bool FASTCALL test_AL(Status_Reg CPSR) { return 1; }
472
-
473
-static bool (FASTCALL* test_conditions[])(Status_Reg CPSR)= {
474
-	test_EQ , test_NE ,
475
-	test_CS , test_CC ,
476
-	test_MI , test_PL ,
477
-	test_VS , test_VC ,
478
-	test_HI , test_LS ,
479
-	test_GE , test_LT ,
480
-	test_GT , test_LE ,
481
-	test_AL
482
-};
483
-#define TEST_COND2(cond, CPSR) \
484
-	(cond<15&&test_conditions[cond](CPSR))
485
-#endif
486
-
487
-//TODO - merge with armcpu_irqException?
488
-//http://www.ethernut.de/en/documents/arm-exceptions.html
489
-//http://docs.google.com/viewer?a=v&q=cache:V4ht1YkxprMJ:www.cs.nctu.edu.tw/~wjtsai/EmbeddedSystemDesign/Ch3-1.pdf+arm+exception+handling&hl=en&gl=us&pid=bl&srcid=ADGEEShx9VTHbUhWdDOrTVRzLkcCsVfJiijncNDkkgkrlJkLa7D0LCpO8fQ_hhU3DTcgZh9rcZWWQq4TYhhCovJ625h41M0ZUX3WGasyzWQFxYzDCB-VS6bsUmpoJnRxAc-bdkD0qmsu&sig=AHIEtbR9VHvDOCRmZFQDUVwy53iJDjoSPQ
236
+// TODO - merge with armcpu_irqException?
237
+// http://www.ethernut.de/en/documents/arm-exceptions.html
238
+// http://docs.google.com/viewer?a=v&q=cache:V4ht1YkxprMJ:www.cs.nctu.edu.tw/~wjtsai/EmbeddedSystemDesign/Ch3-1.pdf+arm+exception+handling&hl=en&gl=us&pid=bl&srcid=ADGEEShx9VTHbUhWdDOrTVRzLkcCsVfJiijncNDkkgkrlJkLa7D0LCpO8fQ_hhU3DTcgZh9rcZWWQq4TYhhCovJ625h41M0ZUX3WGasyzWQFxYzDCB-VS6bsUmpoJnRxAc-bdkD0qmsu&sig=AHIEtbR9VHvDOCRmZFQDUVwy53iJDjoSPQ
490 239
 void armcpu_exception(armcpu_t *cpu, uint32_t number)
491 240
 {
492 241
 	Mode cpumode = USR;
493
-	switch(number)
242
+	switch (number)
494 243
 	{
495
-	case EXCEPTION_RESET: cpumode = SVC; break;
496
-	case EXCEPTION_UNDEFINED_INSTRUCTION: cpumode = UND; break;
497
-	case EXCEPTION_SWI: cpumode = SVC; break;
498
-	case EXCEPTION_PREFETCH_ABORT: cpumode = ABT; break;
499
-	case EXCEPTION_DATA_ABORT: cpumode = ABT; break;
500
-	case EXCEPTION_RESERVED_0x14: execute = false;/*emu_halt();*/ break;
501
-	case EXCEPTION_IRQ: cpumode = IRQ; break;
502
-	case EXCEPTION_FAST_IRQ: cpumode = FIQ; break;
244
+		case EXCEPTION_RESET:
245
+			cpumode = SVC;
246
+			break;
247
+		case EXCEPTION_UNDEFINED_INSTRUCTION:
248
+			cpumode = UND;
249
+			break;
250
+		case EXCEPTION_SWI:
251
+			cpumode = SVC;
252
+			break;
253
+		case EXCEPTION_PREFETCH_ABORT:
254
+			cpumode = ABT;
255
+			break;
256
+		case EXCEPTION_DATA_ABORT:
257
+			cpumode = ABT;
258
+			break;
259
+		case EXCEPTION_RESERVED_0x14:
260
+			execute = false;
261
+			break;
262
+		case EXCEPTION_IRQ:
263
+			cpumode = IRQ;
264
+			break;
265
+		case EXCEPTION_FAST_IRQ:
266
+			cpumode = FIQ;
503 267
 	}
504 268
 
505 269
 	Status_Reg tmp = cpu->CPSR;
506
-	armcpu_switchMode(cpu, cpumode);				//enter new mode
270
+	armcpu_switchMode(cpu, cpumode); // enter new mode
507 271
 	cpu->R[14] = cpu->next_instruction;
508
-	cpu->SPSR = tmp;							//save old CPSR as new SPSR
509
-	cpu->CPSR.bits.T = 0;						//handle as ARM32 code
272
+	cpu->SPSR = tmp; // save old CPSR as new SPSR
273
+	cpu->CPSR.bits.T = 0; // handle as ARM32 code
510 274
 	cpu->CPSR.bits.I = 1;
511 275
 	cpu->changeCPSR();
512 276
 	cpu->R[15] = cpu->intVector + number;
513 277
 	cpu->next_instruction = cpu->R[15];
514 278
 	printf("armcpu_exception!\n");
515
-	//extern bool dolog;
516
-	//dolog=true;
517 279
 
518
-	//HOW DOES THIS WORTK WITHOUT A PREFETCH, LIKE IRQ BELOW?
519
-	//I REALLY WISH WE DIDNT PREFETCH BEFORE EXECUTING
280
+	// HOW DOES THIS WORTK WITHOUT A PREFETCH, LIKE IRQ BELOW?
281
+	// I REALLY WISH WE DIDNT PREFETCH BEFORE EXECUTING
520 282
 }
521 283
 
522 284
 bool armcpu_irqException(armcpu_t *armcpu)
523 285
 {
524
-    Status_Reg tmp;
525
-
526
-	//TODO - remove GDB specific code
527
-//#ifdef GDB_STUB
528
-//	armcpu->irq_flag = 0;
529
-//#endif
286
+	Status_Reg tmp;
530 287
 
531 288
 	tmp = armcpu->CPSR;
532 289
 	armcpu_switchMode(armcpu, IRQ);
533 290
 
534
-	//TODO - remove GDB specific code
535
-//#ifdef GDB_STUB
536
-//	armcpu->R[14] = armcpu->next_instruction + 4;
537
-//#else
538 291
 	armcpu->R[14] = armcpu->instruct_adr + 4;
539
-//#endif
540 292
 	armcpu->SPSR = tmp;
541 293
 	armcpu->CPSR.bits.T = 0;
542 294
 	armcpu->CPSR.bits.I = 1;
543 295
 	armcpu->next_instruction = armcpu->intVector + 0x18;
544 296
 	armcpu->waitIRQ = 0;
545 297
 
546
-	//must retain invariant of having next instruction to be executed prefetched
547
-	//(yucky)
298
+	// must retain invariant of having next instruction to be executed prefetched
299
+	// (yucky)
548 300
 	armcpu_prefetch(armcpu);
549 301
 
550 302
 	return true;
551 303
 }
552 304
 
553
-//TODO - remove GDB specific code
554
-//bool
555
-//armcpu_flagIrq( armcpu_t *armcpu) {
556
-//  if(armcpu->CPSR.bits.I) return false;
557
-//
558
-//  armcpu->waitIRQ = 0;
559
-//
560
-//#ifdef GDB_STUB
561
-//  armcpu->irq_flag = 1;
562
-//#endif
563
-//
564
-//  return true;
565
-//}
566
-
567
-uint32_t TRAPUNDEF(armcpu_t* cpu)
305
+uint32_t TRAPUNDEF(armcpu_t *cpu)
568 306
 {
569
-	//INFO("ARM%c: Undefined instruction: 0x%08X (%s) PC=0x%08X\n", cpu->proc_ID?'7':'9', cpu->instruction, decodeIntruction(false, cpu->instruction), cpu->instruct_adr);
570
-
571
-	if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
307
+	if (!!cpu->intVector ^ (cpu->proc_ID == ARMCPU_ARM9))
572 308
 	{
573
-		armcpu_exception(&NDS_ARM9,EXCEPTION_UNDEFINED_INSTRUCTION);
309
+		armcpu_exception(&NDS_ARM9, EXCEPTION_UNDEFINED_INSTRUCTION);
574 310
 		return 4;
575 311
 	}
576 312
 	else
577 313
 	{
578
-		//emu_halt();
579 314
 		execute = false;
580 315
 		return 4;
581 316
 	}
582 317
 }
583 318
 
584
-//bool
585
-//armcpu_flagIrq( armcpu_t *armcpu) {
586
-//  if(armcpu->CPSR.bits.I) return false;
587
-//
588
-//  armcpu->waitIRQ = 0;
589
-//
590
-//#ifdef GDB_STUB
591
-//  armcpu->irq_flag = 1;
592
-//#endif
593
-//
594
-//  return true;
595
-//}
596
-
597
-template<int PROCNUM>
598
-uint32_t armcpu_exec()
319
+template<int PROCNUM> uint32_t armcpu_exec()
599 320
 {
600 321
 	// Usually, fetching and executing are processed parallelly.
601 322
 	// So this function stores the cycles of each process to
... ...
@@ -603,100 +324,27 @@ uint32_t armcpu_exec()
603 324
 	uint32_t cFetch = 0;
604 325
 	uint32_t cExecute = 0;
605 326
 
606
-	//this assert is annoying. but sometimes it is handy.
327
+	// this assert is annoying. but sometimes it is handy.
607 328
 	//assert(ARMPROC.instruct_adr!=0x00000000);
608
-//#ifdef DEVELOPER
609
-#if 0
610
-	if ((((ARMPROC.instruct_adr & 0x0F000000) == 0x0F000000) && (PROCNUM == 0)) ||
611
-		(((ARMPROC.instruct_adr & 0x0F000000) == 0x00000000) && (PROCNUM == 1)))
612
-	{
613
-		switch (ARMPROC.instruct_adr & 0xFFFF)
614
-		{
615
-			case 0x00000000:
616
-				printf("BIOS%c: Reset!!!\n", PROCNUM?'7':'9');
617
-				emu_halt();
618
-				break;
619
-			case 0x00000004:
620
-				printf("BIOS%c: Undefined instruction\n", PROCNUM?'7':'9');
621
-				//emu_halt();
622
-				break;
623
-			case 0x00000008:
624
-				//printf("BIOS%c: SWI\n", PROCNUM?'7':'9');
625
-				break;
626
-			case 0x0000000C:
627
-				printf("BIOS%c: Prefetch Abort!!!\n", PROCNUM?'7':'9');
628
-				//emu_halt();
629
-				break;
630
-			case 0x00000010:
631
-				//printf("BIOS%c: Data Abort!!!\n", PROCNUM?'7':'9');
632
-				//emu_halt();
633
-				break;
634
-			case 0x00000014:
635
-				printf("BIOS%c: Reserved!!!\n", PROCNUM?'7':'9');
636
-				break;
637
-			case 0x00000018:
638
-				//printf("BIOS%c: IRQ\n", PROCNUM?'7':'9');
639
-				break;
640
-			case 0x0000001C:
641
-				printf("BIOS%c: Fast IRQ\n", PROCNUM?'7':'9');
642
-				break;
643
-		}
644
-	}
645
-#endif
646
-
647
-#if 0 //#ifdef GDB_STUB
648
-	if (ARMPROC.stalled) {
649
-		return STALLED_CYCLE_COUNT;
650
-	}
651
-
652
-	/* check for interrupts */
653
-	if (ARMPROC.irq_flag) {
654
-		armcpu_irqException(&ARMPROC);
655
-	}
656
-
657
-	cFetch = armcpu_prefetch(&ARMPROC);
658
-
659
-	if (ARMPROC.stalled) {
660
-		return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
661
-	}
662
-#endif
663 329
 
664 330
 	//cFetch = armcpu_prefetch(&ARMPROC);
665 331
 
666 332
 	//printf("%d: %08X\n",PROCNUM,ARMPROC.instruct_adr);
667 333
 
668
-	if(ARMPROC.CPSR.bits.T == 0)
334
+	if (!ARMPROC.CPSR.bits.T)
669 335
 	{
670
-		if(
671
-			CONDITION(ARMPROC.instruction) == 0x0E  //fast path for unconditional instructions
672
-			|| (TEST_COND(CONDITION(ARMPROC.instruction), CODE(ARMPROC.instruction), ARMPROC.CPSR)) //handles any condition
673
-			)
336
+		if (
337
+			CONDITION(ARMPROC.instruction) == 0x0E  // fast path for unconditional instructions
338
+			|| (TEST_COND(CONDITION(ARMPROC.instruction), CODE(ARMPROC.instruction), ARMPROC.CPSR)) // handles any condition
339
+		)
674 340
 		{
675 341
 #ifdef HAVE_LUA
676 342
 			CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 4, ARMPROC.instruction, LUAMEMHOOK_EXEC); // should report even if condition=false?
677 343
 #endif
678
-			if(PROCNUM==0) {
679
-				#ifdef DEVELOPER
680
-				DEBUG_statistics.instructionHits[0].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++;
681
-				#endif
682
-				cExecute = arm_instructions_set_0[INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction);
683
-			}
684
-			else {
685
-				#ifdef DEVELOPER
686
-				DEBUG_statistics.instructionHits[1].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++;
687
-				#endif
688
-				cExecute = arm_instructions_set_1[INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction);
689
-			}
344
+			cExecute = arm_instructions_set[PROCNUM][INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction);
690 345
 		}
691 346
 		else
692 347
 			cExecute = 1; // If condition=false: 1S cycle
693
-#ifdef GDB_STUB
694
-		if ( ARMPROC.post_ex_fn != NULL) {
695
-			/* call the external post execute function */
696
-			ARMPROC.post_ex_fn(ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 0);
697
-		}
698
-		ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction);
699
-#endif
700 348
 		cFetch = armcpu_prefetch<PROCNUM>();
701 349
 		return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
702 350
 	}
... ...
@@ -704,31 +352,38 @@ uint32_t armcpu_exec()
704 352
 #ifdef HAVE_LUA
705 353
 	CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 2, ARMPROC.instruction, LUAMEMHOOK_EXEC);
706 354
 #endif
707
-	if(PROCNUM==0)
708
-	{
709
-		#ifdef DEVELOPER
710
-		DEBUG_statistics.instructionHits[0].thumb[ARMPROC.instruction>>6]++;
711
-		#endif
712
-		cExecute = thumb_instructions_set_0[ARMPROC.instruction>>6](ARMPROC.instruction);
713
-	}
714
-	else {
715
-		#ifdef DEVELOPER
716
-		DEBUG_statistics.instructionHits[1].thumb[ARMPROC.instruction>>6]++;
717
-		#endif
718
-		cExecute = thumb_instructions_set_1[ARMPROC.instruction>>6](ARMPROC.instruction);
719
-	}
355
+	cExecute = thumb_instructions_set[PROCNUM][ARMPROC.instruction>>6](ARMPROC.instruction);
720 356
 
721
-#ifdef GDB_STUB
722
-	if ( ARMPROC.post_ex_fn != NULL) {
723
-		/* call the external post execute function */
724
-		ARMPROC.post_ex_fn( ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 1);
725
-	}
726
-	ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction);
727
-#endif
728 357
 	cFetch = armcpu_prefetch<PROCNUM>();
729 358
 	return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
730 359
 }
731 360
 
732
-//these templates needed to be instantiated manually
361
+// these templates needed to be instantiated manually
733 362
 template uint32_t armcpu_exec<0>();
734 363
 template uint32_t armcpu_exec<1>();
364
+
365
+#ifdef HAVE_JIT
366
+void arm_jit_sync()
367
+{
368
+	NDS_ARM7.next_instruction = NDS_ARM7.instruct_adr;
369
+	NDS_ARM9.next_instruction = NDS_ARM9.instruct_adr;
370
+	armcpu_prefetch<0>();
371
+	armcpu_prefetch<1>();
372
+}
373
+
374
+template<int PROCNUM, bool jit> uint32_t armcpu_exec()
375
+{
376
+	if (jit)
377
+	{
378
+		ArmOpCompiled f = reinterpret_cast<ArmOpCompiled>(JIT_COMPILED_FUNC(ARMPROC.instruct_adr, PROCNUM));
379
+		return f ? f() : arm_jit_compile<PROCNUM>();
380
+	}
381
+
382
+	return armcpu_exec<PROCNUM>();
383
+}
384
+
385
+template uint32_t armcpu_exec<0, false>();
386
+template uint32_t armcpu_exec<0, true>();
387
+template uint32_t armcpu_exec<1, false>();
388
+template uint32_t armcpu_exec<1, true>();
389
+#endif
Browse code

Import actual code.

Naram Qashat authored on 2013/03/26 02:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,734 @@
1
+/*
2
+	Copyright (C) 2006 yopyop
3
+	Copyright (C) 2009-2012 DeSmuME team
4
+
5
+	This file is free software: you can redistribute it and/or modify
6
+	it under the terms of the GNU General Public License as published by
7
+	the Free Software Foundation, either version 2 of the License, or
8
+	(at your option) any later version.
9
+
10
+	This file is distributed in the hope that it will be useful,
11
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+	GNU General Public License for more details.
14
+
15
+	You should have received a copy of the GNU General Public License
16
+	along with the this software.  If not, see <http://www.gnu.org/licenses/>.
17
+*/
18
+
19
+#include <cstdlib>
20
+#include <cstdio>
21
+#include <cassert>
22
+#include <algorithm>
23
+
24
+#include "types.h"
25
+#include "arm_instructions.h"
26
+#include "thumb_instructions.h"
27
+#include "cp15.h"
28
+#include "bios.h"
29
+//#include "debug.h"
30
+//#include "Disassembler.h"
31
+#include "NDSSystem.h"
32
+#include "MMU_timing.h"
33
+#ifdef HAVE_LUA
34
+#include "lua-engine.h"
35
+#endif
36
+
37
+template<uint32_t> static uint32_t armcpu_prefetch();
38
+
39
+inline uint32_t armcpu_prefetch(armcpu_t *armcpu) {
40
+	if(armcpu->proc_ID==0) return armcpu_prefetch<0>();
41
+	else return armcpu_prefetch<1>();
42
+}
43
+
44
+const unsigned char arm_cond_table[16*16] = {
45
+    /* N=0, Z=0, C=0, V=0 */
46
+    0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
47
+    0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
48
+    /* N=0, Z=0, C=0, V=1 */
49
+    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x00,
50
+    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
51
+    /* N=0, Z=0, C=1, V=0 */
52
+    0x00,0xFF,0xFF,0x00,0x00,0xFF,0x00,0xFF,
53
+    0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
54
+    /* N=0, Z=0, C=1, V=1 */
55
+    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,
56
+    0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
57
+    /* N=0, Z=1, C=0, V=0 */
58
+    0xFF,0x00,0x00,0xFF,0x00,0xFF,0x00,0xFF,
59
+    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
60
+    /* N=0, Z=1, C=0, V=1 */
61
+    0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x00,
62
+    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
63
+    /* N=0, Z=1, C=1, V=0 */
64
+    0xFF,0x00,0xFF,0x00,0x00,0xFF,0x00,0xFF,
65
+    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
66
+    /* N=0, Z=1, C=1, V=1 */
67
+    0xFF,0x00,0xFF,0x00,0x00,0xFF,0xFF,0x00,
68
+    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
69
+    /* N=1, Z=0, C=0, V=0 */
70
+    0x00,0xFF,0x00,0xFF,0xFF,0x00,0x00,0xFF,
71
+    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
72
+    /* N=1, Z=0, C=0, V=1 */
73
+    0x00,0xFF,0x00,0xFF,0xFF,0x00,0xFF,0x00,
74
+    0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x20,
75
+    /* N=1, Z=0, C=1, V=0 */
76
+    0x00,0xFF,0xFF,0x00,0xFF,0x00,0x00,0xFF,
77
+    0xFF,0x00,0x00,0xFF,0x00,0xFF,0xFF,0x20,
78
+    /* N=1, Z=0, C=1, V=1 */
79
+    0x00,0xFF,0xFF,0x00,0xFF,0x00,0xFF,0x00,
80
+    0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x20,
81
+    /* N=1, Z=1, C=0, V=0 */
82
+    0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,
83
+    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
84
+    /* N=1, Z=1, C=0, V=1 */
85
+    0xFF,0x00,0x00,0xFF,0xFF,0x00,0xFF,0x00,
86
+    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
87
+    /* N=1, Z=1, C=1, V=0 */
88
+    0xFF,0x00,0xFF,0x00,0xFF,0x00,0x00,0xFF,
89
+    0x00,0xFF,0x00,0xFF,0x00,0xFF,0xFF,0x20,
90
+    /* N=1, Z=1, C=1, V=1 */
91
+    0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
92
+    0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x20,
93
+};
94
+
95
+armcpu_t NDS_ARM7;
96
+armcpu_t NDS_ARM9;
97
+
98
+/*#define SWAP(a, b, c) do      \
99
+	              {       \
100
+                         c=a; \
101
+                         a=b; \
102
+                         b=c; \
103
+		      }       \
104
+                      while(0)*/
105
+template<typename T> static inline void SWAP(T &a, T &b)
106
+{
107
+	T c = a;
108
+	a = b;
109
+	b = c;
110
+}
111
+
112
+#ifdef GDB_STUB
113
+
114
+#define STALLED_CYCLE_COUNT 10
115
+
116
+static void
117
+stall_cpu( void *instance) {
118
+  armcpu_t *armcpu = (armcpu_t *)instance;
119
+  printf("UNSTALL\n");
120
+  armcpu->stalled = 1;
121
+}
122
+
123
+static void
124
+unstall_cpu( void *instance) {
125
+  armcpu_t *armcpu = (armcpu_t *)instance;
126
+  printf("UNSTALL\n");
127
+  armcpu->stalled = 0;
128
+}
129
+
130
+static void
131
+install_post_exec_fn( void *instance,
132
+                      void (*ex_fn)( void *, uint32_t adr, int thumb),
133
+                      void *fn_data) {
134
+  armcpu_t *armcpu = (armcpu_t *)instance;
135
+
136
+
137
+  armcpu->post_ex_fn = ex_fn;
138
+  armcpu->post_ex_fn_data = fn_data;
139
+}
140
+
141
+static void
142
+remove_post_exec_fn( void *instance) {
143
+  armcpu_t *armcpu = (armcpu_t *)instance;
144
+
145
+  armcpu->post_ex_fn = NULL;
146
+}
147
+#endif
148
+
149
+#ifdef GDB_STUB
150
+static uint32_t read_cpu_reg( void *instance, uint32_t reg_num)
151
+{
152
+	armcpu_t *armcpu = (armcpu_t *)instance;
153
+
154
+	if ( reg_num <= 14) {
155
+	  return armcpu->R[reg_num];
156
+	}
157
+	else if ( reg_num == 15) {
158
+	  return armcpu->instruct_adr;
159
+	}
160
+	else if ( reg_num == 16) {
161
+	  //CPSR
162
+	  return armcpu->CPSR.val;
163
+	}
164
+}
165
+
166
+static void
167
+set_cpu_reg( void *instance, uint32_t reg_num, uint32_t value) {
168
+  armcpu_t *armcpu = (armcpu_t *)instance;
169
+
170
+  if ( reg_num <= 14) {
171
+    armcpu->R[reg_num] = value;
172
+  }
173
+  else if ( reg_num == 15) {
174
+    armcpu->next_instruction = value;
175
+  }
176
+  else if ( reg_num == 16) {
177
+    /* FIXME: setting the CPSR */
178
+  }
179
+}
180
+#endif
181
+
182
+#ifdef GDB_STUB
183
+int armcpu_new( armcpu_t *armcpu, uint32_t id,
184
+                struct armcpu_memory_iface *mem_if,
185
+                struct armcpu_ctrl_iface **ctrl_iface_ret)
186
+#else
187
+int armcpu_new( armcpu_t *armcpu, uint32_t id)
188
+#endif
189
+{
190
+	armcpu->proc_ID = id;
191
+
192
+#ifdef GDB_STUB
193
+	armcpu->mem_if = mem_if;
194
+
195
+	/* populate the control interface */
196
+	armcpu->ctrl_iface.stall = stall_cpu;
197
+	armcpu->ctrl_iface.unstall = unstall_cpu;
198
+	armcpu->ctrl_iface.read_reg = read_cpu_reg;
199
+	armcpu->ctrl_iface.set_reg = set_cpu_reg;
200
+	armcpu->ctrl_iface.install_post_ex_fn = install_post_exec_fn;
201
+	armcpu->ctrl_iface.remove_post_ex_fn = remove_post_exec_fn;
202
+	armcpu->ctrl_iface.data = armcpu;
203
+
204
+	*ctrl_iface_ret = &armcpu->ctrl_iface;
205
+
206
+	armcpu->post_ex_fn = NULL;
207
+#endif
208
+
209
+	armcpu->stalled = 0;
210
+
211
+	armcpu_init(armcpu, 0);
212
+
213
+	return 0;
214
+}
215
+
216
+//call this whenever CPSR is changed (other than CNVZQ or T flags); interrupts may need to be unleashed
217
+void armcpu_t::changeCPSR()
218
+{
219
+	//but all it does is give them a chance to unleash by forcing an immediate reschedule
220
+	//TODO - we could actually set CPSR through here and look for a change in the I bit
221
+	//that would be a little optimization as well as a safety measure if we prevented setting CPSR directly
222
+	NDS_Reschedule();
223
+}
224
+
225
+void armcpu_init(armcpu_t *armcpu, uint32_t adr)
226
+{
227
+	armcpu->LDTBit = (armcpu->proc_ID==0); //Si ARM9 utiliser le syte v5 pour le load
228
+	armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0);
229
+	armcpu->waitIRQ = false;
230
+	armcpu->halt_IE_and_IF = false;
231
+	armcpu->intrWaitARM_state = 0;
232
+
233
+//#ifdef GDB_STUB
234
+//    armcpu->irq_flag = 0;
235
+//#endif
236
+
237
+	for(int i = 0; i < 16; ++i)
238
+	{
239
+		armcpu->R[i] = 0;
240
+		if(armcpu->coproc[i]) free(armcpu->coproc[i]);
241
+		armcpu->coproc[i] = NULL;
242
+	}
243
+
244
+	armcpu->CPSR.val = armcpu->SPSR.val = SYS;
245
+
246
+	armcpu->R13_usr = armcpu->R14_usr = 0;
247
+	armcpu->R13_svc = armcpu->R14_svc = 0;
248
+	armcpu->R13_abt = armcpu->R14_abt = 0;
249
+	armcpu->R13_und = armcpu->R14_und = 0;
250
+	armcpu->R13_irq = armcpu->R14_irq = 0;
251
+	armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0;
252
+
253
+	armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0;
254
+
255
+//#ifdef GDB_STUB
256
+//    armcpu->instruct_adr = adr;
257
+//	armcpu->R[15] = adr + 8;
258
+//#else
259
+	//armcpu->R[15] = adr;
260
+//#endif
261
+
262
+	armcpu->next_instruction = adr;
263
+
264
+	// only ARM9 have co-processor
265
+	if (armcpu->proc_ID==0)
266
+		armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu);
267
+
268
+//#ifndef GDB_STUB
269
+	armcpu_prefetch(armcpu);
270
+//#endif
271
+}
272
+
273
+uint32_t armcpu_switchMode(armcpu_t *armcpu, uint8_t mode)
274
+{
275
+	uint32_t oldmode = armcpu->CPSR.bits.mode;
276
+
277
+	switch(oldmode)
278
+	{
279
+		case USR :
280
+		case SYS :
281
+			armcpu->R13_usr = armcpu->R[13];
282
+			armcpu->R14_usr = armcpu->R[14];
283
+			break;
284
+
285
+		case FIQ :
286
+			{
287
+                                //uint32_t tmp;
288
+				SWAP(armcpu->R[8], armcpu->R8_fiq/*, tmp*/);
289
+				SWAP(armcpu->R[9], armcpu->R9_fiq/*, tmp*/);
290
+				SWAP(armcpu->R[10], armcpu->R10_fiq/*, tmp*/);
291
+				SWAP(armcpu->R[11], armcpu->R11_fiq/*, tmp*/);
292
+				SWAP(armcpu->R[12], armcpu->R12_fiq/*, tmp*/);
293
+				armcpu->R13_fiq = armcpu->R[13];
294
+				armcpu->R14_fiq = armcpu->R[14];
295
+				armcpu->SPSR_fiq = armcpu->SPSR;
296
+				break;
297
+			}
298
+		case IRQ :
299
+			armcpu->R13_irq = armcpu->R[13];
300
+			armcpu->R14_irq = armcpu->R[14];
301
+			armcpu->SPSR_irq = armcpu->SPSR;
302
+			break;
303
+
304
+		case SVC :
305
+			armcpu->R13_svc = armcpu->R[13];
306
+			armcpu->R14_svc = armcpu->R[14];
307
+			armcpu->SPSR_svc = armcpu->SPSR;
308
+			break;
309
+
310
+		case ABT :
311
+			armcpu->R13_abt = armcpu->R[13];
312
+			armcpu->R14_abt = armcpu->R[14];
313
+			armcpu->SPSR_abt = armcpu->SPSR;
314
+			break;
315
+
316
+		case UND :
317
+			armcpu->R13_und = armcpu->R[13];
318
+			armcpu->R14_und = armcpu->R[14];
319
+			armcpu->SPSR_und = armcpu->SPSR;
320
+			break;
321
+		default :
322
+			break;
323
+		}
324
+
325
+		switch(mode)
326
+		{
327
+			case USR :
328
+			case SYS :
329
+				armcpu->R[13] = armcpu->R13_usr;
330
+				armcpu->R[14] = armcpu->R14_usr;
331
+				//SPSR = CPSR;
332
+				break;
333
+
334
+			case FIQ :
335
+				{
336
+					//uint32_t tmp;
337
+					SWAP(armcpu->R[8], armcpu->R8_fiq/*, tmp*/);
338
+					SWAP(armcpu->R[9], armcpu->R9_fiq/*, tmp*/);
339
+					SWAP(armcpu->R[10], armcpu->R10_fiq/*, tmp*/);
340
+					SWAP(armcpu->R[11], armcpu->R11_fiq/*, tmp*/);
341
+					SWAP(armcpu->R[12], armcpu->R12_fiq/*, tmp*/);
342
+					armcpu->R[13] = armcpu->R13_fiq;
343
+					armcpu->R[14] = armcpu->R14_fiq;
344
+					armcpu->SPSR = armcpu->SPSR_fiq;
345
+					break;
346
+				}
347
+
348
+			case IRQ :
349
+				armcpu->R[13] = armcpu->R13_irq;
350
+				armcpu->R[14] = armcpu->R14_irq;
351
+				armcpu->SPSR = armcpu->SPSR_irq;
352
+				break;
353
+
354
+			case SVC :
355
+				armcpu->R[13] = armcpu->R13_svc;
356
+				armcpu->R[14] = armcpu->R14_svc;
357
+				armcpu->SPSR = armcpu->SPSR_svc;
358
+				break;
359
+
360
+			case ABT :
361
+				armcpu->R[13] = armcpu->R13_abt;
362
+				armcpu->R[14] = armcpu->R14_abt;
363
+				armcpu->SPSR = armcpu->SPSR_abt;
364
+				break;
365
+
366
+          case UND :
367
+				armcpu->R[13] = armcpu->R13_und;
368
+				armcpu->R[14] = armcpu->R14_und;
369
+				armcpu->SPSR = armcpu->SPSR_und;
370
+				break;
371
+
372
+				default :
373
+					break;
374
+	}
375
+
376
+	armcpu->CPSR.bits.mode = mode & 0x1F;
377
+	armcpu->changeCPSR();
378
+	return oldmode;
379
+}
380
+
381
+uint32_t armcpu_Wait4IRQ(armcpu_t *cpu)
382
+{
383
+	cpu->waitIRQ = true;
384
+	cpu->halt_IE_and_IF = true;
385
+	return 1;
386
+}
387
+
388
+template<uint32_t PROCNUM>
389
+inline static uint32_t armcpu_prefetch()
390
+{
391
+	armcpu_t* const armcpu = &ARMPROC;
392
+//#ifdef GDB_STUB
393
+//	uint32_t temp_instruction;
394
+//#endif
395
+	uint32_t curInstruction = armcpu->next_instruction;
396
+
397
+	if(armcpu->CPSR.bits.T == 0)
398
+	{
399
+//#ifdef GDB_STUB
400
+//		temp_instruction =
401
+//			armcpu->mem_if->prefetch32( armcpu->mem_if->data,
402
+//			armcpu->next_instruction);
403
+//
404
+//		if ( !armcpu->stalled) {
405
+//			armcpu->instruction = temp_instruction;
406
+//			armcpu->instruct_adr = armcpu->next_instruction;
407
+//			armcpu->next_instruction += 4;
408
+//			armcpu->R[15] = armcpu->next_instruction + 4;
409
+//		}
410
+//#else
411
+		curInstruction &= 0xFFFFFFFC; //please don't change this to 0x0FFFFFFC -- the NDS will happily run on 0xF******* addresses all day long
412
+		//please note that we must setup R[15] before reading the instruction since there is a protection
413
+		//which prevents PC > 0x3FFF from reading the bios region
414
+		armcpu->instruct_adr = curInstruction;
415
+		armcpu->next_instruction = curInstruction + 4;
416
+		armcpu->R[15] = curInstruction + 8;
417
+		armcpu->instruction = _MMU_read32<PROCNUM, MMU_AT_CODE>(curInstruction);
418
+//#endif
419
+
420
+		return MMU_codeFetchCycles<PROCNUM,32>(curInstruction);
421
+	}
422
+
423
+//#ifdef GDB_STUB
424
+//	temp_instruction =
425
+//		armcpu->mem_if->prefetch16( armcpu->mem_if->data,
426
+//		armcpu->next_instruction);
427
+//
428
+//	if ( !armcpu->stalled) {
429
+//		armcpu->instruction = temp_instruction;
430
+//		armcpu->instruct_adr = armcpu->next_instruction;
431
+//		armcpu->next_instruction = armcpu->next_instruction + 2;
432
+//		armcpu->R[15] = armcpu->next_instruction + 2;
433
+//	}
434
+//#else
435
+	curInstruction &= 0xFFFFFFFE; //please don't change this to 0x0FFFFFFE -- the NDS will happily run on 0xF******* addresses all day long
436
+	//please note that we must setup R[15] before reading the instruction since there is a protection
437
+	//which prevents PC > 0x3FFF from reading the bios region
438
+	armcpu->instruct_adr = curInstruction;
439
+	armcpu->next_instruction = curInstruction + 2;
440
+	armcpu->R[15] = curInstruction + 4;
441
+	armcpu->instruction = _MMU_read16<PROCNUM, MMU_AT_CODE>(curInstruction);
442
+//#endif
443
+
444
+	if(PROCNUM==0)
445
+	{
446
+		// arm9 fetches 2 instructions at a time in thumb mode
447
+		if(!(curInstruction == armcpu->instruct_adr + 2 && (curInstruction & 2)))
448
+			return MMU_codeFetchCycles<PROCNUM,32>(curInstruction);
449
+		else
450
+			return 0;
451
+	}
452
+
453
+	return MMU_codeFetchCycles<PROCNUM,16>(curInstruction);
454
+}
455
+
456
+#if 0 /* not used */
457
+static bool FASTCALL test_EQ(Status_Reg CPSR) { return CPSR.bits.Z; }
458
+static bool FASTCALL test_NE(Status_Reg CPSR) { return !CPSR.bits.Z; }
459
+static bool FASTCALL test_CS(Status_Reg CPSR) { return CPSR.bits.C; }
460
+static bool FASTCALL test_CC(Status_Reg CPSR) { return !CPSR.bits.C; }
461
+static bool FASTCALL test_MI(Status_Reg CPSR) { return CPSR.bits.N; }
462
+static bool FASTCALL test_PL(Status_Reg CPSR) { return !CPSR.bits.N; }
463
+static bool FASTCALL test_VS(Status_Reg CPSR) { return CPSR.bits.V; }
464
+static bool FASTCALL test_VC(Status_Reg CPSR) { return !CPSR.bits.V; }
465
+static bool FASTCALL test_HI(Status_Reg CPSR) { return CPSR.bits.C && !CPSR.bits.Z; }
466
+static bool FASTCALL test_LS(Status_Reg CPSR) { return CPSR.bits.Z || !CPSR.bits.C; }
467
+static bool FASTCALL test_GE(Status_Reg CPSR) { return CPSR.bits.N==CPSR.bits.V; }
468
+static bool FASTCALL test_LT(Status_Reg CPSR) { return CPSR.bits.N!=CPSR.bits.V; }
469
+static bool FASTCALL test_GT(Status_Reg CPSR) { return !CPSR.bits.Z && CPSR.bits.N==CPSR.bits.V; }
470
+static bool FASTCALL test_LE(Status_Reg CPSR) { return CPSR.bits.Z || CPSR.bits.N!=CPSR.bits.V; }
471
+static bool FASTCALL test_AL(Status_Reg CPSR) { return 1; }
472
+
473
+static bool (FASTCALL* test_conditions[])(Status_Reg CPSR)= {
474
+	test_EQ , test_NE ,
475
+	test_CS , test_CC ,
476
+	test_MI , test_PL ,
477
+	test_VS , test_VC ,
478
+	test_HI , test_LS ,
479
+	test_GE , test_LT ,
480
+	test_GT , test_LE ,
481
+	test_AL
482
+};
483
+#define TEST_COND2(cond, CPSR) \
484
+	(cond<15&&test_conditions[cond](CPSR))
485
+#endif
486
+
487
+//TODO - merge with armcpu_irqException?
488
+//http://www.ethernut.de/en/documents/arm-exceptions.html
489
+//http://docs.google.com/viewer?a=v&q=cache:V4ht1YkxprMJ:www.cs.nctu.edu.tw/~wjtsai/EmbeddedSystemDesign/Ch3-1.pdf+arm+exception+handling&hl=en&gl=us&pid=bl&srcid=ADGEEShx9VTHbUhWdDOrTVRzLkcCsVfJiijncNDkkgkrlJkLa7D0LCpO8fQ_hhU3DTcgZh9rcZWWQq4TYhhCovJ625h41M0ZUX3WGasyzWQFxYzDCB-VS6bsUmpoJnRxAc-bdkD0qmsu&sig=AHIEtbR9VHvDOCRmZFQDUVwy53iJDjoSPQ
490
+void armcpu_exception(armcpu_t *cpu, uint32_t number)
491
+{
492
+	Mode cpumode = USR;
493
+	switch(number)
494
+	{
495
+	case EXCEPTION_RESET: cpumode = SVC; break;
496
+	case EXCEPTION_UNDEFINED_INSTRUCTION: cpumode = UND; break;
497
+	case EXCEPTION_SWI: cpumode = SVC; break;
498
+	case EXCEPTION_PREFETCH_ABORT: cpumode = ABT; break;
499
+	case EXCEPTION_DATA_ABORT: cpumode = ABT; break;
500
+	case EXCEPTION_RESERVED_0x14: execute = false;/*emu_halt();*/ break;
501
+	case EXCEPTION_IRQ: cpumode = IRQ; break;
502
+	case EXCEPTION_FAST_IRQ: cpumode = FIQ; break;
503
+	}
504
+
505
+	Status_Reg tmp = cpu->CPSR;
506
+	armcpu_switchMode(cpu, cpumode);				//enter new mode
507
+	cpu->R[14] = cpu->next_instruction;
508
+	cpu->SPSR = tmp;							//save old CPSR as new SPSR
509
+	cpu->CPSR.bits.T = 0;						//handle as ARM32 code
510
+	cpu->CPSR.bits.I = 1;
511
+	cpu->changeCPSR();
512
+	cpu->R[15] = cpu->intVector + number;
513
+	cpu->next_instruction = cpu->R[15];
514
+	printf("armcpu_exception!\n");
515
+	//extern bool dolog;
516
+	//dolog=true;
517
+
518
+	//HOW DOES THIS WORTK WITHOUT A PREFETCH, LIKE IRQ BELOW?
519
+	//I REALLY WISH WE DIDNT PREFETCH BEFORE EXECUTING
520
+}
521
+
522
+bool armcpu_irqException(armcpu_t *armcpu)
523
+{
524
+    Status_Reg tmp;
525
+
526
+	//TODO - remove GDB specific code
527
+//#ifdef GDB_STUB
528
+//	armcpu->irq_flag = 0;
529
+//#endif
530
+
531
+	tmp = armcpu->CPSR;
532
+	armcpu_switchMode(armcpu, IRQ);
533
+
534
+	//TODO - remove GDB specific code
535
+//#ifdef GDB_STUB
536
+//	armcpu->R[14] = armcpu->next_instruction + 4;
537
+//#else
538
+	armcpu->R[14] = armcpu->instruct_adr + 4;
539
+//#endif
540
+	armcpu->SPSR = tmp;
541
+	armcpu->CPSR.bits.T = 0;
542
+	armcpu->CPSR.bits.I = 1;
543
+	armcpu->next_instruction = armcpu->intVector + 0x18;
544
+	armcpu->waitIRQ = 0;
545
+
546
+	//must retain invariant of having next instruction to be executed prefetched
547
+	//(yucky)
548
+	armcpu_prefetch(armcpu);
549
+
550
+	return true;
551
+}
552
+
553
+//TODO - remove GDB specific code
554
+//bool
555
+//armcpu_flagIrq( armcpu_t *armcpu) {
556
+//  if(armcpu->CPSR.bits.I) return false;
557
+//
558
+//  armcpu->waitIRQ = 0;
559
+//
560
+//#ifdef GDB_STUB
561
+//  armcpu->irq_flag = 1;
562
+//#endif
563
+//
564
+//  return true;
565
+//}
566
+
567
+uint32_t TRAPUNDEF(armcpu_t* cpu)
568
+{
569
+	//INFO("ARM%c: Undefined instruction: 0x%08X (%s) PC=0x%08X\n", cpu->proc_ID?'7':'9', cpu->instruction, decodeIntruction(false, cpu->instruction), cpu->instruct_adr);
570
+
571
+	if (((cpu->intVector != 0) ^ (cpu->proc_ID == ARMCPU_ARM9)))
572
+	{
573
+		armcpu_exception(&NDS_ARM9,EXCEPTION_UNDEFINED_INSTRUCTION);
574
+		return 4;
575
+	}
576
+	else
577
+	{
578
+		//emu_halt();
579
+		execute = false;
580
+		return 4;
581
+	}
582
+}
583
+
584
+//bool
585
+//armcpu_flagIrq( armcpu_t *armcpu) {
586
+//  if(armcpu->CPSR.bits.I) return false;
587
+//
588
+//  armcpu->waitIRQ = 0;
589
+//
590
+//#ifdef GDB_STUB
591
+//  armcpu->irq_flag = 1;
592
+//#endif
593
+//
594
+//  return true;
595
+//}
596
+
597
+template<int PROCNUM>
598
+uint32_t armcpu_exec()
599
+{
600
+	// Usually, fetching and executing are processed parallelly.
601
+	// So this function stores the cycles of each process to
602
+	// the variables below, and returns appropriate cycle count.
603
+	uint32_t cFetch = 0;
604
+	uint32_t cExecute = 0;
605
+
606
+	//this assert is annoying. but sometimes it is handy.
607
+	//assert(ARMPROC.instruct_adr!=0x00000000);
608
+//#ifdef DEVELOPER
609
+#if 0
610
+	if ((((ARMPROC.instruct_adr & 0x0F000000) == 0x0F000000) && (PROCNUM == 0)) ||
611
+		(((ARMPROC.instruct_adr & 0x0F000000) == 0x00000000) && (PROCNUM == 1)))
612
+	{
613
+		switch (ARMPROC.instruct_adr & 0xFFFF)
614
+		{
615
+			case 0x00000000:
616
+				printf("BIOS%c: Reset!!!\n", PROCNUM?'7':'9');
617
+				emu_halt();
618
+				break;
619
+			case 0x00000004:
620
+				printf("BIOS%c: Undefined instruction\n", PROCNUM?'7':'9');
621
+				//emu_halt();
622
+				break;
623
+			case 0x00000008:
624
+				//printf("BIOS%c: SWI\n", PROCNUM?'7':'9');
625
+				break;
626
+			case 0x0000000C:
627
+				printf("BIOS%c: Prefetch Abort!!!\n", PROCNUM?'7':'9');
628
+				//emu_halt();
629
+				break;
630
+			case 0x00000010:
631
+				//printf("BIOS%c: Data Abort!!!\n", PROCNUM?'7':'9');
632
+				//emu_halt();
633
+				break;
634
+			case 0x00000014:
635
+				printf("BIOS%c: Reserved!!!\n", PROCNUM?'7':'9');
636
+				break;
637
+			case 0x00000018:
638
+				//printf("BIOS%c: IRQ\n", PROCNUM?'7':'9');
639
+				break;
640
+			case 0x0000001C:
641
+				printf("BIOS%c: Fast IRQ\n", PROCNUM?'7':'9');
642
+				break;
643
+		}
644
+	}
645
+#endif
646
+
647
+#if 0 //#ifdef GDB_STUB
648
+	if (ARMPROC.stalled) {
649
+		return STALLED_CYCLE_COUNT;
650
+	}
651
+
652
+	/* check for interrupts */
653
+	if (ARMPROC.irq_flag) {
654
+		armcpu_irqException(&ARMPROC);
655
+	}
656
+
657
+	cFetch = armcpu_prefetch(&ARMPROC);
658
+
659
+	if (ARMPROC.stalled) {
660
+		return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
661
+	}
662
+#endif
663
+
664
+	//cFetch = armcpu_prefetch(&ARMPROC);
665
+
666
+	//printf("%d: %08X\n",PROCNUM,ARMPROC.instruct_adr);
667
+
668
+	if(ARMPROC.CPSR.bits.T == 0)
669
+	{
670
+		if(
671
+			CONDITION(ARMPROC.instruction) == 0x0E  //fast path for unconditional instructions
672
+			|| (TEST_COND(CONDITION(ARMPROC.instruction), CODE(ARMPROC.instruction), ARMPROC.CPSR)) //handles any condition
673
+			)
674
+		{
675
+#ifdef HAVE_LUA
676
+			CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 4, ARMPROC.instruction, LUAMEMHOOK_EXEC); // should report even if condition=false?
677
+#endif
678
+			if(PROCNUM==0) {
679
+				#ifdef DEVELOPER
680
+				DEBUG_statistics.instructionHits[0].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++;
681
+				#endif
682
+				cExecute = arm_instructions_set_0[INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction);
683
+			}
684
+			else {
685
+				#ifdef DEVELOPER
686
+				DEBUG_statistics.instructionHits[1].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++;
687
+				#endif
688
+				cExecute = arm_instructions_set_1[INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction);
689
+			}
690
+		}
691
+		else
692
+			cExecute = 1; // If condition=false: 1S cycle
693
+#ifdef GDB_STUB
694
+		if ( ARMPROC.post_ex_fn != NULL) {
695
+			/* call the external post execute function */
696
+			ARMPROC.post_ex_fn(ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 0);
697
+		}
698
+		ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction);
699
+#endif
700
+		cFetch = armcpu_prefetch<PROCNUM>();
701
+		return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
702
+	}
703
+
704
+#ifdef HAVE_LUA
705
+	CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 2, ARMPROC.instruction, LUAMEMHOOK_EXEC);
706
+#endif
707
+	if(PROCNUM==0)
708
+	{
709
+		#ifdef DEVELOPER
710
+		DEBUG_statistics.instructionHits[0].thumb[ARMPROC.instruction>>6]++;
711
+		#endif
712
+		cExecute = thumb_instructions_set_0[ARMPROC.instruction>>6](ARMPROC.instruction);
713
+	}
714
+	else {
715
+		#ifdef DEVELOPER
716
+		DEBUG_statistics.instructionHits[1].thumb[ARMPROC.instruction>>6]++;
717
+		#endif
718
+		cExecute = thumb_instructions_set_1[ARMPROC.instruction>>6](ARMPROC.instruction);
719
+	}
720
+
721
+#ifdef GDB_STUB
722
+	if ( ARMPROC.post_ex_fn != NULL) {
723
+		/* call the external post execute function */
724
+		ARMPROC.post_ex_fn( ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 1);
725
+	}
726
+	ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction);
727
+#endif
728
+	cFetch = armcpu_prefetch<PROCNUM>();
729
+	return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch);
730
+}
731
+
732
+//these templates needed to be instantiated manually
733
+template uint32_t armcpu_exec<0>();
734
+template uint32_t armcpu_exec<1>();