1 // -*- C++ -*-
2 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
3 // Copyright (C) 1999-2003 Forgotten
4 // Copyright (C) 2005 Forgotten and the VBA development team
5
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or(at your option)
9 // any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 #define INCED_FROM_ARM_CPP
21
22 #include "GBA.h"
23 #include "GBAinline.h"
24 #include "Globals.h"
25
26 namespace MDFN_IEN_GBA
27 {
28
RunARM(void)29 unsigned int RunARM(void)
30 {
31 unsigned int clockTicks;
32
33 #define OP_AND \
34 reg[dest].I = reg[(opcode>>16)&15].I & value;
35
36 #define OP_ANDS \
37 reg[dest].I = reg[(opcode>>16)&15].I & value;\
38 \
39 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
40 Z_FLAG = (reg[dest].I) ? false : true;\
41 C_FLAG = C_OUT;
42
43 #define OP_EOR \
44 reg[dest].I = reg[(opcode>>16)&15].I ^ value;
45
46 #define OP_EORS \
47 reg[dest].I = reg[(opcode>>16)&15].I ^ value;\
48 \
49 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
50 Z_FLAG = (reg[dest].I) ? false : true;\
51 C_FLAG = C_OUT;
52
53 #define NEG(i) ((i) >> 31)
54 #define POS(i) ((~(i)) >> 31)
55 #define ADDCARRY(a, b, c) \
56 C_FLAG = ((NEG(a) & NEG(b)) |\
57 (NEG(a) & POS(c)) |\
58 (NEG(b) & POS(c))) ? true : false;
59 #define ADDOVERFLOW(a, b, c) \
60 V_FLAG = ((NEG(a) & NEG(b) & POS(c)) |\
61 (POS(a) & POS(b) & NEG(c))) ? true : false;
62 #define SUBCARRY(a, b, c) \
63 C_FLAG = ((NEG(a) & POS(b)) |\
64 (NEG(a) & POS(c)) |\
65 (POS(b) & POS(c))) ? true : false;
66 #define SUBOVERFLOW(a, b, c)\
67 V_FLAG = ((NEG(a) & POS(b) & POS(c)) |\
68 (POS(a) & NEG(b) & NEG(c))) ? true : false;
69 #define OP_SUB \
70 {\
71 reg[dest].I = reg[base].I - value;\
72 }
73 #define OP_SUBS \
74 {\
75 uint32 lhs = reg[base].I;\
76 uint32 rhs = value;\
77 uint32 res = lhs - rhs;\
78 reg[dest].I = res;\
79 Z_FLAG = (res == 0) ? true : false;\
80 N_FLAG = NEG(res) ? true : false;\
81 SUBCARRY(lhs, rhs, res);\
82 SUBOVERFLOW(lhs, rhs, res);\
83 }
84 #define OP_RSB \
85 {\
86 reg[dest].I = value - reg[base].I;\
87 }
88 #define OP_RSBS \
89 {\
90 uint32 lhs = reg[base].I;\
91 uint32 rhs = value;\
92 uint32 res = rhs - lhs;\
93 reg[dest].I = res;\
94 Z_FLAG = (res == 0) ? true : false;\
95 N_FLAG = NEG(res) ? true : false;\
96 SUBCARRY(rhs, lhs, res);\
97 SUBOVERFLOW(rhs, lhs, res);\
98 }
99 #define OP_ADD \
100 {\
101 reg[dest].I = reg[base].I + value;\
102 }
103 #define OP_ADDS \
104 {\
105 uint32 lhs = reg[base].I;\
106 uint32 rhs = value;\
107 uint32 res = lhs + rhs;\
108 reg[dest].I = res;\
109 Z_FLAG = (res == 0) ? true : false;\
110 N_FLAG = NEG(res) ? true : false;\
111 ADDCARRY(lhs, rhs, res);\
112 ADDOVERFLOW(lhs, rhs, res);\
113 }
114 #define OP_ADC \
115 {\
116 reg[dest].I = reg[base].I + value + (uint32)C_FLAG;\
117 }
118 #define OP_ADCS \
119 {\
120 uint32 lhs = reg[base].I;\
121 uint32 rhs = value;\
122 uint32 res = lhs + rhs + (uint32)C_FLAG;\
123 reg[dest].I = res;\
124 Z_FLAG = (res == 0) ? true : false;\
125 N_FLAG = NEG(res) ? true : false;\
126 ADDCARRY(lhs, rhs, res);\
127 ADDOVERFLOW(lhs, rhs, res);\
128 }
129 #define OP_SBC \
130 {\
131 reg[dest].I = reg[base].I - value - !((uint32)C_FLAG);\
132 }
133 #define OP_SBCS \
134 {\
135 uint32 lhs = reg[base].I;\
136 uint32 rhs = value;\
137 uint32 res = lhs - rhs - !((uint32)C_FLAG);\
138 reg[dest].I = res;\
139 Z_FLAG = (res == 0) ? true : false;\
140 N_FLAG = NEG(res) ? true : false;\
141 SUBCARRY(lhs, rhs, res);\
142 SUBOVERFLOW(lhs, rhs, res);\
143 }
144 #define OP_RSC \
145 {\
146 reg[dest].I = value - reg[base].I - !((uint32)C_FLAG);\
147 }
148 #define OP_RSCS \
149 {\
150 uint32 lhs = reg[base].I;\
151 uint32 rhs = value;\
152 uint32 res = rhs - lhs - !((uint32)C_FLAG);\
153 reg[dest].I = res;\
154 Z_FLAG = (res == 0) ? true : false;\
155 N_FLAG = NEG(res) ? true : false;\
156 SUBCARRY(rhs, lhs, res);\
157 SUBOVERFLOW(rhs, lhs, res);\
158 }
159 #define OP_CMP \
160 {\
161 uint32 lhs = reg[base].I;\
162 uint32 rhs = value;\
163 uint32 res = lhs - rhs;\
164 Z_FLAG = (res == 0) ? true : false;\
165 N_FLAG = NEG(res) ? true : false;\
166 SUBCARRY(lhs, rhs, res);\
167 SUBOVERFLOW(lhs, rhs, res);\
168 }
169 #define OP_CMN \
170 {\
171 uint32 lhs = reg[base].I;\
172 uint32 rhs = value;\
173 uint32 res = lhs + rhs;\
174 Z_FLAG = (res == 0) ? true : false;\
175 N_FLAG = NEG(res) ? true : false;\
176 ADDCARRY(lhs, rhs, res);\
177 ADDOVERFLOW(lhs, rhs, res);\
178 }
179
180 #define LOGICAL_LSL_REG \
181 {\
182 uint32 v = reg[opcode & 0x0f].I;\
183 C_OUT = (v >> (32 - shift)) & 1 ? true : false;\
184 value = v << shift;\
185 }
186 #define LOGICAL_LSR_REG \
187 {\
188 uint32 v = reg[opcode & 0x0f].I;\
189 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
190 value = v >> shift;\
191 }
192 #define LOGICAL_ASR_REG \
193 {\
194 uint32 v = reg[opcode & 0x0f].I;\
195 C_OUT = ((int32)v >> (int)(shift - 1)) & 1 ? true : false;\
196 value = (int32)v >> (int)shift;\
197 }
198 #define LOGICAL_ROR_REG \
199 {\
200 uint32 v = reg[opcode & 0x0f].I;\
201 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
202 value = ((v << (32 - shift)) |\
203 (v >> shift));\
204 }
205 #define LOGICAL_RRX_REG \
206 {\
207 uint32 v = reg[opcode & 0x0f].I;\
208 shift = (int)C_FLAG;\
209 C_OUT = (v & 1) ? true : false;\
210 value = ((v >> 1) |\
211 (shift << 31));\
212 }
213 #define LOGICAL_ROR_IMM \
214 {\
215 uint32 v = opcode & 0xff;\
216 C_OUT = (v >> (shift - 1)) & 1 ? true : false;\
217 value = ((v << (32 - shift)) |\
218 (v >> shift));\
219 }
220 #define ARITHMETIC_LSL_REG \
221 {\
222 uint32 v = reg[opcode & 0x0f].I;\
223 value = v << shift;\
224 }
225 #define ARITHMETIC_LSR_REG \
226 {\
227 uint32 v = reg[opcode & 0x0f].I;\
228 value = v >> shift;\
229 }
230 #define ARITHMETIC_ASR_REG \
231 {\
232 uint32 v = reg[opcode & 0x0f].I;\
233 value = (int32)v >> (int)shift;\
234 }
235 #define ARITHMETIC_ROR_REG \
236 {\
237 uint32 v = reg[opcode & 0x0f].I;\
238 value = ((v << (32 - shift)) |\
239 (v >> shift));\
240 }
241 #define ARITHMETIC_RRX_REG \
242 {\
243 uint32 v = reg[opcode & 0x0f].I;\
244 shift = (int)C_FLAG;\
245 value = ((v >> 1) |\
246 (shift << 31));\
247 }
248 #define ARITHMETIC_ROR_IMM \
249 {\
250 uint32 v = opcode & 0xff;\
251 value = ((v << ((32 - shift) & 0x1F)) |\
252 (v >> shift));\
253 }
254 #define ROR_IMM_MSR \
255 {\
256 uint32 v = opcode & 0xff;\
257 value = ((v << (32 - shift)) |\
258 (v >> shift));\
259 }
260 #define ROR_VALUE \
261 {\
262 value = ((value << (32 - shift)) |\
263 (value >> shift));\
264 }
265 #define RCR_VALUE \
266 {\
267 shift = (int)C_FLAG;\
268 value = ((value >> 1) |\
269 (shift << 31));\
270 }
271
272 #define OP_TST \
273 uint32 res = reg[base].I & value;\
274 N_FLAG = (res & 0x80000000) ? true : false;\
275 Z_FLAG = (res) ? false : true;\
276 C_FLAG = C_OUT;
277
278 #define OP_TEQ \
279 uint32 res = reg[base].I ^ value;\
280 N_FLAG = (res & 0x80000000) ? true : false;\
281 Z_FLAG = (res) ? false : true;\
282 C_FLAG = C_OUT;
283
284 #define OP_ORR \
285 reg[dest].I = reg[base].I | value;
286
287 #define OP_ORRS \
288 reg[dest].I = reg[base].I | value;\
289 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
290 Z_FLAG = (reg[dest].I) ? false : true;\
291 C_FLAG = C_OUT;
292
293 #define OP_MOV \
294 reg[dest].I = value;
295
296 #define OP_MOVS \
297 reg[dest].I = value;\
298 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
299 Z_FLAG = (reg[dest].I) ? false : true;\
300 C_FLAG = C_OUT;
301
302 #define OP_BIC \
303 reg[dest].I = reg[base].I & (~value);
304
305 #define OP_BICS \
306 reg[dest].I = reg[base].I & (~value);\
307 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
308 Z_FLAG = (reg[dest].I) ? false : true;\
309 C_FLAG = C_OUT;
310
311 #define OP_MVN \
312 reg[dest].I = ~value;
313
314 #define OP_MVNS \
315 reg[dest].I = ~value; \
316 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;\
317 Z_FLAG = (reg[dest].I) ? false : true;\
318 C_FLAG = C_OUT;
319
320 #define CASE_16(BASE) \
321 case BASE:\
322 case BASE+1:\
323 case BASE+2:\
324 case BASE+3:\
325 case BASE+4:\
326 case BASE+5:\
327 case BASE+6:\
328 case BASE+7:\
329 case BASE+8:\
330 case BASE+9:\
331 case BASE+10:\
332 case BASE+11:\
333 case BASE+12:\
334 case BASE+13:\
335 case BASE+14:\
336 case BASE+15:
337
338 #define CASE_256(BASE) \
339 CASE_16(BASE)\
340 CASE_16(BASE+0x10)\
341 CASE_16(BASE+0x20)\
342 CASE_16(BASE+0x30)\
343 CASE_16(BASE+0x40)\
344 CASE_16(BASE+0x50)\
345 CASE_16(BASE+0x60)\
346 CASE_16(BASE+0x70)\
347 CASE_16(BASE+0x80)\
348 CASE_16(BASE+0x90)\
349 CASE_16(BASE+0xa0)\
350 CASE_16(BASE+0xb0)\
351 CASE_16(BASE+0xc0)\
352 CASE_16(BASE+0xd0)\
353 CASE_16(BASE+0xe0)\
354 CASE_16(BASE+0xf0)
355
356 #define LOGICAL_DATA_OPCODE(OPCODE, OPCODE2, BASE) \
357 case BASE: \
358 case BASE+8:\
359 {\
360 /* OP Rd,Rb,Rm LSL # */ \
361 int base = (opcode >> 16) & 0x0F;\
362 int shift = (opcode >> 7) & 0x1F;\
363 int dest = (opcode>>12) & 15;\
364 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
365 uint32 value;\
366 \
367 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
368 {\
369 clockTicks = 1+codeTicksAccesint32(armNextPC);\
370 if ((opcode & 0x02000010)==0x10)\
371 clockTicks++;\
372 }\
373 if(shift) {\
374 LOGICAL_LSL_REG\
375 } else {\
376 value = reg[opcode & 0x0F].I;\
377 }\
378 if(dest == 15) {\
379 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
380 OPCODE2\
381 /* todo */\
382 if(opcode & 0x00100000) {\
383 CPUSwitchMode(reg[17].I & 0x1f, false);\
384 }\
385 if(armState) {\
386 reg[15].I &= 0xFFFFFFFC;\
387 armNextPC = reg[15].I;\
388 reg[15].I += 4;\
389 ARM_PREFETCH;\
390 } else {\
391 reg[15].I &= 0xFFFFFFFE;\
392 armNextPC = reg[15].I;\
393 reg[15].I += 2;\
394 THUMB_PREFETCH;\
395 }\
396 } else {\
397 OPCODE \
398 }\
399 }\
400 break;\
401 case BASE+2:\
402 case BASE+10:\
403 {\
404 /* OP Rd,Rb,Rm LSR # */ \
405 int base = (opcode >> 16) & 0x0F;\
406 int shift = (opcode >> 7) & 0x1F;\
407 int dest = (opcode>>12) & 15;\
408 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
409 uint32 value;\
410 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
411 {\
412 clockTicks = 1+codeTicksAccesint32(armNextPC);\
413 if ((opcode & 0x02000010)==0x10)\
414 clockTicks++;\
415 }\
416 if(shift) {\
417 LOGICAL_LSR_REG\
418 } else {\
419 value = 0;\
420 C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\
421 }\
422 \
423 if(dest == 15) {\
424 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
425 OPCODE2\
426 /* todo */\
427 if(opcode & 0x00100000) {\
428 CPUSwitchMode(reg[17].I & 0x1f, false);\
429 }\
430 if(armState) {\
431 reg[15].I &= 0xFFFFFFFC;\
432 armNextPC = reg[15].I;\
433 reg[15].I += 4;\
434 ARM_PREFETCH;\
435 } else {\
436 reg[15].I &= 0xFFFFFFFE;\
437 armNextPC = reg[15].I;\
438 reg[15].I += 2;\
439 THUMB_PREFETCH;\
440 }\
441 } else {\
442 OPCODE \
443 }\
444 }\
445 break;\
446 case BASE+4:\
447 case BASE+12:\
448 {\
449 /* OP Rd,Rb,Rm ASR # */\
450 int base = (opcode >> 16) & 0x0F;\
451 int shift = (opcode >> 7) & 0x1F;\
452 int dest = (opcode>>12) & 15;\
453 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
454 uint32 value;\
455 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
456 {\
457 clockTicks = 1+codeTicksAccesint32(armNextPC);\
458 if ((opcode & 0x02000010)==0x10)\
459 clockTicks++;\
460 }\
461 if(shift) {\
462 LOGICAL_ASR_REG\
463 } else {\
464 if(reg[opcode & 0x0F].I & 0x80000000){\
465 value = 0xFFFFFFFF;\
466 C_OUT = true;\
467 } else {\
468 value = 0;\
469 C_OUT = false;\
470 } \
471 }\
472 \
473 if(dest == 15) {\
474 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
475 OPCODE2\
476 /* todo */\
477 if(opcode & 0x00100000) {\
478 CPUSwitchMode(reg[17].I & 0x1f, false);\
479 }\
480 if(armState) {\
481 reg[15].I &= 0xFFFFFFFC;\
482 armNextPC = reg[15].I;\
483 reg[15].I += 4;\
484 ARM_PREFETCH;\
485 } else {\
486 reg[15].I &= 0xFFFFFFFE;\
487 armNextPC = reg[15].I;\
488 reg[15].I += 2;\
489 THUMB_PREFETCH;\
490 }\
491 } else {\
492 OPCODE \
493 }\
494 }\
495 break;\
496 case BASE+6:\
497 case BASE+14:\
498 {\
499 /* OP Rd,Rb,Rm ROR # */\
500 int base = (opcode >> 16) & 0x0F;\
501 int shift = (opcode >> 7) & 0x1F;\
502 int dest = (opcode>>12) & 15;\
503 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
504 uint32 value;\
505 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
506 {\
507 clockTicks = 1+codeTicksAccesint32(armNextPC);\
508 if ((opcode & 0x02000010)==0x10)\
509 clockTicks++;\
510 }\
511 if(shift) {\
512 LOGICAL_ROR_REG\
513 } else {\
514 LOGICAL_RRX_REG\
515 }\
516 if(dest == 15) {\
517 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
518 OPCODE2\
519 /* todo */\
520 if(opcode & 0x00100000) {\
521 CPUSwitchMode(reg[17].I & 0x1f, false);\
522 }\
523 if(armState) {\
524 reg[15].I &= 0xFFFFFFFC;\
525 armNextPC = reg[15].I;\
526 reg[15].I += 4;\
527 ARM_PREFETCH;\
528 } else {\
529 reg[15].I &= 0xFFFFFFFE;\
530 armNextPC = reg[15].I;\
531 reg[15].I += 2;\
532 THUMB_PREFETCH;\
533 }\
534 } else {\
535 OPCODE \
536 }\
537 }\
538 break;\
539 case BASE+1:\
540 {\
541 /* OP Rd,Rb,Rm LSL Rs */\
542 int base = (opcode >> 16) & 0x0F;\
543 int shift = reg[(opcode >> 8)&15].B.B0;\
544 int dest = (opcode>>12) & 15;\
545 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
546 uint32 value;\
547 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
548 {\
549 clockTicks = 1+codeTicksAccesint32(armNextPC);\
550 if ((opcode & 0x02000010)==0x10)\
551 clockTicks++;\
552 }\
553 if(shift) {\
554 if(shift == 32) {\
555 value = 0;\
556 C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\
557 } else if(shift < 32) {\
558 LOGICAL_LSL_REG\
559 } else {\
560 value = 0;\
561 C_OUT = false;\
562 }\
563 } else {\
564 value = reg[opcode & 0x0F].I;\
565 }\
566 if(dest == 15) {\
567 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
568 OPCODE2\
569 /* todo */\
570 if(opcode & 0x00100000) {\
571 CPUSwitchMode(reg[17].I & 0x1f, false);\
572 }\
573 if(armState) {\
574 reg[15].I &= 0xFFFFFFFC;\
575 armNextPC = reg[15].I;\
576 reg[15].I += 4;\
577 ARM_PREFETCH;\
578 } else {\
579 reg[15].I &= 0xFFFFFFFE;\
580 armNextPC = reg[15].I;\
581 reg[15].I += 2;\
582 THUMB_PREFETCH;\
583 }\
584 } else {\
585 OPCODE \
586 }\
587 }\
588 break;\
589 case BASE+3:\
590 {\
591 /* OP Rd,Rb,Rm LSR Rs */ \
592 int base = (opcode >> 16) & 0x0F;\
593 int shift = reg[(opcode >> 8)&15].B.B0;\
594 int dest = (opcode>>12) & 15;\
595 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
596 uint32 value;\
597 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
598 {\
599 clockTicks = 1+codeTicksAccesint32(armNextPC);\
600 if ((opcode & 0x02000010)==0x10)\
601 clockTicks++;\
602 }\
603 if(shift) {\
604 if(shift == 32) {\
605 value = 0;\
606 C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\
607 } else if(shift < 32) {\
608 LOGICAL_LSR_REG\
609 } else {\
610 value = 0;\
611 C_OUT = false;\
612 }\
613 } else {\
614 value = reg[opcode & 0x0F].I;\
615 }\
616 if(dest == 15) {\
617 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
618 OPCODE2\
619 /* todo */\
620 if(opcode & 0x00100000) {\
621 CPUSwitchMode(reg[17].I & 0x1f, false);\
622 }\
623 if(armState) {\
624 reg[15].I &= 0xFFFFFFFC;\
625 armNextPC = reg[15].I;\
626 reg[15].I += 4;\
627 ARM_PREFETCH;\
628 } else {\
629 reg[15].I &= 0xFFFFFFFE;\
630 armNextPC = reg[15].I;\
631 reg[15].I += 2;\
632 THUMB_PREFETCH;\
633 }\
634 } else {\
635 OPCODE \
636 }\
637 }\
638 break;\
639 case BASE+5:\
640 {\
641 /* OP Rd,Rb,Rm ASR Rs */ \
642 int base = (opcode >> 16) & 0x0F;\
643 int shift = reg[(opcode >> 8)&15].B.B0;\
644 int dest = (opcode>>12) & 15;\
645 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
646 uint32 value;\
647 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
648 {\
649 clockTicks = 1+codeTicksAccesint32(armNextPC);\
650 if ((opcode & 0x02000010)==0x10)\
651 clockTicks++;\
652 }\
653 if(shift < 32) {\
654 if(shift) {\
655 LOGICAL_ASR_REG\
656 } else {\
657 value = reg[opcode & 0x0F].I;\
658 }\
659 } else {\
660 if(reg[opcode & 0x0F].I & 0x80000000){\
661 value = 0xFFFFFFFF;\
662 C_OUT = true;\
663 } else {\
664 value = 0;\
665 C_OUT = false;\
666 }\
667 }\
668 if(dest == 15) {\
669 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
670 OPCODE2\
671 /* todo */\
672 if(opcode & 0x00100000) {\
673 CPUSwitchMode(reg[17].I & 0x1f, false);\
674 }\
675 if(armState) {\
676 reg[15].I &= 0xFFFFFFFC;\
677 armNextPC = reg[15].I;\
678 reg[15].I += 4;\
679 ARM_PREFETCH;\
680 } else {\
681 reg[15].I &= 0xFFFFFFFE;\
682 armNextPC = reg[15].I;\
683 reg[15].I += 2;\
684 THUMB_PREFETCH;\
685 }\
686 } else {\
687 OPCODE \
688 }\
689 }\
690 break;\
691 case BASE+7:\
692 {\
693 /* OP Rd,Rb,Rm ROR Rs */\
694 int base = (opcode >> 16) & 0x0F;\
695 int shift = reg[(opcode >> 8)&15].B.B0;\
696 int dest = (opcode>>12) & 15;\
697 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
698 uint32 value;\
699 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
700 {\
701 clockTicks = 1+codeTicksAccesint32(armNextPC);\
702 if ((opcode & 0x02000010)==0x10)\
703 clockTicks++;\
704 }\
705 if(shift) {\
706 shift &= 0x1f;\
707 if(shift) {\
708 LOGICAL_ROR_REG\
709 } else {\
710 value = reg[opcode & 0x0F].I;\
711 C_OUT = (value & 0x80000000 ? true : false);\
712 }\
713 } else {\
714 value = reg[opcode & 0x0F].I;\
715 C_OUT = (value & 0x80000000 ? true : false);\
716 }\
717 if(dest == 15) {\
718 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
719 OPCODE2\
720 /* todo */\
721 if(opcode & 0x00100000) {\
722 CPUSwitchMode(reg[17].I & 0x1f, false);\
723 }\
724 if(armState) {\
725 reg[15].I &= 0xFFFFFFFC;\
726 armNextPC = reg[15].I;\
727 reg[15].I += 4;\
728 ARM_PREFETCH;\
729 } else {\
730 reg[15].I &= 0xFFFFFFFE;\
731 armNextPC = reg[15].I;\
732 reg[15].I += 2;\
733 THUMB_PREFETCH;\
734 }\
735 } else {\
736 OPCODE \
737 }\
738 }\
739 break;\
740 case BASE+0x200:\
741 case BASE+0x201:\
742 case BASE+0x202:\
743 case BASE+0x203:\
744 case BASE+0x204:\
745 case BASE+0x205:\
746 case BASE+0x206:\
747 case BASE+0x207:\
748 case BASE+0x208:\
749 case BASE+0x209:\
750 case BASE+0x20a:\
751 case BASE+0x20b:\
752 case BASE+0x20c:\
753 case BASE+0x20d:\
754 case BASE+0x20e:\
755 case BASE+0x20f:\
756 {\
757 int shift = (opcode & 0xF00) >> 7;\
758 int base = (opcode >> 16) & 0x0F;\
759 int dest = (opcode >> 12) & 0x0F;\
760 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
761 uint32 value;\
762 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
763 {\
764 clockTicks = 1+codeTicksAccesint32(armNextPC);\
765 if ((opcode & 0x02000010)==0x10)\
766 clockTicks++;\
767 }\
768 if(shift) {\
769 LOGICAL_ROR_IMM\
770 } else {\
771 value = opcode & 0xff;\
772 }\
773 if(dest == 15) {\
774 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
775 OPCODE2\
776 /* todo */\
777 if(opcode & 0x00100000) {\
778 CPUSwitchMode(reg[17].I & 0x1f, false);\
779 }\
780 if(armState) {\
781 reg[15].I &= 0xFFFFFFFC;\
782 armNextPC = reg[15].I;\
783 reg[15].I += 4;\
784 ARM_PREFETCH;\
785 } else {\
786 reg[15].I &= 0xFFFFFFFE;\
787 armNextPC = reg[15].I;\
788 reg[15].I += 2;\
789 THUMB_PREFETCH;\
790 }\
791 } else {\
792 OPCODE \
793 }\
794 }\
795 break;
796
797 #define LOGICAL_DATA_OPCODE_WITHOUT_base(OPCODE, OPCODE2, BASE) \
798 case BASE: \
799 case BASE+8:\
800 {\
801 /* OP Rd,Rb,Rm LSL # */ \
802 int shift = (opcode >> 7) & 0x1F;\
803 int dest = (opcode>>12) & 15;\
804 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
805 uint32 value;\
806 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
807 {\
808 clockTicks = 1+codeTicksAccesint32(armNextPC);\
809 if ((opcode & 0x02000010)==0x10)\
810 clockTicks++;\
811 }\
812 \
813 if(shift) {\
814 LOGICAL_LSL_REG\
815 } else {\
816 value = reg[opcode & 0x0F].I;\
817 }\
818 if(dest == 15) {\
819 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
820 OPCODE2\
821 /* todo */\
822 if(opcode & 0x00100000) {\
823 CPUSwitchMode(reg[17].I & 0x1f, false);\
824 }\
825 if(armState) {\
826 reg[15].I &= 0xFFFFFFFC;\
827 armNextPC = reg[15].I;\
828 reg[15].I += 4;\
829 ARM_PREFETCH;\
830 } else {\
831 reg[15].I &= 0xFFFFFFFE;\
832 armNextPC = reg[15].I;\
833 reg[15].I += 2;\
834 THUMB_PREFETCH;\
835 }\
836 } else {\
837 OPCODE \
838 }\
839 }\
840 break;\
841 case BASE+2:\
842 case BASE+10:\
843 {\
844 /* OP Rd,Rb,Rm LSR # */ \
845 int shift = (opcode >> 7) & 0x1F;\
846 int dest = (opcode>>12) & 15;\
847 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
848 uint32 value;\
849 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
850 {\
851 clockTicks = 1+codeTicksAccesint32(armNextPC);\
852 if ((opcode & 0x02000010)==0x10)\
853 clockTicks++;\
854 }\
855 if(shift) {\
856 LOGICAL_LSR_REG\
857 } else {\
858 value = 0;\
859 C_OUT = (reg[opcode & 0x0F].I & 0x80000000) ? true : false;\
860 }\
861 \
862 if(dest == 15) {\
863 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
864 OPCODE2\
865 /* todo */\
866 if(opcode & 0x00100000) {\
867 CPUSwitchMode(reg[17].I & 0x1f, false);\
868 }\
869 if(armState) {\
870 reg[15].I &= 0xFFFFFFFC;\
871 armNextPC = reg[15].I;\
872 reg[15].I += 4;\
873 ARM_PREFETCH;\
874 } else {\
875 reg[15].I &= 0xFFFFFFFE;\
876 armNextPC = reg[15].I;\
877 reg[15].I += 2;\
878 THUMB_PREFETCH;\
879 }\
880 } else {\
881 OPCODE \
882 }\
883 }\
884 break;\
885 case BASE+4:\
886 case BASE+12:\
887 {\
888 /* OP Rd,Rb,Rm ASR # */\
889 int shift = (opcode >> 7) & 0x1F;\
890 int dest = (opcode>>12) & 15;\
891 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
892 uint32 value;\
893 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
894 {\
895 clockTicks = 1+codeTicksAccesint32(armNextPC);\
896 if ((opcode & 0x02000010)==0x10)\
897 clockTicks++;\
898 }\
899 if(shift) {\
900 LOGICAL_ASR_REG\
901 } else {\
902 if(reg[opcode & 0x0F].I & 0x80000000){\
903 value = 0xFFFFFFFF;\
904 C_OUT = true;\
905 } else {\
906 value = 0;\
907 C_OUT = false;\
908 } \
909 }\
910 \
911 if(dest == 15) {\
912 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
913 OPCODE2\
914 /* todo */\
915 if(opcode & 0x00100000) {\
916 CPUSwitchMode(reg[17].I & 0x1f, false);\
917 }\
918 if(armState) {\
919 reg[15].I &= 0xFFFFFFFC;\
920 armNextPC = reg[15].I;\
921 reg[15].I += 4;\
922 ARM_PREFETCH;\
923 } else {\
924 reg[15].I &= 0xFFFFFFFE;\
925 armNextPC = reg[15].I;\
926 reg[15].I += 2;\
927 THUMB_PREFETCH;\
928 }\
929 } else {\
930 OPCODE \
931 }\
932 }\
933 break;\
934 case BASE+6:\
935 case BASE+14:\
936 {\
937 /* OP Rd,Rb,Rm ROR # */\
938 int shift = (opcode >> 7) & 0x1F;\
939 int dest = (opcode>>12) & 15;\
940 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
941 uint32 value;\
942 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
943 {\
944 clockTicks = 1+codeTicksAccesint32(armNextPC);\
945 if ((opcode & 0x02000010)==0x10)\
946 clockTicks++;\
947 }\
948 if(shift) {\
949 LOGICAL_ROR_REG\
950 } else {\
951 LOGICAL_RRX_REG\
952 }\
953 if(dest == 15) {\
954 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
955 OPCODE2\
956 /* todo */\
957 if(opcode & 0x00100000) {\
958 CPUSwitchMode(reg[17].I & 0x1f, false);\
959 }\
960 if(armState) {\
961 reg[15].I &= 0xFFFFFFFC;\
962 armNextPC = reg[15].I;\
963 reg[15].I += 4;\
964 ARM_PREFETCH;\
965 } else {\
966 reg[15].I &= 0xFFFFFFFE;\
967 armNextPC = reg[15].I;\
968 reg[15].I += 2;\
969 THUMB_PREFETCH;\
970 }\
971 } else {\
972 OPCODE \
973 }\
974 }\
975 break;\
976 case BASE+1:\
977 {\
978 /* OP Rd,Rb,Rm LSL Rs */\
979 int shift = reg[(opcode >> 8)&15].B.B0;\
980 int dest = (opcode>>12) & 15;\
981 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
982 uint32 value;\
983 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
984 {\
985 clockTicks = 1+codeTicksAccesint32(armNextPC);\
986 if ((opcode & 0x02000010)==0x10)\
987 clockTicks++;\
988 }\
989 if(shift) {\
990 if(shift == 32) {\
991 value = 0;\
992 C_OUT = (reg[opcode & 0x0F].I & 1 ? true : false);\
993 } else if(shift < 32) {\
994 LOGICAL_LSL_REG\
995 } else {\
996 value = 0;\
997 C_OUT = false;\
998 }\
999 } else {\
1000 value = reg[opcode & 0x0F].I;\
1001 }\
1002 if(dest == 15) {\
1003 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1004 OPCODE2\
1005 /* todo */\
1006 if(opcode & 0x00100000) {\
1007 CPUSwitchMode(reg[17].I & 0x1f, false);\
1008 }\
1009 if(armState) {\
1010 reg[15].I &= 0xFFFFFFFC;\
1011 armNextPC = reg[15].I;\
1012 reg[15].I += 4;\
1013 ARM_PREFETCH;\
1014 } else {\
1015 reg[15].I &= 0xFFFFFFFE;\
1016 armNextPC = reg[15].I;\
1017 reg[15].I += 2;\
1018 THUMB_PREFETCH;\
1019 }\
1020 } else {\
1021 OPCODE \
1022 }\
1023 }\
1024 break;\
1025 case BASE+3:\
1026 {\
1027 /* OP Rd,Rb,Rm LSR Rs */ \
1028 int shift = reg[(opcode >> 8)&15].B.B0;\
1029 int dest = (opcode>>12) & 15;\
1030 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
1031 uint32 value;\
1032 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1033 {\
1034 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1035 if ((opcode & 0x02000010)==0x10)\
1036 clockTicks++;\
1037 }\
1038 if(shift) {\
1039 if(shift == 32) {\
1040 value = 0;\
1041 C_OUT = (reg[opcode & 0x0F].I & 0x80000000 ? true : false);\
1042 } else if(shift < 32) {\
1043 LOGICAL_LSR_REG\
1044 } else {\
1045 value = 0;\
1046 C_OUT = false;\
1047 }\
1048 } else {\
1049 value = reg[opcode & 0x0F].I;\
1050 }\
1051 if(dest == 15) {\
1052 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1053 OPCODE2\
1054 /* todo */\
1055 if(opcode & 0x00100000) {\
1056 CPUSwitchMode(reg[17].I & 0x1f, false);\
1057 }\
1058 if(armState) {\
1059 reg[15].I &= 0xFFFFFFFC;\
1060 armNextPC = reg[15].I;\
1061 reg[15].I += 4;\
1062 ARM_PREFETCH;\
1063 } else {\
1064 reg[15].I &= 0xFFFFFFFE;\
1065 armNextPC = reg[15].I;\
1066 reg[15].I += 2;\
1067 THUMB_PREFETCH;\
1068 }\
1069 } else {\
1070 OPCODE \
1071 }\
1072 }\
1073 break;\
1074 case BASE+5:\
1075 {\
1076 /* OP Rd,Rb,Rm ASR Rs */ \
1077 int shift = reg[(opcode >> 8)&15].B.B0;\
1078 int dest = (opcode>>12) & 15;\
1079 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
1080 uint32 value;\
1081 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1082 {\
1083 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1084 if ((opcode & 0x02000010)==0x10)\
1085 clockTicks++;\
1086 }\
1087 if(shift < 32) {\
1088 if(shift) {\
1089 LOGICAL_ASR_REG\
1090 } else {\
1091 value = reg[opcode & 0x0F].I;\
1092 }\
1093 } else {\
1094 if(reg[opcode & 0x0F].I & 0x80000000){\
1095 value = 0xFFFFFFFF;\
1096 C_OUT = true;\
1097 } else {\
1098 value = 0;\
1099 C_OUT = false;\
1100 }\
1101 }\
1102 if(dest == 15) {\
1103 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1104 OPCODE2\
1105 /* todo */\
1106 if(opcode & 0x00100000) {\
1107 CPUSwitchMode(reg[17].I & 0x1f, false);\
1108 }\
1109 if(armState) {\
1110 reg[15].I &= 0xFFFFFFFC;\
1111 armNextPC = reg[15].I;\
1112 reg[15].I += 4;\
1113 ARM_PREFETCH;\
1114 } else {\
1115 reg[15].I &= 0xFFFFFFFE;\
1116 armNextPC = reg[15].I;\
1117 reg[15].I += 2;\
1118 THUMB_PREFETCH;\
1119 }\
1120 } else {\
1121 OPCODE \
1122 }\
1123 }\
1124 break;\
1125 case BASE+7:\
1126 {\
1127 /* OP Rd,Rb,Rm ROR Rs */\
1128 int shift = reg[(opcode >> 8)&15].B.B0;\
1129 int dest = (opcode>>12) & 15;\
1130 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
1131 uint32 value;\
1132 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1133 {\
1134 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1135 if ((opcode & 0x02000010)==0x10)\
1136 clockTicks++;\
1137 }\
1138 if(shift) {\
1139 shift &= 0x1f;\
1140 if(shift) {\
1141 LOGICAL_ROR_REG\
1142 } else {\
1143 value = reg[opcode & 0x0F].I;\
1144 C_OUT = (value & 0x80000000 ? true : false);\
1145 }\
1146 } else {\
1147 value = reg[opcode & 0x0F].I;\
1148 C_OUT = (value & 0x80000000 ? true : false);\
1149 }\
1150 if(dest == 15) {\
1151 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1152 OPCODE2\
1153 /* todo */\
1154 if(opcode & 0x00100000) {\
1155 CPUSwitchMode(reg[17].I & 0x1f, false);\
1156 }\
1157 if(armState) {\
1158 reg[15].I &= 0xFFFFFFFC;\
1159 armNextPC = reg[15].I;\
1160 reg[15].I += 4;\
1161 ARM_PREFETCH;\
1162 } else {\
1163 reg[15].I &= 0xFFFFFFFE;\
1164 armNextPC = reg[15].I;\
1165 reg[15].I += 2;\
1166 THUMB_PREFETCH;\
1167 }\
1168 } else {\
1169 OPCODE \
1170 }\
1171 }\
1172 break;\
1173 case BASE+0x200:\
1174 case BASE+0x201:\
1175 case BASE+0x202:\
1176 case BASE+0x203:\
1177 case BASE+0x204:\
1178 case BASE+0x205:\
1179 case BASE+0x206:\
1180 case BASE+0x207:\
1181 case BASE+0x208:\
1182 case BASE+0x209:\
1183 case BASE+0x20a:\
1184 case BASE+0x20b:\
1185 case BASE+0x20c:\
1186 case BASE+0x20d:\
1187 case BASE+0x20e:\
1188 case BASE+0x20f:\
1189 {\
1190 int shift = (opcode & 0xF00) >> 7;\
1191 int dest = (opcode >> 12) & 0x0F;\
1192 bool C_OUT MDFN_NOWARN_UNUSED = C_FLAG;\
1193 uint32 value;\
1194 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1195 {\
1196 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1197 if ((opcode & 0x02000010)==0x10)\
1198 clockTicks++;\
1199 }\
1200 if(shift) {\
1201 LOGICAL_ROR_IMM\
1202 } else {\
1203 value = opcode & 0xff;\
1204 }\
1205 if(dest == 15) {\
1206 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1207 OPCODE2\
1208 /* todo */\
1209 if(opcode & 0x00100000) {\
1210 CPUSwitchMode(reg[17].I & 0x1f, false);\
1211 }\
1212 if(armState) {\
1213 reg[15].I &= 0xFFFFFFFC;\
1214 armNextPC = reg[15].I;\
1215 reg[15].I += 4;\
1216 ARM_PREFETCH;\
1217 } else {\
1218 reg[15].I &= 0xFFFFFFFE;\
1219 armNextPC = reg[15].I;\
1220 reg[15].I += 2;\
1221 THUMB_PREFETCH;\
1222 }\
1223 } else {\
1224 OPCODE \
1225 }\
1226 }\
1227 break;
1228
1229 #define ARITHMETIC_DATA_OPCODE(OPCODE, OPCODE2, BASE) \
1230 case BASE:\
1231 case BASE+8:\
1232 {\
1233 /* OP Rd,Rb,Rm LSL # */\
1234 int base = (opcode >> 16) & 0x0F;\
1235 int shift = (opcode >> 7) & 0x1F;\
1236 int dest = (opcode>>12) & 15;\
1237 uint32 value;\
1238 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1239 {\
1240 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1241 if ((opcode & 0x02000010)==0x10)\
1242 clockTicks++;\
1243 }\
1244 if(shift) {\
1245 ARITHMETIC_LSL_REG\
1246 } else {\
1247 value = reg[opcode & 0x0F].I;\
1248 }\
1249 if(dest == 15) {\
1250 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1251 OPCODE2\
1252 /* todo */\
1253 if(opcode & 0x00100000) {\
1254 CPUSwitchMode(reg[17].I & 0x1f, false);\
1255 }\
1256 if(armState) {\
1257 reg[15].I &= 0xFFFFFFFC;\
1258 armNextPC = reg[15].I;\
1259 reg[15].I += 4;\
1260 ARM_PREFETCH;\
1261 } else {\
1262 reg[15].I &= 0xFFFFFFFE;\
1263 armNextPC = reg[15].I;\
1264 reg[15].I += 2;\
1265 THUMB_PREFETCH;\
1266 }\
1267 } else {\
1268 OPCODE \
1269 }\
1270 }\
1271 break;\
1272 case BASE+2:\
1273 case BASE+10:\
1274 {\
1275 /* OP Rd,Rb,Rm LSR # */\
1276 int base = (opcode >> 16) & 0x0F;\
1277 int shift = (opcode >> 7) & 0x1F;\
1278 int dest = (opcode>>12) & 15;\
1279 uint32 value;\
1280 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1281 {\
1282 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1283 if ((opcode & 0x02000010)==0x10)\
1284 clockTicks++;\
1285 }\
1286 if(shift) {\
1287 ARITHMETIC_LSR_REG\
1288 } else {\
1289 value = 0;\
1290 }\
1291 if(dest == 15) {\
1292 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1293 OPCODE2\
1294 /* todo */\
1295 if(opcode & 0x00100000) {\
1296 CPUSwitchMode(reg[17].I & 0x1f, false);\
1297 }\
1298 if(armState) {\
1299 reg[15].I &= 0xFFFFFFFC;\
1300 armNextPC = reg[15].I;\
1301 reg[15].I += 4;\
1302 ARM_PREFETCH;\
1303 } else {\
1304 reg[15].I &= 0xFFFFFFFE;\
1305 armNextPC = reg[15].I;\
1306 reg[15].I += 2;\
1307 THUMB_PREFETCH;\
1308 }\
1309 } else {\
1310 OPCODE \
1311 }\
1312 }\
1313 break;\
1314 case BASE+4:\
1315 case BASE+12:\
1316 {\
1317 /* OP Rd,Rb,Rm ASR # */\
1318 int base = (opcode >> 16) & 0x0F;\
1319 int shift = (opcode >> 7) & 0x1F;\
1320 int dest = (opcode>>12) & 15;\
1321 uint32 value;\
1322 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1323 {\
1324 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1325 if ((opcode & 0x02000010)==0x10)\
1326 clockTicks++;\
1327 }\
1328 if(shift) {\
1329 ARITHMETIC_ASR_REG\
1330 } else {\
1331 if(reg[opcode & 0x0F].I & 0x80000000){\
1332 value = 0xFFFFFFFF;\
1333 } else value = 0;\
1334 }\
1335 if(dest == 15) {\
1336 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1337 OPCODE2\
1338 /* todo */\
1339 if(opcode & 0x00100000) {\
1340 CPUSwitchMode(reg[17].I & 0x1f, false);\
1341 }\
1342 if(armState) {\
1343 reg[15].I &= 0xFFFFFFFC;\
1344 armNextPC = reg[15].I;\
1345 reg[15].I += 4;\
1346 ARM_PREFETCH;\
1347 } else {\
1348 reg[15].I &= 0xFFFFFFFE;\
1349 armNextPC = reg[15].I;\
1350 reg[15].I += 2;\
1351 THUMB_PREFETCH;\
1352 }\
1353 } else {\
1354 OPCODE \
1355 }\
1356 }\
1357 break;\
1358 case BASE+6:\
1359 case BASE+14:\
1360 {\
1361 /* OP Rd,Rb,Rm ROR # */\
1362 int base = (opcode >> 16) & 0x0F;\
1363 int shift = (opcode >> 7) & 0x1F;\
1364 int dest = (opcode>>12) & 15;\
1365 uint32 value;\
1366 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1367 {\
1368 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1369 if ((opcode & 0x02000010)==0x10)\
1370 clockTicks++;\
1371 }\
1372 if(shift) {\
1373 ARITHMETIC_ROR_REG\
1374 } else {\
1375 ARITHMETIC_RRX_REG\
1376 }\
1377 if(dest == 15) {\
1378 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1379 OPCODE2\
1380 /* todo */\
1381 if(opcode & 0x00100000) {\
1382 CPUSwitchMode(reg[17].I & 0x1f, false);\
1383 }\
1384 if(armState) {\
1385 reg[15].I &= 0xFFFFFFFC;\
1386 armNextPC = reg[15].I;\
1387 reg[15].I += 4;\
1388 ARM_PREFETCH;\
1389 } else {\
1390 reg[15].I &= 0xFFFFFFFE;\
1391 armNextPC = reg[15].I;\
1392 reg[15].I += 2;\
1393 THUMB_PREFETCH;\
1394 }\
1395 } else {\
1396 OPCODE \
1397 }\
1398 }\
1399 break;\
1400 case BASE+1:\
1401 {\
1402 /* OP Rd,Rb,Rm LSL Rs */\
1403 int base = (opcode >> 16) & 0x0F;\
1404 int shift = reg[(opcode >> 8)&15].B.B0;\
1405 int dest = (opcode>>12) & 15;\
1406 uint32 value;\
1407 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1408 {\
1409 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1410 if ((opcode & 0x02000010)==0x10)\
1411 clockTicks++;\
1412 }\
1413 if(shift) {\
1414 if(shift == 32) {\
1415 value = 0;\
1416 } else if(shift < 32) {\
1417 ARITHMETIC_LSL_REG\
1418 } else value = 0;\
1419 } else {\
1420 value = reg[opcode & 0x0F].I;\
1421 }\
1422 if(dest == 15) {\
1423 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1424 OPCODE2\
1425 /* todo */\
1426 if(opcode & 0x00100000) {\
1427 CPUSwitchMode(reg[17].I & 0x1f, false);\
1428 }\
1429 if(armState) {\
1430 reg[15].I &= 0xFFFFFFFC;\
1431 armNextPC = reg[15].I;\
1432 reg[15].I += 4;\
1433 ARM_PREFETCH;\
1434 } else {\
1435 reg[15].I &= 0xFFFFFFFE;\
1436 armNextPC = reg[15].I;\
1437 reg[15].I += 2;\
1438 THUMB_PREFETCH;\
1439 }\
1440 } else {\
1441 OPCODE \
1442 }\
1443 }\
1444 break;\
1445 case BASE+3:\
1446 {\
1447 /* OP Rd,Rb,Rm LSR Rs */\
1448 int base = (opcode >> 16) & 0x0F;\
1449 int shift = reg[(opcode >> 8)&15].B.B0;\
1450 int dest = (opcode>>12) & 15;\
1451 uint32 value;\
1452 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1453 {\
1454 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1455 if ((opcode & 0x02000010)==0x10)\
1456 clockTicks++;\
1457 }\
1458 if(shift) {\
1459 if(shift == 32) {\
1460 value = 0;\
1461 } else if(shift < 32) {\
1462 ARITHMETIC_LSR_REG\
1463 } else value = 0;\
1464 } else {\
1465 value = reg[opcode & 0x0F].I;\
1466 }\
1467 if(dest == 15) {\
1468 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1469 OPCODE2\
1470 /* todo */\
1471 if(opcode & 0x00100000) {\
1472 CPUSwitchMode(reg[17].I & 0x1f, false);\
1473 }\
1474 if(armState) {\
1475 reg[15].I &= 0xFFFFFFFC;\
1476 armNextPC = reg[15].I;\
1477 reg[15].I += 4;\
1478 ARM_PREFETCH;\
1479 } else {\
1480 reg[15].I &= 0xFFFFFFFE;\
1481 armNextPC = reg[15].I;\
1482 reg[15].I += 2;\
1483 THUMB_PREFETCH;\
1484 }\
1485 } else {\
1486 OPCODE \
1487 }\
1488 }\
1489 break;\
1490 case BASE+5:\
1491 {\
1492 /* OP Rd,Rb,Rm ASR Rs */\
1493 int base = (opcode >> 16) & 0x0F;\
1494 int shift = reg[(opcode >> 8)&15].B.B0;\
1495 int dest = (opcode>>12) & 15;\
1496 uint32 value;\
1497 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1498 {\
1499 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1500 if ((opcode & 0x02000010)==0x10)\
1501 clockTicks++;\
1502 }\
1503 if(shift < 32) {\
1504 if(shift) {\
1505 ARITHMETIC_ASR_REG\
1506 } else {\
1507 value = reg[opcode & 0x0F].I;\
1508 }\
1509 } else {\
1510 if(reg[opcode & 0x0F].I & 0x80000000){\
1511 value = 0xFFFFFFFF;\
1512 } else value = 0;\
1513 }\
1514 if(dest == 15) {\
1515 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1516 OPCODE2\
1517 /* todo */\
1518 if(opcode & 0x00100000) {\
1519 CPUSwitchMode(reg[17].I & 0x1f, false);\
1520 }\
1521 if(armState) {\
1522 reg[15].I &= 0xFFFFFFFC;\
1523 armNextPC = reg[15].I;\
1524 reg[15].I += 4;\
1525 ARM_PREFETCH;\
1526 } else {\
1527 reg[15].I &= 0xFFFFFFFE;\
1528 armNextPC = reg[15].I;\
1529 reg[15].I += 2;\
1530 THUMB_PREFETCH;\
1531 }\
1532 } else {\
1533 OPCODE \
1534 }\
1535 }\
1536 break;\
1537 case BASE+7:\
1538 {\
1539 /* OP Rd,Rb,Rm ROR Rs */\
1540 int base = (opcode >> 16) & 0x0F;\
1541 int shift = reg[(opcode >> 8)&15].B.B0;\
1542 int dest = (opcode>>12) & 15;\
1543 uint32 value;\
1544 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1545 {\
1546 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1547 if ((opcode & 0x02000010)==0x10)\
1548 clockTicks++;\
1549 }\
1550 if(shift) {\
1551 shift &= 0x1f;\
1552 if(shift) {\
1553 ARITHMETIC_ROR_REG\
1554 } else {\
1555 value = reg[opcode & 0x0F].I;\
1556 }\
1557 } else {\
1558 value = reg[opcode & 0x0F].I;\
1559 }\
1560 if(dest == 15) {\
1561 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1562 OPCODE2\
1563 /* todo */\
1564 if(opcode & 0x00100000) {\
1565 CPUSwitchMode(reg[17].I & 0x1f, false);\
1566 }\
1567 if(armState) {\
1568 reg[15].I &= 0xFFFFFFFC;\
1569 armNextPC = reg[15].I;\
1570 reg[15].I += 4;\
1571 ARM_PREFETCH;\
1572 } else {\
1573 reg[15].I &= 0xFFFFFFFE;\
1574 armNextPC = reg[15].I;\
1575 reg[15].I += 2;\
1576 THUMB_PREFETCH;\
1577 }\
1578 } else {\
1579 OPCODE \
1580 }\
1581 }\
1582 break;\
1583 case BASE+0x200:\
1584 case BASE+0x201:\
1585 case BASE+0x202:\
1586 case BASE+0x203:\
1587 case BASE+0x204:\
1588 case BASE+0x205:\
1589 case BASE+0x206:\
1590 case BASE+0x207:\
1591 case BASE+0x208:\
1592 case BASE+0x209:\
1593 case BASE+0x20a:\
1594 case BASE+0x20b:\
1595 case BASE+0x20c:\
1596 case BASE+0x20d:\
1597 case BASE+0x20e:\
1598 case BASE+0x20f:\
1599 {\
1600 int shift = (opcode & 0xF00) >> 7;\
1601 int base = (opcode >> 16) & 0x0F;\
1602 int dest = (opcode >> 12) & 0x0F;\
1603 uint32 value;\
1604 if ((dest == 15)||((opcode & 0x02000010)==0x10))\
1605 {\
1606 clockTicks = 1+codeTicksAccesint32(armNextPC);\
1607 if ((opcode & 0x02000010)==0x10)\
1608 clockTicks++;\
1609 }\
1610 {\
1611 ARITHMETIC_ROR_IMM\
1612 }\
1613 if(dest == 15) {\
1614 clockTicks+=2+codeTicksAccessSeq32(armNextPC)+codeTicksAccessSeq32(armNextPC);\
1615 OPCODE2\
1616 /* todo */\
1617 if(opcode & 0x00100000) {\
1618 CPUSwitchMode(reg[17].I & 0x1f, false);\
1619 }\
1620 if(armState) {\
1621 reg[15].I &= 0xFFFFFFFC;\
1622 armNextPC = reg[15].I;\
1623 reg[15].I += 4;\
1624 ARM_PREFETCH;\
1625 } else {\
1626 reg[15].I &= 0xFFFFFFFE;\
1627 armNextPC = reg[15].I;\
1628 reg[15].I += 2;\
1629 THUMB_PREFETCH;\
1630 }\
1631 } else {\
1632 OPCODE \
1633 }\
1634 }\
1635 break;
1636
1637 uint32 opcode = cpuPrefetch[0];
1638 cpuPrefetch[0] = cpuPrefetch[1];
1639
1640 busPrefetch = false;
1641 if (busPrefetchCount & 0xFFFFFE00)
1642 busPrefetchCount = 0x100 | (busPrefetchCount & 0xFF);
1643
1644
1645 clockTicks = 0;//codeTicksAccessSeq32(armNextPC)+1;
1646 int oldArmNextPC = armNextPC;
1647
1648 #ifndef FINAL_VERSION
1649 if(armNextPC == stop) {
1650 armNextPC++;
1651 }
1652 #endif
1653
1654 armNextPC = reg[15].I;
1655 reg[15].I += 4;
1656 ARM_PREFETCH_NEXT;
1657
1658 int cond = opcode >> 28;
1659 // suggested optimization for frequent cases
1660 bool cond_res;
1661 if(cond == 0x0e) {
1662 cond_res = true;
1663 } else {
1664 switch(cond) {
1665 case 0x00: // EQ
1666 cond_res = Z_FLAG;
1667 break;
1668 case 0x01: // NE
1669 cond_res = !Z_FLAG;
1670 break;
1671 case 0x02: // CS
1672 cond_res = C_FLAG;
1673 break;
1674 case 0x03: // CC
1675 cond_res = !C_FLAG;
1676 break;
1677 case 0x04: // MI
1678 cond_res = N_FLAG;
1679 break;
1680 case 0x05: // PL
1681 cond_res = !N_FLAG;
1682 break;
1683 case 0x06: // VS
1684 cond_res = V_FLAG;
1685 break;
1686 case 0x07: // VC
1687 cond_res = !V_FLAG;
1688 break;
1689 case 0x08: // HI
1690 cond_res = C_FLAG && !Z_FLAG;
1691 break;
1692 case 0x09: // LS
1693 cond_res = !C_FLAG || Z_FLAG;
1694 break;
1695 case 0x0A: // GE
1696 cond_res = N_FLAG == V_FLAG;
1697 break;
1698 case 0x0B: // LT
1699 cond_res = N_FLAG != V_FLAG;
1700 break;
1701 case 0x0C: // GT
1702 cond_res = !Z_FLAG &&(N_FLAG == V_FLAG);
1703 break;
1704 case 0x0D: // LE
1705 cond_res = Z_FLAG || (N_FLAG != V_FLAG);
1706 break;
1707 case 0x0E:
1708 cond_res = true;
1709 break;
1710 case 0x0F:
1711 default:
1712 // ???
1713 cond_res = false;
1714 break;
1715 }
1716 }
1717
1718 if(cond_res) {
1719 switch(((opcode>>16)&0xFF0) | ((opcode>>4)&0x0F)) {
1720 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_AND, OP_AND, 0x000);
1721 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_ANDS, OP_AND, 0x010);
1722 case 0x009:
1723 {
1724 // MUL Rd, Rm, Rs
1725 int dest = (opcode >> 16) & 0x0F;
1726 int mult = (opcode & 0x0F);
1727 clockTicks = 1;
1728 uint32 rs = reg[(opcode >> 8) & 0x0F].I;
1729 reg[dest].I = reg[mult].I * rs;
1730 if(((int32)rs)<0)
1731 rs = ~rs;
1732 if((rs & 0xFFFFFF00) == 0)
1733 clockTicks += 0;
1734 else if ((rs & 0xFFFF0000) == 0)
1735 clockTicks += 1;
1736 else if ((rs & 0xFF000000) == 0)
1737 clockTicks += 2;
1738 else
1739 clockTicks += 3;
1740 if (busPrefetchCount==0)
1741 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
1742 clockTicks += codeTicksAccesint32(armNextPC) + 1;
1743
1744 }
1745 break;
1746 case 0x019:
1747 {
1748 // MULS Rd, Rm, Rs
1749 int dest = (opcode >> 16) & 0x0F;
1750 int mult = (opcode & 0x0F);
1751 clockTicks = 1;
1752 uint32 rs = reg[(opcode >> 8) & 0x0F].I;
1753 reg[dest].I = reg[mult].I * rs;
1754 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;
1755 Z_FLAG = (reg[dest].I) ? false : true;
1756 if(((int32)rs)<0)
1757 rs = ~rs;
1758 if((rs & 0xFFFFFF00) == 0)
1759 clockTicks += 0;
1760 else if ((rs & 0xFFFF0000) == 0)
1761 clockTicks += 1;
1762 else if ((rs & 0xFF000000) == 0)
1763 clockTicks += 2;
1764 else
1765 clockTicks += 3;
1766 if (busPrefetchCount==0)
1767 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
1768 clockTicks += codeTicksAccesint32(armNextPC) + 1;
1769 }
1770 break;
1771 case 0x00b:
1772 case 0x02b:
1773 {
1774 // STRH Rd, [Rn], -Rm
1775 if (busPrefetchCount==0)
1776 busPrefetch = busPrefetchEnable;
1777 int base = (opcode >> 16) & 0x0F;
1778 int dest = (opcode >> 12) & 0x0F;
1779 uint32 address = reg[base].I;
1780 int offset = reg[opcode & 0x0F].I;
1781 clockTicks = 2 + dataTicksAccesint16(address) +
1782 codeTicksAccesint32(armNextPC);
1783 CPUWriteHalfWord(address, reg[dest].W.W0);
1784 address -= offset;
1785 reg[base].I = address;
1786 }
1787 break;
1788 case 0x04b:
1789 case 0x06b:
1790 {
1791 // STRH Rd, [Rn], #-offset
1792 if (busPrefetchCount==0)
1793 busPrefetch = busPrefetchEnable;
1794 int base = (opcode >> 16) & 0x0F;
1795 int dest = (opcode >> 12) & 0x0F;
1796 uint32 address = reg[base].I;
1797 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
1798 clockTicks = 2 + dataTicksAccesint16(address)
1799 + codeTicksAccesint32(armNextPC);
1800 CPUWriteHalfWord(address, reg[dest].W.W0);
1801 address -= offset;
1802 reg[base].I = address;
1803 }
1804 break;
1805 case 0x08b:
1806 case 0x0ab:
1807 {
1808 // STRH Rd, [Rn], Rm
1809 if (busPrefetchCount==0)
1810 busPrefetch = busPrefetchEnable;
1811 int base = (opcode >> 16) & 0x0F;
1812 int dest = (opcode >> 12) & 0x0F;
1813 uint32 address = reg[base].I;
1814 int offset = reg[opcode & 0x0F].I;
1815 clockTicks = 2 + dataTicksAccesint16(address) +
1816 codeTicksAccesint32(armNextPC);
1817 CPUWriteHalfWord(address, reg[dest].W.W0);
1818 address += offset;
1819 reg[base].I = address;
1820 }
1821 break;
1822 case 0x0cb:
1823 case 0x0eb:
1824 {
1825 // STRH Rd, [Rn], #offset
1826 if (busPrefetchCount==0)
1827 busPrefetch = busPrefetchEnable;
1828 int base = (opcode >> 16) & 0x0F;
1829 int dest = (opcode >> 12) & 0x0F;
1830 uint32 address = reg[base].I;
1831 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
1832 clockTicks = 2 + dataTicksAccesint16(address) +
1833 codeTicksAccesint32(armNextPC);
1834 CPUWriteHalfWord(address, reg[dest].W.W0);
1835 address += offset;
1836 reg[base].I = address;
1837 }
1838 break;
1839 case 0x10b:
1840 {
1841 // STRH Rd, [Rn, -Rm]
1842 if (busPrefetchCount==0)
1843 busPrefetch = busPrefetchEnable;
1844 int base = (opcode >> 16) & 0x0F;
1845 int dest = (opcode >> 12) & 0x0F;
1846 uint32 address = reg[base].I - reg[opcode & 0x0F].I;
1847 clockTicks = 2 + dataTicksAccesint16(address) +
1848 codeTicksAccesint32(armNextPC);
1849 CPUWriteHalfWord(address, reg[dest].W.W0);
1850 }
1851 break;
1852 case 0x12b:
1853 {
1854 // STRH Rd, [Rn, -Rm]!
1855 if (busPrefetchCount==0)
1856 busPrefetch = busPrefetchEnable;
1857 int base = (opcode >> 16) & 0x0F;
1858 int dest = (opcode >> 12) & 0x0F;
1859 uint32 address = reg[base].I - reg[opcode & 0x0F].I;
1860 clockTicks = 2 + dataTicksAccesint16(address) +
1861 codeTicksAccesint32(armNextPC);
1862 CPUWriteHalfWord(address, reg[dest].W.W0);
1863 reg[base].I = address;
1864 }
1865 break;
1866 case 0x14b:
1867 {
1868 // STRH Rd, [Rn, -#offset]
1869 if (busPrefetchCount==0)
1870 busPrefetch = busPrefetchEnable;
1871 int base = (opcode >> 16) & 0x0F;
1872 int dest = (opcode >> 12) & 0x0F;
1873 uint32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
1874 clockTicks = 2 + dataTicksAccesint16(address) +
1875 codeTicksAccesint32(armNextPC);
1876 CPUWriteHalfWord(address, reg[dest].W.W0);
1877 }
1878 break;
1879 case 0x16b:
1880 {
1881 // STRH Rd, [Rn, -#offset]!
1882 if (busPrefetchCount==0)
1883 busPrefetch = busPrefetchEnable;
1884 int base = (opcode >> 16) & 0x0F;
1885 int dest = (opcode >> 12) & 0x0F;
1886 uint32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
1887 clockTicks = 2 + dataTicksAccesint16(address) +
1888 codeTicksAccesint32(armNextPC);
1889 CPUWriteHalfWord(address, reg[dest].W.W0);
1890 reg[base].I = address;
1891 }
1892 break;
1893 case 0x18b:
1894 {
1895 // STRH Rd, [Rn, Rm]
1896 if (busPrefetchCount==0)
1897 busPrefetch = busPrefetchEnable;
1898 int base = (opcode >> 16) & 0x0F;
1899 int dest = (opcode >> 12) & 0x0F;
1900 uint32 address = reg[base].I + reg[opcode & 0x0F].I;
1901 clockTicks = 2 + dataTicksAccesint16(address) +
1902 codeTicksAccesint32(armNextPC);
1903 CPUWriteHalfWord(address, reg[dest].W.W0);
1904 }
1905 break;
1906 case 0x1ab:
1907 {
1908 // STRH Rd, [Rn, Rm]!
1909 if (busPrefetchCount==0)
1910 busPrefetch = busPrefetchEnable;
1911 int base = (opcode >> 16) & 0x0F;
1912 int dest = (opcode >> 12) & 0x0F;
1913 uint32 address = reg[base].I + reg[opcode & 0x0F].I;
1914 clockTicks = 2 + dataTicksAccesint16(address) +
1915 codeTicksAccesint32(armNextPC);
1916 CPUWriteHalfWord(address, reg[dest].W.W0);
1917 reg[base].I = address;
1918 }
1919 break;
1920 case 0x1cb:
1921 {
1922 // STRH Rd, [Rn, #offset]
1923 if (busPrefetchCount==0)
1924 busPrefetch = busPrefetchEnable;
1925 int base = (opcode >> 16) & 0x0F;
1926 int dest = (opcode >> 12) & 0x0F;
1927 uint32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
1928 clockTicks = 2 + dataTicksAccesint16(address) +
1929 codeTicksAccesint32(armNextPC);
1930 CPUWriteHalfWord(address, reg[dest].W.W0);
1931 }
1932 break;
1933 case 0x1eb:
1934 {
1935 // STRH Rd, [Rn, #offset]!
1936 if (busPrefetchCount==0)
1937 busPrefetch = busPrefetchEnable;
1938 int base = (opcode >> 16) & 0x0F;
1939 int dest = (opcode >> 12) & 0x0F;
1940 uint32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
1941 clockTicks = 2 + dataTicksAccesint16(address) +
1942 codeTicksAccesint32(armNextPC);
1943 CPUWriteHalfWord(address, reg[dest].W.W0);
1944 reg[base].I = address;
1945 }
1946 break;
1947 case 0x01b:
1948 case 0x03b:
1949 {
1950 // LDRH Rd, [Rn], -Rm
1951 if (busPrefetchCount==0)
1952 busPrefetch = busPrefetchEnable;
1953 int base = (opcode >> 16) & 0x0F;
1954 int dest = (opcode >> 12) & 0x0F;
1955 uint32 address = reg[base].I;
1956 int offset = reg[opcode & 0x0F].I;
1957 reg[dest].I = CPUReadHalfWord(address);
1958 if(dest != base) {
1959 address -= offset;
1960 reg[base].I = address;
1961 }
1962 clockTicks = 0;
1963 if(dest == 15) {
1964 reg[15].I &= 0xFFFFFFFC;
1965 armNextPC = reg[15].I;
1966 reg[15].I += 4;
1967 ARM_PREFETCH;
1968 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
1969 }
1970 clockTicks += 3 + dataTicksAccesint16(address) +
1971 codeTicksAccesint32(armNextPC);
1972 }
1973 break;
1974 case 0x05b:
1975 case 0x07b:
1976 {
1977 // LDRH Rd, [Rn], #-offset
1978 if (busPrefetchCount==0)
1979 busPrefetch = busPrefetchEnable;
1980 int base = (opcode >> 16) & 0x0F;
1981 int dest = (opcode >> 12) & 0x0F;
1982 uint32 address = reg[base].I;
1983 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
1984 reg[dest].I = CPUReadHalfWord(address);
1985 if(dest != base) {
1986 address -= offset;
1987 reg[base].I = address;
1988 }
1989 clockTicks=0;
1990 if(dest == 15) {
1991 reg[15].I &= 0xFFFFFFFC;
1992 armNextPC = reg[15].I;
1993 reg[15].I += 4;
1994 ARM_PREFETCH;
1995 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
1996 }
1997 clockTicks += 3 + dataTicksAccesint16(address) +
1998 codeTicksAccesint32(armNextPC);
1999 }
2000 break;
2001 case 0x09b:
2002 case 0x0bb:
2003 {
2004 // LDRH Rd, [Rn], Rm
2005 if (busPrefetchCount==0)
2006 busPrefetch = busPrefetchEnable;
2007 int base = (opcode >> 16) & 0x0F;
2008 int dest = (opcode >> 12) & 0x0F;
2009 uint32 address = reg[base].I;
2010 int offset = reg[opcode & 0x0F].I;
2011 reg[dest].I = CPUReadHalfWord(address);
2012 if(dest != base) {
2013 address += offset;
2014 reg[base].I = address;
2015 }
2016 clockTicks = 0;
2017 if(dest == 15) {
2018 reg[15].I &= 0xFFFFFFFC;
2019 armNextPC = reg[15].I;
2020 reg[15].I += 4;
2021 ARM_PREFETCH;
2022 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2023 }
2024 clockTicks += 3 + dataTicksAccesint16(address) +
2025 codeTicksAccesint32(armNextPC);
2026 }
2027 break;
2028 case 0x0db:
2029 case 0x0fb:
2030 {
2031 // LDRH Rd, [Rn], #offset
2032 if (busPrefetchCount==0)
2033 busPrefetch = busPrefetchEnable;
2034 int base = (opcode >> 16) & 0x0F;
2035 int dest = (opcode >> 12) & 0x0F;
2036 uint32 address = reg[base].I;
2037 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2038 reg[dest].I = CPUReadHalfWord(address);
2039 if(dest != base) {
2040 address += offset;
2041 reg[base].I = address;
2042 }
2043 clockTicks = 0;
2044 if(dest == 15) {
2045 reg[15].I &= 0xFFFFFFFC;
2046 armNextPC = reg[15].I;
2047 reg[15].I += 4;
2048 ARM_PREFETCH;
2049 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2050 }
2051 clockTicks += 3 + dataTicksAccesint16(address) +
2052 codeTicksAccesint32(armNextPC);
2053 }
2054 break;
2055 case 0x11b:
2056 {
2057 // LDRH Rd, [Rn, -Rm]
2058 if (busPrefetchCount==0)
2059 busPrefetch = busPrefetchEnable;
2060 int base = (opcode >> 16) & 0x0F;
2061 int dest = (opcode >> 12) & 0x0F;
2062 uint32 address = reg[base].I - reg[opcode & 0x0F].I;
2063 reg[dest].I = CPUReadHalfWord(address);
2064 clockTicks = 0;
2065 if(dest == 15) {
2066 reg[15].I &= 0xFFFFFFFC;
2067 armNextPC = reg[15].I;
2068 reg[15].I += 4;
2069 ARM_PREFETCH;
2070 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2071 }
2072 clockTicks += 3 + dataTicksAccesint16(address) +
2073 codeTicksAccesint32(armNextPC);
2074 }
2075 break;
2076 case 0x13b:
2077 {
2078 // LDRH Rd, [Rn, -Rm]!
2079 if (busPrefetchCount==0)
2080 busPrefetch = busPrefetchEnable;
2081 int base = (opcode >> 16) & 0x0F;
2082 int dest = (opcode >> 12) & 0x0F;
2083 uint32 address = reg[base].I - reg[opcode & 0x0F].I;
2084 reg[dest].I = CPUReadHalfWord(address);
2085 if(dest != base)
2086 reg[base].I = address;
2087 clockTicks = 0;
2088 if(dest == 15) {
2089 reg[15].I &= 0xFFFFFFFC;
2090 armNextPC = reg[15].I;
2091 reg[15].I += 4;
2092 ARM_PREFETCH;
2093 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2094 }
2095 clockTicks += 3 + dataTicksAccesint16(address) +
2096 codeTicksAccesint32(armNextPC);
2097 }
2098 break;
2099 case 0x15b:
2100 {
2101 // LDRH Rd, [Rn, -#offset]
2102 if (busPrefetchCount==0)
2103 busPrefetch = busPrefetchEnable;
2104 int base = (opcode >> 16) & 0x0F;
2105 int dest = (opcode >> 12) & 0x0F;
2106 uint32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2107 reg[dest].I = CPUReadHalfWord(address);
2108 clockTicks = 0;
2109 if(dest == 15) {
2110 reg[15].I &= 0xFFFFFFFC;
2111 armNextPC = reg[15].I;
2112 reg[15].I += 4;
2113 ARM_PREFETCH;
2114 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2115 }
2116 clockTicks += 3 + dataTicksAccesint16(address) +
2117 codeTicksAccesint32(armNextPC);
2118 }
2119 break;
2120 case 0x17b:
2121 {
2122 // LDRH Rd, [Rn, -#offset]!
2123 if (busPrefetchCount==0)
2124 busPrefetch = busPrefetchEnable;
2125 int base = (opcode >> 16) & 0x0F;
2126 int dest = (opcode >> 12) & 0x0F;
2127 uint32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2128 reg[dest].I = CPUReadHalfWord(address);
2129 if(dest != base)
2130 reg[base].I = address;
2131 clockTicks = 0;
2132 if(dest == 15) {
2133 reg[15].I &= 0xFFFFFFFC;
2134 armNextPC = reg[15].I;
2135 reg[15].I += 4;
2136 ARM_PREFETCH;
2137 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2138 }
2139 clockTicks += 3 + dataTicksAccesint16(address) +
2140 codeTicksAccesint32(armNextPC);
2141 }
2142 break;
2143 case 0x19b:
2144 {
2145 // LDRH Rd, [Rn, Rm]
2146 if (busPrefetchCount==0)
2147 busPrefetch = busPrefetchEnable;
2148 int base = (opcode >> 16) & 0x0F;
2149 int dest = (opcode >> 12) & 0x0F;
2150 uint32 address = reg[base].I + reg[opcode & 0x0F].I;
2151 reg[dest].I = CPUReadHalfWord(address);
2152 clockTicks = 0;
2153 if(dest == 15) {
2154 reg[15].I &= 0xFFFFFFFC;
2155 armNextPC = reg[15].I;
2156 reg[15].I += 4;
2157 ARM_PREFETCH;
2158 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2159 }
2160 clockTicks += 3 + dataTicksAccesint16(address) +
2161 codeTicksAccesint32(armNextPC);
2162 }
2163 break;
2164 case 0x1bb:
2165 {
2166 // LDRH Rd, [Rn, Rm]!
2167 if (busPrefetchCount==0)
2168 busPrefetch = busPrefetchEnable;
2169 int base = (opcode >> 16) & 0x0F;
2170 int dest = (opcode >> 12) & 0x0F;
2171 uint32 address = reg[base].I + reg[opcode & 0x0F].I;
2172 reg[dest].I = CPUReadHalfWord(address);
2173 if(dest != base)
2174 reg[base].I = address;
2175 clockTicks = 0;
2176 if(dest == 15) {
2177 reg[15].I &= 0xFFFFFFFC;
2178 armNextPC = reg[15].I;
2179 reg[15].I += 4;
2180 ARM_PREFETCH;
2181 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2182 }
2183 clockTicks += 3 + dataTicksAccesint16(address) +
2184 codeTicksAccesint32(armNextPC);
2185 }
2186 break;
2187 case 0x1db:
2188 {
2189 // LDRH Rd, [Rn, #offset]
2190 if (busPrefetchCount==0)
2191 busPrefetch = busPrefetchEnable;
2192 int base = (opcode >> 16) & 0x0F;
2193 int dest = (opcode >> 12) & 0x0F;
2194 uint32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2195 reg[dest].I = CPUReadHalfWord(address);
2196 clockTicks = 0;
2197 if(dest == 15) {
2198 reg[15].I &= 0xFFFFFFFC;
2199 armNextPC = reg[15].I;
2200 reg[15].I += 4;
2201 ARM_PREFETCH;
2202 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2203 }
2204 clockTicks += 3 + dataTicksAccesint16(address) +
2205 codeTicksAccesint32(armNextPC);
2206 }
2207 break;
2208 case 0x1fb:
2209 {
2210 // LDRH Rd, [Rn, #offset]!
2211 if (busPrefetchCount==0)
2212 busPrefetch = busPrefetchEnable;
2213 int base = (opcode >> 16) & 0x0F;
2214 int dest = (opcode >> 12) & 0x0F;
2215 uint32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2216 reg[dest].I = CPUReadHalfWord(address);
2217 if(dest != base)
2218 reg[base].I = address;
2219 clockTicks = 0;
2220 if(dest == 15) {
2221 reg[15].I &= 0xFFFFFFFC;
2222 armNextPC = reg[15].I;
2223 reg[15].I += 4;
2224 ARM_PREFETCH;
2225 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2226 }
2227 clockTicks += 3 + dataTicksAccesint16(address) +
2228 codeTicksAccesint32(armNextPC);
2229 }
2230 break;
2231 case 0x01d:
2232 case 0x03d:
2233 {
2234 // LDRSB Rd, [Rn], -Rm
2235 if (busPrefetchCount==0)
2236 busPrefetch = busPrefetchEnable;
2237 int base = (opcode >> 16) & 0x0F;
2238 int dest = (opcode >> 12) & 0x0F;
2239 uint32 address = reg[base].I;
2240 int offset = reg[opcode & 0x0F].I;
2241 reg[dest].I = (int8)CPUReadByte(address);
2242 if(dest != base) {
2243 address -= offset;
2244 reg[base].I = address;
2245 }
2246 clockTicks = 0;
2247 if(dest == 15) {
2248 reg[15].I &= 0xFFFFFFFC;
2249 armNextPC = reg[15].I;
2250 reg[15].I += 4;
2251 ARM_PREFETCH;
2252 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2253 }
2254 clockTicks += 3 + dataTicksAccesint16(address) +
2255 codeTicksAccesint32(armNextPC);
2256 }
2257 break;
2258 case 0x05d:
2259 case 0x07d:
2260 {
2261 // LDRSB Rd, [Rn], #-offset
2262 if (busPrefetchCount==0)
2263 busPrefetch = busPrefetchEnable;
2264 int base = (opcode >> 16) & 0x0F;
2265 int dest = (opcode >> 12) & 0x0F;
2266 uint32 address = reg[base].I;
2267 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2268 reg[dest].I = (int8)CPUReadByte(address);
2269 if(dest != base) {
2270 address -= offset;
2271 reg[base].I = address;
2272 }
2273 clockTicks = 0;
2274 if(dest == 15) {
2275 reg[15].I &= 0xFFFFFFFC;
2276 armNextPC = reg[15].I;
2277 reg[15].I += 4;
2278 ARM_PREFETCH;
2279 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2280 }
2281 clockTicks += 3 + dataTicksAccesint16(address) +
2282 codeTicksAccesint32(armNextPC);
2283 }
2284 break;
2285 case 0x09d:
2286 case 0x0bd:
2287 {
2288 // LDRSB Rd, [Rn], Rm
2289 if (busPrefetchCount==0)
2290 busPrefetch = busPrefetchEnable;
2291 int base = (opcode >> 16) & 0x0F;
2292 int dest = (opcode >> 12) & 0x0F;
2293 uint32 address = reg[base].I;
2294 int offset = reg[opcode & 0x0F].I;
2295 reg[dest].I = (int8)CPUReadByte(address);
2296 if(dest != base) {
2297 address += offset;
2298 reg[base].I = address;
2299 }
2300 clockTicks = 0;
2301 if(dest == 15) {
2302 reg[15].I &= 0xFFFFFFFC;
2303 armNextPC = reg[15].I;
2304 reg[15].I += 4;
2305 ARM_PREFETCH;
2306 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2307 }
2308 clockTicks += 3 + dataTicksAccesint16(address) +
2309 codeTicksAccesint32(armNextPC);
2310 }
2311 break;
2312 case 0x0dd:
2313 case 0x0fd:
2314 {
2315 // LDRSB Rd, [Rn], #offset
2316 if (busPrefetchCount==0)
2317 busPrefetch = busPrefetchEnable;
2318 int base = (opcode >> 16) & 0x0F;
2319 int dest = (opcode >> 12) & 0x0F;
2320 uint32 address = reg[base].I;
2321 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2322 reg[dest].I = (int8)CPUReadByte(address);
2323 if(dest != base) {
2324 address += offset;
2325 reg[base].I = address;
2326 }
2327 clockTicks = 0;
2328 if(dest == 15) {
2329 reg[15].I &= 0xFFFFFFFC;
2330 armNextPC = reg[15].I;
2331 reg[15].I += 4;
2332 ARM_PREFETCH;
2333 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2334 }
2335 clockTicks += 3 + dataTicksAccesint16(address) +
2336 codeTicksAccesint32(armNextPC);
2337 }
2338 break;
2339 case 0x11d:
2340 {
2341 // LDRSB Rd, [Rn, -Rm]
2342 if (busPrefetchCount==0)
2343 busPrefetch = busPrefetchEnable;
2344 int base = (opcode >> 16) & 0x0F;
2345 int dest = (opcode >> 12) & 0x0F;
2346 uint32 address = reg[base].I - reg[opcode & 0x0F].I;
2347 reg[dest].I = (int8)CPUReadByte(address);
2348 clockTicks = 0;
2349 if(dest == 15) {
2350 reg[15].I &= 0xFFFFFFFC;
2351 armNextPC = reg[15].I;
2352 reg[15].I += 4;
2353 ARM_PREFETCH;
2354 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2355 }
2356 clockTicks += 3 + dataTicksAccesint16(address) +
2357 codeTicksAccesint32(armNextPC);
2358 }
2359 break;
2360 case 0x13d:
2361 {
2362 // LDRSB Rd, [Rn, -Rm]!
2363 if (busPrefetchCount==0)
2364 busPrefetch = busPrefetchEnable;
2365 int base = (opcode >> 16) & 0x0F;
2366 int dest = (opcode >> 12) & 0x0F;
2367 uint32 address = reg[base].I - reg[opcode & 0x0F].I;
2368 reg[dest].I = (int8)CPUReadByte(address);
2369 if(dest != base)
2370 reg[base].I = address;
2371 clockTicks = 0;
2372 if(dest == 15) {
2373 reg[15].I &= 0xFFFFFFFC;
2374 armNextPC = reg[15].I;
2375 reg[15].I += 4;
2376 ARM_PREFETCH;
2377 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2378 }
2379 clockTicks += 3 + dataTicksAccesint16(address) +
2380 codeTicksAccesint32(armNextPC);
2381 }
2382 break;
2383 case 0x15d:
2384 {
2385 // LDRSB Rd, [Rn, -#offset]
2386 if (busPrefetchCount==0)
2387 busPrefetch = busPrefetchEnable;
2388 int base = (opcode >> 16) & 0x0F;
2389 int dest = (opcode >> 12) & 0x0F;
2390 uint32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2391 reg[dest].I = (int8)CPUReadByte(address);
2392 clockTicks = 0;
2393 if(dest == 15) {
2394 reg[15].I &= 0xFFFFFFFC;
2395 armNextPC = reg[15].I;
2396 reg[15].I += 4;
2397 ARM_PREFETCH;
2398 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2399 }
2400 clockTicks += 3 + dataTicksAccesint16(address) +
2401 codeTicksAccesint32(armNextPC);
2402 }
2403 break;
2404 case 0x17d:
2405 {
2406 // LDRSB Rd, [Rn, -#offset]!
2407 if (busPrefetchCount==0)
2408 busPrefetch = busPrefetchEnable;
2409 int base = (opcode >> 16) & 0x0F;
2410 int dest = (opcode >> 12) & 0x0F;
2411 uint32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2412 reg[dest].I = (int8)CPUReadByte(address);
2413 if(dest != base)
2414 reg[base].I = address;
2415 clockTicks = 0;
2416 if(dest == 15) {
2417 reg[15].I &= 0xFFFFFFFC;
2418 armNextPC = reg[15].I;
2419 reg[15].I += 4;
2420 ARM_PREFETCH;
2421 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2422 }
2423 clockTicks += 3 + dataTicksAccesint16(address) +
2424 codeTicksAccesint32(armNextPC);
2425 }
2426 break;
2427 case 0x19d:
2428 {
2429 // LDRSB Rd, [Rn, Rm]
2430 if (busPrefetchCount==0)
2431 busPrefetch = busPrefetchEnable;
2432 int base = (opcode >> 16) & 0x0F;
2433 int dest = (opcode >> 12) & 0x0F;
2434 uint32 address = reg[base].I + reg[opcode & 0x0F].I;
2435 reg[dest].I = (int8)CPUReadByte(address);
2436 clockTicks = 0;
2437 if(dest == 15) {
2438 reg[15].I &= 0xFFFFFFFC;
2439 armNextPC = reg[15].I;
2440 reg[15].I += 4;
2441 ARM_PREFETCH;
2442 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2443 }
2444 clockTicks += 3 + dataTicksAccesint16(address) +
2445 codeTicksAccesint32(armNextPC);
2446 }
2447 break;
2448 case 0x1bd:
2449 {
2450 // LDRSB Rd, [Rn, Rm]!
2451 if (busPrefetchCount==0)
2452 busPrefetch = busPrefetchEnable;
2453 int base = (opcode >> 16) & 0x0F;
2454 int dest = (opcode >> 12) & 0x0F;
2455 uint32 address = reg[base].I + reg[opcode & 0x0F].I;
2456 reg[dest].I = (int8)CPUReadByte(address);
2457 if(dest != base)
2458 reg[base].I = address;
2459 clockTicks = 0;
2460 if(dest == 15) {
2461 reg[15].I &= 0xFFFFFFFC;
2462 armNextPC = reg[15].I;
2463 reg[15].I += 4;
2464 ARM_PREFETCH;
2465 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2466 }
2467 clockTicks += 3 + dataTicksAccesint16(address) +
2468 codeTicksAccesint32(armNextPC);
2469 }
2470 break;
2471 case 0x1dd:
2472 {
2473 // LDRSB Rd, [Rn, #offset]
2474 if (busPrefetchCount==0)
2475 busPrefetch = busPrefetchEnable;
2476 int base = (opcode >> 16) & 0x0F;
2477 int dest = (opcode >> 12) & 0x0F;
2478 uint32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2479 reg[dest].I = (int8)CPUReadByte(address);
2480 clockTicks = 0;
2481 if(dest == 15) {
2482 reg[15].I &= 0xFFFFFFFC;
2483 armNextPC = reg[15].I;
2484 reg[15].I += 4;
2485 ARM_PREFETCH;
2486 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2487 }
2488 clockTicks += 3 + dataTicksAccesint16(address) +
2489 codeTicksAccesint32(armNextPC);
2490 }
2491 break;
2492 case 0x1fd:
2493 {
2494 // LDRSB Rd, [Rn, #offset]!
2495 if (busPrefetchCount==0)
2496 busPrefetch = busPrefetchEnable;
2497 int base = (opcode >> 16) & 0x0F;
2498 int dest = (opcode >> 12) & 0x0F;
2499 uint32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2500 reg[dest].I = (int8)CPUReadByte(address);
2501 if(dest != base)
2502 reg[base].I = address;
2503 clockTicks = 0;
2504 if(dest == 15) {
2505 reg[15].I &= 0xFFFFFFFC;
2506 armNextPC = reg[15].I;
2507 reg[15].I += 4;
2508 ARM_PREFETCH;
2509 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2510 }
2511 clockTicks += 3 + dataTicksAccesint16(address) +
2512 codeTicksAccesint32(armNextPC);
2513 }
2514 break;
2515 case 0x01f:
2516 case 0x03f:
2517 {
2518 // LDRSH Rd, [Rn], -Rm
2519 if (busPrefetchCount==0)
2520 busPrefetch = busPrefetchEnable;
2521 int base = (opcode >> 16) & 0x0F;
2522 int dest = (opcode >> 12) & 0x0F;
2523 uint32 address = reg[base].I;
2524 int offset = reg[opcode & 0x0F].I;
2525 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2526 if(dest != base) {
2527 address -= offset;
2528 reg[base].I = address;
2529 }
2530 clockTicks = 0;
2531 if(dest == 15) {
2532 reg[15].I &= 0xFFFFFFFC;
2533 armNextPC = reg[15].I;
2534 reg[15].I += 4;
2535 ARM_PREFETCH;
2536 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2537 }
2538 clockTicks += 3 + dataTicksAccesint16(address) +
2539 codeTicksAccesint32(armNextPC);
2540 }
2541 break;
2542 case 0x05f:
2543 case 0x07f:
2544 {
2545 // LDRSH Rd, [Rn], #-offset
2546 if (busPrefetchCount==0)
2547 busPrefetch = busPrefetchEnable;
2548 int base = (opcode >> 16) & 0x0F;
2549 int dest = (opcode >> 12) & 0x0F;
2550 uint32 address = reg[base].I;
2551 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2552 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2553 if(dest != base) {
2554 address -= offset;
2555 reg[base].I = address;
2556 }
2557 clockTicks = 0;
2558 if(dest == 15) {
2559 reg[15].I &= 0xFFFFFFFC;
2560 armNextPC = reg[15].I;
2561 reg[15].I += 4;
2562 ARM_PREFETCH;
2563 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2564 }
2565 clockTicks += 3 + dataTicksAccesint16(address) +
2566 codeTicksAccesint32(armNextPC);
2567 }
2568 break;
2569 case 0x09f:
2570 case 0x0bf:
2571 {
2572 // LDRSH Rd, [Rn], Rm
2573 if (busPrefetchCount==0)
2574 busPrefetch = busPrefetchEnable;
2575 int base = (opcode >> 16) & 0x0F;
2576 int dest = (opcode >> 12) & 0x0F;
2577 uint32 address = reg[base].I;
2578 int offset = reg[opcode & 0x0F].I;
2579 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2580 if(dest != base) {
2581 address += offset;
2582 reg[base].I = address;
2583 }
2584 clockTicks = 0;
2585 if(dest == 15) {
2586 reg[15].I &= 0xFFFFFFFC;
2587 armNextPC = reg[15].I;
2588 reg[15].I += 4;
2589 ARM_PREFETCH;
2590 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2591 }
2592 clockTicks += 3 + dataTicksAccesint16(address) +
2593 codeTicksAccesint32(armNextPC);
2594 }
2595 break;
2596 case 0x0df:
2597 case 0x0ff:
2598 {
2599 // LDRSH Rd, [Rn], #offset
2600 if (busPrefetchCount==0)
2601 busPrefetch = busPrefetchEnable;
2602 int base = (opcode >> 16) & 0x0F;
2603 int dest = (opcode >> 12) & 0x0F;
2604 uint32 address = reg[base].I;
2605 int offset = (opcode & 0x0F) | ((opcode >> 4) & 0xF0);
2606 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2607 if(dest != base) {
2608 address += offset;
2609 reg[base].I = address;
2610 }
2611 clockTicks = 0;
2612 if(dest == 15) {
2613 reg[15].I &= 0xFFFFFFFC;
2614 armNextPC = reg[15].I;
2615 reg[15].I += 4;
2616 ARM_PREFETCH;
2617 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2618 }
2619 clockTicks += 3 + dataTicksAccesint16(address) +
2620 codeTicksAccesint32(armNextPC);
2621 }
2622 break;
2623 case 0x11f:
2624 {
2625 // LDRSH Rd, [Rn, -Rm]
2626 if (busPrefetchCount==0)
2627 busPrefetch = busPrefetchEnable;
2628 int base = (opcode >> 16) & 0x0F;
2629 int dest = (opcode >> 12) & 0x0F;
2630 uint32 address = reg[base].I - reg[opcode & 0x0F].I;
2631 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2632 clockTicks = 0;
2633 if(dest == 15) {
2634 reg[15].I &= 0xFFFFFFFC;
2635 armNextPC = reg[15].I;
2636 reg[15].I += 4;
2637 ARM_PREFETCH;
2638 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2639 }
2640 clockTicks += 3 + dataTicksAccesint16(address) +
2641 codeTicksAccesint32(armNextPC);
2642 }
2643 break;
2644 case 0x13f:
2645 {
2646 // LDRSH Rd, [Rn, -Rm]!
2647 if (busPrefetchCount==0)
2648 busPrefetch = busPrefetchEnable;
2649 int base = (opcode >> 16) & 0x0F;
2650 int dest = (opcode >> 12) & 0x0F;
2651 uint32 address = reg[base].I - reg[opcode & 0x0F].I;
2652 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2653 if(dest != base)
2654 reg[base].I = address;
2655 clockTicks = 0;
2656 if(dest == 15) {
2657 reg[15].I &= 0xFFFFFFFC;
2658 armNextPC = reg[15].I;
2659 reg[15].I += 4;
2660 ARM_PREFETCH;
2661 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2662 }
2663 clockTicks += 3 + dataTicksAccesint16(address) +
2664 codeTicksAccesint32(armNextPC);
2665 }
2666 break;
2667 case 0x15f:
2668 {
2669 // LDRSH Rd, [Rn, -#offset]
2670 if (busPrefetchCount==0)
2671 busPrefetch = busPrefetchEnable;
2672 int base = (opcode >> 16) & 0x0F;
2673 int dest = (opcode >> 12) & 0x0F;
2674 uint32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2675 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2676 clockTicks = 0;
2677 if(dest == 15) {
2678 reg[15].I &= 0xFFFFFFFC;
2679 armNextPC = reg[15].I;
2680 reg[15].I += 4;
2681 ARM_PREFETCH;
2682 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2683 }
2684 clockTicks += 3 + dataTicksAccesint16(address) +
2685 codeTicksAccesint32(armNextPC);
2686 }
2687 break;
2688 case 0x17f:
2689 {
2690 // LDRSH Rd, [Rn, -#offset]!
2691 if (busPrefetchCount==0)
2692 busPrefetch = busPrefetchEnable;
2693 int base = (opcode >> 16) & 0x0F;
2694 int dest = (opcode >> 12) & 0x0F;
2695 uint32 address = reg[base].I - ((opcode & 0x0F)|((opcode>>4)&0xF0));
2696 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2697 if(dest != base)
2698 reg[base].I = address;
2699 clockTicks = 0;
2700 if(dest == 15) {
2701 reg[15].I &= 0xFFFFFFFC;
2702 armNextPC = reg[15].I;
2703 reg[15].I += 4;
2704 ARM_PREFETCH;
2705 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2706 }
2707 clockTicks += 3 + dataTicksAccesint16(address) +
2708 codeTicksAccesint32(armNextPC);
2709 }
2710 break;
2711 case 0x19f:
2712 {
2713 // LDRSH Rd, [Rn, Rm]
2714 if (busPrefetchCount==0)
2715 busPrefetch = busPrefetchEnable;
2716 int base = (opcode >> 16) & 0x0F;
2717 int dest = (opcode >> 12) & 0x0F;
2718 uint32 address = reg[base].I + reg[opcode & 0x0F].I;
2719 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2720 clockTicks = 0;
2721 if(dest == 15) {
2722 reg[15].I &= 0xFFFFFFFC;
2723 armNextPC = reg[15].I;
2724 reg[15].I += 4;
2725 ARM_PREFETCH;
2726 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2727 }
2728 clockTicks += 3 + dataTicksAccesint16(address) +
2729 codeTicksAccesint32(armNextPC);
2730 }
2731 break;
2732 case 0x1bf:
2733 {
2734 // LDRSH Rd, [Rn, Rm]!
2735 if (busPrefetchCount==0)
2736 busPrefetch = busPrefetchEnable;
2737 int base = (opcode >> 16) & 0x0F;
2738 int dest = (opcode >> 12) & 0x0F;
2739 uint32 address = reg[base].I + reg[opcode & 0x0F].I;
2740 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2741 if(dest != base)
2742 reg[base].I = address;
2743 clockTicks = 0;
2744 if(dest == 15) {
2745 reg[15].I &= 0xFFFFFFFC;
2746 armNextPC = reg[15].I;
2747 reg[15].I += 4;
2748 ARM_PREFETCH;
2749 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2750 }
2751 clockTicks += 3 + dataTicksAccesint16(address) +
2752 codeTicksAccesint32(armNextPC);
2753 }
2754 break;
2755 case 0x1df:
2756 {
2757 // LDRSH Rd, [Rn, #offset]
2758 if (busPrefetchCount==0)
2759 busPrefetch = busPrefetchEnable;
2760 int base = (opcode >> 16) & 0x0F;
2761 int dest = (opcode >> 12) & 0x0F;
2762 uint32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2763 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2764 clockTicks = 0;
2765 if(dest == 15) {
2766 reg[15].I &= 0xFFFFFFFC;
2767 armNextPC = reg[15].I;
2768 reg[15].I += 4;
2769 ARM_PREFETCH;
2770 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2771 }
2772 clockTicks += 3 + dataTicksAccesint16(address) +
2773 codeTicksAccesint32(armNextPC);
2774 }
2775 break;
2776 case 0x1ff:
2777 {
2778 // LDRSH Rd, [Rn, #offset]!
2779 if (busPrefetchCount==0)
2780 busPrefetch = busPrefetchEnable;
2781 int base = (opcode >> 16) & 0x0F;
2782 int dest = (opcode >> 12) & 0x0F;
2783 uint32 address = reg[base].I + ((opcode & 0x0F)|((opcode>>4)&0xF0));
2784 reg[dest].I = (int16)CPUReadHalfWordSigned(address);
2785 if(dest != base)
2786 reg[base].I = address;
2787 clockTicks = 0;
2788 if(dest == 15) {
2789 reg[15].I &= 0xFFFFFFFC;
2790 armNextPC = reg[15].I;
2791 reg[15].I += 4;
2792 ARM_PREFETCH;
2793 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
2794 }
2795 clockTicks += 3 + dataTicksAccesint16(address) +
2796 codeTicksAccesint32(armNextPC);
2797 }
2798 break;
2799 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EOR, OP_EOR, 0x020);
2800 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_EORS, OP_EOR, 0x030);
2801 case 0x029:
2802 {
2803 // MLA Rd, Rm, Rs, Rn
2804 clockTicks = 2;
2805 int dest = (opcode >> 16) & 0x0F;
2806 int mult = (opcode & 0x0F);
2807 uint32 rs = reg[(opcode >> 8) & 0x0F].I;
2808 reg[dest].I = reg[mult].I * rs + reg[(opcode>>12)&0x0f].I;
2809 if((rs & 0xFFFFFF00) == 0)
2810 clockTicks += 0;
2811 else if ((rs & 0xFFFF0000) == 0)
2812 clockTicks += 1;
2813 else if ((rs & 0xFF000000) == 0)
2814 clockTicks += 2;
2815 else
2816 clockTicks += 3;
2817 if (busPrefetchCount==0)
2818 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
2819 clockTicks += codeTicksAccesint32(armNextPC) + 1;
2820 }
2821 break;
2822 case 0x039:
2823 {
2824 // MLAS Rd, Rm, Rs, Rn
2825 clockTicks = 2;
2826 int dest = (opcode >> 16) & 0x0F;
2827 int mult = (opcode & 0x0F);
2828 uint32 rs = reg[(opcode >> 8) & 0x0F].I;
2829 reg[dest].I = reg[mult].I * rs + reg[(opcode>>12)&0x0f].I;
2830 N_FLAG = (reg[dest].I & 0x80000000) ? true : false;
2831 Z_FLAG = (reg[dest].I) ? false : true;
2832 if(((int32)rs)<0)
2833 rs = ~rs;
2834 if((rs & 0xFFFFFF00) == 0)
2835 clockTicks += 0;
2836 else if ((rs & 0xFFFF0000) == 0)
2837 clockTicks += 1;
2838 else if ((rs & 0xFF000000) == 0)
2839 clockTicks += 2;
2840 else
2841 clockTicks += 3;
2842 if (busPrefetchCount==0)
2843 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
2844 clockTicks += codeTicksAccesint32(armNextPC) + 1;
2845 }
2846 break;
2847 ARITHMETIC_DATA_OPCODE(OP_SUB, OP_SUB, 0x040);
2848 ARITHMETIC_DATA_OPCODE(OP_SUBS, OP_SUB, 0x050);
2849 ARITHMETIC_DATA_OPCODE(OP_RSB, OP_RSB, 0x060);
2850 ARITHMETIC_DATA_OPCODE(OP_RSBS, OP_RSB, 0x070);
2851 ARITHMETIC_DATA_OPCODE(OP_ADD, OP_ADD, 0x080);
2852 ARITHMETIC_DATA_OPCODE(OP_ADDS, OP_ADD, 0x090);
2853 case 0x089:
2854 {
2855 // UMULL RdLo, RdHi, Rn, Rs
2856 clockTicks = 2;
2857 uint32 umult = reg[(opcode & 0x0F)].I;
2858 uint32 usource = reg[(opcode >> 8) & 0x0F].I;
2859 int destLo = (opcode >> 12) & 0x0F;
2860 int destHi = (opcode >> 16) & 0x0F;
2861 uint64 uTemp = ((uint64)umult)*((uint64)usource);
2862 reg[destLo].I = (uint32)uTemp;
2863 reg[destHi].I = (uint32)(uTemp >> 32);
2864 if ((usource & 0xFFFFFF00) == 0)
2865 clockTicks += 0;
2866 else if ((usource & 0xFFFF0000) == 0)
2867 clockTicks += 1;
2868 else if ((usource & 0xFF000000) == 0)
2869 clockTicks += 2;
2870 else
2871 clockTicks += 3;
2872 if (busPrefetchCount==0)
2873 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
2874 clockTicks += codeTicksAccesint32(armNextPC) + 1;
2875 }
2876 break;
2877 case 0x099:
2878 {
2879 // UMULLS RdLo, RdHi, Rn, Rs
2880 clockTicks = 2;
2881 uint32 umult = reg[(opcode & 0x0F)].I;
2882 uint32 usource = reg[(opcode >> 8) & 0x0F].I;
2883 int destLo = (opcode >> 12) & 0x0F;
2884 int destHi = (opcode >> 16) & 0x0F;
2885 uint64 uTemp = ((uint64)umult)*((uint64)usource);
2886 reg[destLo].I = (uint32)uTemp;
2887 reg[destHi].I = (uint32)(uTemp >> 32);
2888 Z_FLAG = (uTemp) ? false : true;
2889 N_FLAG = (reg[destHi].I & 0x80000000) ? true : false;
2890 if ((usource & 0xFFFFFF00) == 0)
2891 clockTicks += 0;
2892 else if ((usource & 0xFFFF0000) == 0)
2893 clockTicks += 1;
2894 else if ((usource & 0xFF000000) == 0)
2895 clockTicks += 2;
2896 else
2897 clockTicks += 3;
2898 if (busPrefetchCount==0)
2899 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
2900 clockTicks += codeTicksAccesint32(armNextPC) + 1;
2901 }
2902 break;
2903 ARITHMETIC_DATA_OPCODE(OP_ADC, OP_ADC, 0x0a0);
2904 ARITHMETIC_DATA_OPCODE(OP_ADCS, OP_ADC, 0x0b0);
2905 case 0x0a9:
2906 {
2907 // UMLAL RdLo, RdHi, Rn, Rs
2908 clockTicks = 3;
2909 uint32 umult = reg[(opcode & 0x0F)].I;
2910 uint32 usource = reg[(opcode >> 8) & 0x0F].I;
2911 int destLo = (opcode >> 12) & 0x0F;
2912 int destHi = (opcode >> 16) & 0x0F;
2913 uint64 uTemp = (uint64)reg[destHi].I;
2914 uTemp <<= 32;
2915 uTemp |= (uint64)reg[destLo].I;
2916 uTemp += ((uint64)umult)*((uint64)usource);
2917 reg[destLo].I = (uint32)uTemp;
2918 reg[destHi].I = (uint32)(uTemp >> 32);
2919 if ((usource & 0xFFFFFF00) == 0)
2920 clockTicks += 0;
2921 else if ((usource & 0xFFFF0000) == 0)
2922 clockTicks += 1;
2923 else if ((usource & 0xFF000000) == 0)
2924 clockTicks += 2;
2925 else
2926 clockTicks += 3;
2927 if (busPrefetchCount==0)
2928 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
2929 clockTicks += codeTicksAccesint32(armNextPC) + 1;
2930 }
2931 break;
2932 case 0x0b9:
2933 {
2934 // UMLALS RdLo, RdHi, Rn, Rs
2935 clockTicks = 3;
2936 uint32 umult = reg[(opcode & 0x0F)].I;
2937 uint32 usource = reg[(opcode >> 8) & 0x0F].I;
2938 int destLo = (opcode >> 12) & 0x0F;
2939 int destHi = (opcode >> 16) & 0x0F;
2940 uint64 uTemp = (uint64)reg[destHi].I;
2941 uTemp <<= 32;
2942 uTemp |= (uint64)reg[destLo].I;
2943 uTemp += ((uint64)umult)*((uint64)usource);
2944 reg[destLo].I = (uint32)uTemp;
2945 reg[destHi].I = (uint32)(uTemp >> 32);
2946 Z_FLAG = (uTemp) ? false : true;
2947 N_FLAG = (reg[destHi].I & 0x80000000) ? true : false;
2948 if ((usource & 0xFFFFFF00) == 0)
2949 clockTicks += 0;
2950 else if ((usource & 0xFFFF0000) == 0)
2951 clockTicks += 1;
2952 else if ((usource & 0xFF000000) == 0)
2953 clockTicks += 2;
2954 else
2955 clockTicks += 3;
2956 if (busPrefetchCount==0)
2957 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
2958 clockTicks += codeTicksAccesint32(armNextPC) + 1;
2959 }
2960 break;
2961 ARITHMETIC_DATA_OPCODE(OP_SBC, OP_SBC, 0x0c0);
2962 ARITHMETIC_DATA_OPCODE(OP_SBCS, OP_SBC, 0x0d0);
2963 case 0x0c9:
2964 {
2965 // SMULL RdLo, RdHi, Rm, Rs
2966 clockTicks = 2;
2967 int destLo = (opcode >> 12) & 0x0F;
2968 int destHi = (opcode >> 16) & 0x0F;
2969 uint32 rs = reg[(opcode >> 8) & 0x0F].I;
2970 int64 m = (int32)reg[(opcode & 0x0F)].I;
2971 int64 s = (int32)rs;
2972 int64 sTemp = m*s;
2973 reg[destLo].I = (uint32)sTemp;
2974 reg[destHi].I = (uint32)(sTemp >> 32);
2975 if(((int32)rs) < 0)
2976 rs = ~rs;
2977 if((rs & 0xFFFFFF00) == 0)
2978 clockTicks += 0;
2979 else if((rs & 0xFFFF0000) == 0)
2980 clockTicks += 1;
2981 else if((rs & 0xFF000000) == 0)
2982 clockTicks += 2;
2983 else
2984 clockTicks += 3;
2985 if (busPrefetchCount==0)
2986 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
2987 clockTicks += codeTicksAccesint32(armNextPC) + 1;
2988 }
2989 break;
2990 case 0x0d9:
2991 {
2992 // SMULLS RdLo, RdHi, Rm, Rs
2993 clockTicks = 2;
2994 int destLo = (opcode >> 12) & 0x0F;
2995 int destHi = (opcode >> 16) & 0x0F;
2996 uint32 rs = reg[(opcode >> 8) & 0x0F].I;
2997 int64 m = (int32)reg[(opcode & 0x0F)].I;
2998 int64 s = (int32)rs;
2999 int64 sTemp = m*s;
3000 reg[destLo].I = (uint32)sTemp;
3001 reg[destHi].I = (uint32)(sTemp >> 32);
3002 Z_FLAG = (sTemp) ? false : true;
3003 N_FLAG = (sTemp < 0) ? true : false;
3004 if(((int32)rs) < 0)
3005 rs = ~rs;
3006 if((rs & 0xFFFFFF00) == 0)
3007 clockTicks += 0;
3008 else if((rs & 0xFFFF0000) == 0)
3009 clockTicks += 1;
3010 else if((rs & 0xFF000000) == 0)
3011 clockTicks += 2;
3012 else
3013 clockTicks += 3;
3014 if (busPrefetchCount==0)
3015 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
3016 clockTicks += codeTicksAccesint32(armNextPC) + 1;
3017 }
3018 break;
3019 ARITHMETIC_DATA_OPCODE(OP_RSC, OP_RSC, 0x0e0);
3020 ARITHMETIC_DATA_OPCODE(OP_RSCS, OP_RSC, 0x0f0);
3021 case 0x0e9:
3022 {
3023 // SMLAL RdLo, RdHi, Rm, Rs
3024 clockTicks = codeTicksAccesint32(armNextPC) + 4;
3025 int destLo = (opcode >> 12) & 0x0F;
3026 int destHi = (opcode >> 16) & 0x0F;
3027 uint32 rs = reg[(opcode >> 8) & 0x0F].I;
3028 int64 m = (int32)reg[(opcode & 0x0F)].I;
3029 int64 s = (int32)rs;
3030 int64 sTemp = (uint64)reg[destHi].I;
3031 sTemp <<= 32;
3032 sTemp |= (uint64)reg[destLo].I;
3033 sTemp += m*s;
3034 reg[destLo].I = (uint32)sTemp;
3035 reg[destHi].I = (uint32)(sTemp >> 32);
3036 if(((int32)rs) < 0)
3037 rs = ~rs;
3038 if((rs & 0xFFFFFF00) == 0)
3039 clockTicks += 0;
3040 else if((rs & 0xFFFF0000) == 0)
3041 clockTicks += 1;
3042 else if((rs & 0xFF000000) == 0)
3043 clockTicks += 2;
3044 else
3045 clockTicks += 3;
3046 if (busPrefetchCount==0)
3047 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
3048 }
3049 break;
3050 case 0x0f9:
3051 {
3052 // SMLALS RdLo, RdHi, Rm, Rs
3053 clockTicks = codeTicksAccesint32(armNextPC) + 4;
3054 int destLo = (opcode >> 12) & 0x0F;
3055 int destHi = (opcode >> 16) & 0x0F;
3056 uint32 rs = reg[(opcode >> 8) & 0x0F].I;
3057 int64 m = (int32)reg[(opcode & 0x0F)].I;
3058 int64 s = (int32)rs;
3059 int64 sTemp = (uint64)reg[destHi].I;
3060 sTemp <<= 32;
3061 sTemp |= (uint64)reg[destLo].I;
3062 sTemp += m*s;
3063 reg[destLo].I = (uint32)sTemp;
3064 reg[destHi].I = (uint32)(sTemp >> 32);
3065 Z_FLAG = (sTemp) ? false : true;
3066 N_FLAG = (sTemp < 0) ? true : false;
3067 if(((int32)rs) < 0)
3068 rs = ~rs;
3069 if((rs & 0xFFFFFF00) == 0)
3070 clockTicks += 0;
3071 else if((rs & 0xFFFF0000) == 0)
3072 clockTicks += 1;
3073 else if((rs & 0xFF000000) == 0)
3074 clockTicks += 2;
3075 else
3076 clockTicks += 3;
3077 if (busPrefetchCount==0)
3078 busPrefetchCount = (busPrefetchCount<<clockTicks) | (0xFF>>(8-clockTicks));
3079 }
3080 break;
3081 LOGICAL_DATA_OPCODE(OP_TST, OP_TST, 0x110);
3082 case 0x100:
3083 // MRS Rd, CPSR
3084 // TODO: check if right instruction....
3085 CPUUpdateCPSR();
3086 reg[(opcode >> 12) & 0x0F].I = reg[16].I;
3087 break;
3088 case 0x109:
3089 {
3090 // SWP Rd, Rm, [Rn]
3091 uint32 address = reg[(opcode >> 16) & 15].I;
3092 uint32 temp = CPUReadMemory(address);
3093 CPUWriteMemory(address, reg[opcode&15].I);
3094 reg[(opcode >> 12) & 15].I = temp;
3095 clockTicks = 4 + dataTicksAccesint32(address) + dataTicksAccesint32(address) +
3096 codeTicksAccesint32(armNextPC);
3097 }
3098 break;
3099 LOGICAL_DATA_OPCODE(OP_TEQ, OP_TEQ, 0x130);
3100 case 0x120:
3101 {
3102 // MSR CPSR_fields, Rm
3103 CPUUpdateCPSR();
3104 uint32 value = reg[opcode & 15].I;
3105 uint32 newValue = reg[16].I;
3106 if(armMode > 0x10) {
3107 if(opcode & 0x00010000)
3108 newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
3109 if(opcode & 0x00020000)
3110 newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
3111 if(opcode & 0x00040000)
3112 newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
3113 }
3114 if(opcode & 0x00080000)
3115 newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
3116 newValue |= 0x10;
3117 CPUSwitchMode(newValue & 0x1f, false);
3118 reg[16].I = newValue;
3119 CPUUpdateFlags();
3120 if(!armState) { // this should not be allowed, but it seems to work
3121 THUMB_PREFETCH;
3122 reg[15].I = armNextPC + 2;
3123 }
3124 }
3125 break;
3126 case 0x121:
3127 {
3128 // BX Rm
3129 // TODO: check if right instruction...
3130 int base = opcode & 0x0F;
3131 busPrefetchCount=0;
3132 armState = reg[base].I & 1 ? false : true;
3133 if(armState) {
3134 reg[15].I = reg[base].I & 0xFFFFFFFC;
3135 armNextPC = reg[15].I;
3136 reg[15].I += 4;
3137 ARM_PREFETCH;
3138 clockTicks = codeTicksAccessSeq32(armNextPC) +
3139 codeTicksAccessSeq32(armNextPC) + codeTicksAccesint32(armNextPC) + 3;
3140 } else {
3141 reg[15].I = reg[base].I & 0xFFFFFFFE;
3142 armNextPC = reg[15].I;
3143 reg[15].I += 2;
3144 THUMB_PREFETCH;
3145 clockTicks = codeTicksAccessSeq16(armNextPC) +
3146 codeTicksAccessSeq16(armNextPC) + codeTicksAccesint16(armNextPC) + 3;
3147 }
3148 }
3149 break;
3150 ARITHMETIC_DATA_OPCODE(OP_CMP, OP_CMP, 0x150);
3151 case 0x140:
3152 // MRS Rd, SPSR
3153 // TODO: check if right instruction...
3154 reg[(opcode >> 12) & 0x0F].I = reg[17].I;
3155 break;
3156 case 0x149:
3157 {
3158 // SWPB Rd, Rm, [Rn]
3159 uint32 address = reg[(opcode >> 16) & 15].I;
3160 uint32 temp = CPUReadByte(address);
3161 CPUWriteByte(address, reg[opcode&15].B.B0);
3162 reg[(opcode>>12)&15].I = temp;
3163 clockTicks = 4 + dataTicksAccesint32(address) + dataTicksAccesint32(address) +
3164 codeTicksAccesint32(armNextPC);
3165 }
3166 break;
3167 ARITHMETIC_DATA_OPCODE(OP_CMN, OP_CMN, 0x170);
3168 case 0x160:
3169 {
3170 // MSR SPSR_fields, Rm
3171 uint32 value = reg[opcode & 15].I;
3172 if(armMode > 0x10 && armMode < 0x1f) {
3173 if(opcode & 0x00010000)
3174 reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
3175 if(opcode & 0x00020000)
3176 reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
3177 if(opcode & 0x00040000)
3178 reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
3179 if(opcode & 0x00080000)
3180 reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
3181 }
3182 }
3183 break;
3184 LOGICAL_DATA_OPCODE (OP_ORR, OP_ORR, 0x180);
3185 LOGICAL_DATA_OPCODE (OP_ORRS, OP_ORR, 0x190);
3186 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOV, OP_MOV, 0x1a0);
3187 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MOVS, OP_MOV, 0x1b0);
3188 LOGICAL_DATA_OPCODE (OP_BIC, OP_BIC, 0x1c0);
3189 LOGICAL_DATA_OPCODE (OP_BICS, OP_BIC, 0x1d0);
3190 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVN, OP_MVN, 0x1e0);
3191 LOGICAL_DATA_OPCODE_WITHOUT_base(OP_MVNS, OP_MVN, 0x1f0);
3192 #ifdef BKPT_SUPPORT
3193 case 0x127:
3194 case 0x7ff: // for GDB support
3195 extern void (*dbgSignal)(int,int);
3196 reg[15].I -= 4;
3197 armNextPC -= 4;
3198 dbgSignal(5, (opcode & 0x0f)|((opcode>>4) & 0xfff0));
3199 return;
3200 #endif
3201 case 0x320:
3202 case 0x321:
3203 case 0x322:
3204 case 0x323:
3205 case 0x324:
3206 case 0x325:
3207 case 0x326:
3208 case 0x327:
3209 case 0x328:
3210 case 0x329:
3211 case 0x32a:
3212 case 0x32b:
3213 case 0x32c:
3214 case 0x32d:
3215 case 0x32e:
3216 case 0x32f:
3217 {
3218 // MSR CPSR_fields, #
3219 CPUUpdateCPSR();
3220 uint32 value = opcode & 0xFF;
3221 int shift = (opcode & 0xF00) >> 7;
3222 if(shift) {
3223 ROR_IMM_MSR;
3224 }
3225 uint32 newValue = reg[16].I;
3226 if(armMode > 0x10) {
3227 if(opcode & 0x00010000)
3228 newValue = (newValue & 0xFFFFFF00) | (value & 0x000000FF);
3229 if(opcode & 0x00020000)
3230 newValue = (newValue & 0xFFFF00FF) | (value & 0x0000FF00);
3231 if(opcode & 0x00040000)
3232 newValue = (newValue & 0xFF00FFFF) | (value & 0x00FF0000);
3233 }
3234 if(opcode & 0x00080000)
3235 newValue = (newValue & 0x00FFFFFF) | (value & 0xFF000000);
3236
3237 newValue |= 0x10;
3238
3239 CPUSwitchMode(newValue & 0x1f, false);
3240 reg[16].I = newValue;
3241 CPUUpdateFlags();
3242 if(!armState) { // this should not be allowed, but it seems to work
3243 THUMB_PREFETCH;
3244 reg[15].I = armNextPC + 2;
3245 }
3246 }
3247 break;
3248 case 0x360:
3249 case 0x361:
3250 case 0x362:
3251 case 0x363:
3252 case 0x364:
3253 case 0x365:
3254 case 0x366:
3255 case 0x367:
3256 case 0x368:
3257 case 0x369:
3258 case 0x36a:
3259 case 0x36b:
3260 case 0x36c:
3261 case 0x36d:
3262 case 0x36e:
3263 case 0x36f:
3264 {
3265 // MSR SPSR_fields, #
3266 if(armMode > 0x10 && armMode < 0x1f) {
3267 uint32 value = opcode & 0xFF;
3268 int shift = (opcode & 0xF00) >> 7;
3269 if(shift) {
3270 ROR_IMM_MSR;
3271 }
3272 if(opcode & 0x00010000)
3273 reg[17].I = (reg[17].I & 0xFFFFFF00) | (value & 0x000000FF);
3274 if(opcode & 0x00020000)
3275 reg[17].I = (reg[17].I & 0xFFFF00FF) | (value & 0x0000FF00);
3276 if(opcode & 0x00040000)
3277 reg[17].I = (reg[17].I & 0xFF00FFFF) | (value & 0x00FF0000);
3278 if(opcode & 0x00080000)
3279 reg[17].I = (reg[17].I & 0x00FFFFFF) | (value & 0xFF000000);
3280 }
3281 }
3282 break;
3283 CASE_16(0x400)
3284 // T versions shouldn't be different on GBA
3285 CASE_16(0x420)
3286 {
3287 // STR Rd, [Rn], -#
3288 if (busPrefetchCount==0)
3289 busPrefetch = busPrefetchEnable;
3290 int offset = opcode & 0xFFF;
3291 int dest = (opcode >> 12) & 15;
3292 int base = (opcode >> 16) & 15;
3293 uint32 address = reg[base].I;
3294 CPUWriteMemory(address, reg[dest].I);
3295 reg[base].I = address - offset;
3296 clockTicks = 2 + dataTicksAccesint32(address) +
3297 codeTicksAccesint32(armNextPC);
3298 }
3299 break;
3300 CASE_16(0x480)
3301 // T versions shouldn't be different on GBA
3302 CASE_16(0x4a0)
3303 {
3304 // STR Rd, [Rn], #
3305 if (busPrefetchCount==0)
3306 busPrefetch = busPrefetchEnable;
3307 int offset = opcode & 0xFFF;
3308 int dest = (opcode >> 12) & 15;
3309 int base = (opcode >> 16) & 15;
3310 uint32 address = reg[base].I;
3311 CPUWriteMemory(address, reg[dest].I);
3312 reg[base].I = address + offset;
3313 clockTicks = 2 + dataTicksAccesint32(address) +
3314 codeTicksAccesint32(armNextPC);
3315 }
3316 break;
3317 CASE_16(0x500)
3318 {
3319 // STR Rd, [Rn, -#]
3320 if (busPrefetchCount==0)
3321 busPrefetch = busPrefetchEnable;
3322 int offset = opcode & 0xFFF;
3323 int dest = (opcode >> 12) & 15;
3324 int base = (opcode >> 16) & 15;
3325 uint32 address = reg[base].I - offset;
3326 CPUWriteMemory(address, reg[dest].I);
3327 clockTicks = 2 + dataTicksAccesint32(address) +
3328 codeTicksAccesint32(armNextPC);
3329 }
3330 break;
3331 CASE_16(0x520)
3332 {
3333 // STR Rd, [Rn, -#]!
3334 if (busPrefetchCount==0)
3335 busPrefetch = busPrefetchEnable;
3336 int offset = opcode & 0xFFF;
3337 int dest = (opcode >> 12) & 15;
3338 int base = (opcode >> 16) & 15;
3339 uint32 address = reg[base].I - offset;
3340 reg[base].I = address;
3341 CPUWriteMemory(address, reg[dest].I);
3342 clockTicks = 2 + dataTicksAccesint32(address) +
3343 codeTicksAccesint32(armNextPC);
3344 }
3345 break;
3346 CASE_16(0x580)
3347 {
3348 // STR Rd, [Rn, #]
3349 if (busPrefetchCount==0)
3350 busPrefetch = busPrefetchEnable;
3351 int offset = opcode & 0xFFF;
3352 int dest = (opcode >> 12) & 15;
3353 int base = (opcode >> 16) & 15;
3354 uint32 address = reg[base].I + offset;
3355 CPUWriteMemory(address, reg[dest].I);
3356 clockTicks = 2 + dataTicksAccesint32(address) +
3357 codeTicksAccesint32(armNextPC);
3358 }
3359 break;
3360 CASE_16(0x5a0)
3361 {
3362 // STR Rd, [Rn, #]!
3363 if (busPrefetchCount==0)
3364 busPrefetch = busPrefetchEnable;
3365 int offset = opcode & 0xFFF;
3366 int dest = (opcode >> 12) & 15;
3367 int base = (opcode >> 16) & 15;
3368 uint32 address = reg[base].I + offset;
3369 reg[base].I = address;
3370 CPUWriteMemory(address, reg[dest].I);
3371 clockTicks = 2 + dataTicksAccesint32(address) +
3372 codeTicksAccesint32(armNextPC);
3373 }
3374 break;
3375 CASE_16(0x410)
3376 {
3377 // LDR Rd, [Rn], -#
3378 if (busPrefetchCount==0)
3379 busPrefetch = busPrefetchEnable;
3380 int offset = opcode & 0xFFF;
3381 int dest = (opcode >> 12) & 15;
3382 int base = (opcode >> 16) & 15;
3383 uint32 address = reg[base].I;
3384 reg[dest].I = CPUReadMemory(address);
3385 if(dest != base)
3386 reg[base].I -= offset;
3387 clockTicks = 0;
3388 if(dest == 15) {
3389 reg[15].I &= 0xFFFFFFFC;
3390 armNextPC = reg[15].I;
3391 reg[15].I += 4;
3392 ARM_PREFETCH;
3393 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3394 }
3395 clockTicks += 3 + dataTicksAccesint32(address) +
3396 codeTicksAccesint32(armNextPC);
3397 }
3398 break;
3399 CASE_16(0x430)
3400 {
3401 // LDRT Rd, [Rn], -#
3402 if (busPrefetchCount==0)
3403 busPrefetch = busPrefetchEnable;
3404 int offset = opcode & 0xFFF;
3405 int dest = (opcode >> 12) & 15;
3406 int base = (opcode >> 16) & 15;
3407 uint32 address = reg[base].I;
3408 reg[dest].I = CPUReadMemory(address);
3409 if(dest != base)
3410 reg[base].I -= offset;
3411 clockTicks = 0;
3412 if(dest == 15) {
3413 reg[15].I &= 0xFFFFFFFC;
3414 armNextPC = reg[15].I;
3415 reg[15].I += 4;
3416 ARM_PREFETCH;
3417 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3418 }
3419 clockTicks += 3 + dataTicksAccesint32(address) +
3420 codeTicksAccesint32(armNextPC);
3421 }
3422 break;
3423 CASE_16(0x490)
3424 {
3425 // LDR Rd, [Rn], #
3426 if (busPrefetchCount==0)
3427 busPrefetch = busPrefetchEnable;
3428 int offset = opcode & 0xFFF;
3429 int dest = (opcode >> 12) & 15;
3430 int base = (opcode >> 16) & 15;
3431 uint32 address = reg[base].I;
3432 reg[dest].I = CPUReadMemory(address);
3433 if(dest != base)
3434 reg[base].I += offset;
3435 clockTicks = 0;
3436 if(dest == 15) {
3437 reg[15].I &= 0xFFFFFFFC;
3438 armNextPC = reg[15].I;
3439 reg[15].I += 4;
3440 ARM_PREFETCH;
3441 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3442 }
3443 clockTicks += 3 + dataTicksAccesint32(address) +
3444 codeTicksAccesint32(armNextPC);
3445 }
3446 break;
3447 CASE_16(0x4b0)
3448 {
3449 // LDRT Rd, [Rn], #
3450 if (busPrefetchCount==0)
3451 busPrefetch = busPrefetchEnable;
3452 int offset = opcode & 0xFFF;
3453 int dest = (opcode >> 12) & 15;
3454 int base = (opcode >> 16) & 15;
3455 uint32 address = reg[base].I;
3456 reg[dest].I = CPUReadMemory(address);
3457 if(dest != base)
3458 reg[base].I += offset;
3459 clockTicks = 0;
3460 if(dest == 15) {
3461 reg[15].I &= 0xFFFFFFFC;
3462 armNextPC = reg[15].I;
3463 reg[15].I += 4;
3464 ARM_PREFETCH;
3465 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3466 }
3467 clockTicks += 3 + dataTicksAccesint32(address) +
3468 codeTicksAccesint32(armNextPC);
3469 }
3470 break;
3471 CASE_16(0x510)
3472 {
3473 // LDR Rd, [Rn, -#]
3474 if (busPrefetchCount==0)
3475 busPrefetch = busPrefetchEnable;
3476 int offset = opcode & 0xFFF;
3477 int dest = (opcode >> 12) & 15;
3478 int base = (opcode >> 16) & 15;
3479 uint32 address = reg[base].I - offset;
3480 reg[dest].I = CPUReadMemory(address);
3481 clockTicks = 0;
3482 if(dest == 15) {
3483 reg[15].I &= 0xFFFFFFFC;
3484 armNextPC = reg[15].I;
3485 reg[15].I += 4;
3486 ARM_PREFETCH;
3487 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3488 }
3489 clockTicks += 3 + dataTicksAccesint32(address) +
3490 codeTicksAccesint32(armNextPC);
3491 }
3492 break;
3493 CASE_16(0x530)
3494 {
3495 // LDR Rd, [Rn, -#]!
3496 if (busPrefetchCount==0)
3497 busPrefetch = busPrefetchEnable;
3498 int offset = opcode & 0xFFF;
3499 int dest = (opcode >> 12) & 15;
3500 int base = (opcode >> 16) & 15;
3501 uint32 address = reg[base].I - offset;
3502 reg[dest].I = CPUReadMemory(address);
3503 if(dest != base)
3504 reg[base].I = address;
3505 clockTicks = 0;
3506 if(dest == 15) {
3507 reg[15].I &= 0xFFFFFFFC;
3508 armNextPC = reg[15].I;
3509 reg[15].I += 4;
3510 ARM_PREFETCH;
3511 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3512 }
3513 clockTicks += 3 + dataTicksAccesint32(address) +
3514 codeTicksAccesint32(armNextPC);
3515 }
3516 break;
3517 CASE_16(0x590)
3518 {
3519 // LDR Rd, [Rn, #]
3520 if (busPrefetchCount==0)
3521 busPrefetch = busPrefetchEnable;
3522 int offset = opcode & 0xFFF;
3523 int dest = (opcode >> 12) & 15;
3524 int base = (opcode >> 16) & 15;
3525 uint32 address = reg[base].I + offset;
3526 reg[dest].I = CPUReadMemory(address);
3527 clockTicks = 0;
3528 if(dest == 15) {
3529 reg[15].I &= 0xFFFFFFFC;
3530 armNextPC = reg[15].I;
3531 reg[15].I += 4;
3532 ARM_PREFETCH;
3533 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3534 }
3535 clockTicks += 3 + dataTicksAccesint32(address) +
3536 codeTicksAccesint32(armNextPC);
3537 }
3538 break;
3539 CASE_16(0x5b0)
3540 {
3541 // LDR Rd, [Rn, #]!
3542 if (busPrefetchCount==0)
3543 busPrefetch = busPrefetchEnable;
3544 int offset = opcode & 0xFFF;
3545 int dest = (opcode >> 12) & 15;
3546 int base = (opcode >> 16) & 15;
3547 uint32 address = reg[base].I + offset;
3548 reg[dest].I = CPUReadMemory(address);
3549 if(dest != base)
3550 reg[base].I = address;
3551 clockTicks = 0;
3552 if(dest == 15) {
3553 reg[15].I &= 0xFFFFFFFC;
3554 armNextPC = reg[15].I;
3555 reg[15].I += 4;
3556 ARM_PREFETCH;
3557 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3558 }
3559 clockTicks += 3 + dataTicksAccesint32(address) +
3560 codeTicksAccesint32(armNextPC);
3561 }
3562 break;
3563 CASE_16(0x440)
3564 // T versions shouldn't be different on GBA
3565 CASE_16(0x460)
3566 {
3567 // STRB Rd, [Rn], -#
3568 if (busPrefetchCount==0)
3569 busPrefetch = busPrefetchEnable;
3570 int offset = opcode & 0xFFF;
3571 int dest = (opcode >> 12) & 15;
3572 int base = (opcode >> 16) & 15;
3573 uint32 address = reg[base].I;
3574 CPUWriteByte(address, reg[dest].B.B0);
3575 reg[base].I = address - offset;
3576 clockTicks = 2 + dataTicksAccesint16(address) +
3577 codeTicksAccesint32(armNextPC);
3578 }
3579 break;
3580 CASE_16(0x4c0)
3581 // T versions shouldn't be different on GBA
3582 CASE_16(0x4e0)
3583 {
3584 // STRB Rd, [Rn], #
3585 if (busPrefetchCount==0)
3586 busPrefetch = busPrefetchEnable;
3587 int offset = opcode & 0xFFF;
3588 int dest = (opcode >> 12) & 15;
3589 int base = (opcode >> 16) & 15;
3590 uint32 address = reg[base].I;
3591 CPUWriteByte(address, reg[dest].B.B0);
3592 reg[base].I = address + offset;
3593 clockTicks = 2 + dataTicksAccesint16(address) +
3594 codeTicksAccesint32(armNextPC);
3595 }
3596 break;
3597 CASE_16(0x540)
3598 {
3599 // STRB Rd, [Rn, -#]
3600 if (busPrefetchCount==0)
3601 busPrefetch = busPrefetchEnable;
3602 int offset = opcode & 0xFFF;
3603 int dest = (opcode >> 12) & 15;
3604 int base = (opcode >> 16) & 15;
3605 uint32 address = reg[base].I - offset;
3606 CPUWriteByte(address, reg[dest].B.B0);
3607 clockTicks = 2 + dataTicksAccesint16(address) +
3608 codeTicksAccesint32(armNextPC);
3609 }
3610 break;
3611 CASE_16(0x560)
3612 {
3613 // STRB Rd, [Rn, -#]!
3614 if (busPrefetchCount==0)
3615 busPrefetch = busPrefetchEnable;
3616 int offset = opcode & 0xFFF;
3617 int dest = (opcode >> 12) & 15;
3618 int base = (opcode >> 16) & 15;
3619 uint32 address = reg[base].I - offset;
3620 reg[base].I = address;
3621 CPUWriteByte(address, reg[dest].B.B0);
3622 clockTicks = 2 + dataTicksAccesint16(address) +
3623 codeTicksAccesint32(armNextPC);
3624 }
3625 break;
3626 CASE_16(0x5c0)
3627 {
3628 // STRB Rd, [Rn, #]
3629 if (busPrefetchCount==0)
3630 busPrefetch = busPrefetchEnable;
3631 int offset = opcode & 0xFFF;
3632 int dest = (opcode >> 12) & 15;
3633 int base = (opcode >> 16) & 15;
3634 uint32 address = reg[base].I + offset;
3635 CPUWriteByte(address, reg[dest].B.B0);
3636 clockTicks = 2 + dataTicksAccesint16(address) +
3637 codeTicksAccesint32(armNextPC);
3638 }
3639 break;
3640 CASE_16(0x5e0)
3641 {
3642 // STRB Rd, [Rn, #]!
3643 if (busPrefetchCount==0)
3644 busPrefetch = busPrefetchEnable;
3645 int offset = opcode & 0xFFF;
3646 int dest = (opcode >> 12) & 15;
3647 int base = (opcode >> 16) & 15;
3648 uint32 address = reg[base].I + offset;
3649 reg[base].I = address;
3650 CPUWriteByte(address, reg[dest].I);
3651 clockTicks = 2 + dataTicksAccesint16(address) +
3652 codeTicksAccesint32(armNextPC);
3653 }
3654 break;
3655 CASE_16(0x450)
3656 // T versions shouldn't be different
3657 CASE_16(0x470)
3658 {
3659 // LDRB Rd, [Rn], -#
3660 if (busPrefetchCount==0)
3661 busPrefetch = busPrefetchEnable;
3662 int offset = opcode & 0xFFF;
3663 int dest = (opcode >> 12) & 15;
3664 int base = (opcode >> 16) & 15;
3665 uint32 address = reg[base].I;
3666 reg[dest].I = CPUReadByte(address);
3667 if(dest != base)
3668 reg[base].I -= offset;
3669 clockTicks = 0;
3670 if(dest == 15) {
3671 reg[15].I &= 0xFFFFFFFC;
3672 armNextPC = reg[15].I;
3673 reg[15].I += 4;
3674 ARM_PREFETCH;
3675 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3676 }
3677 clockTicks += 3 + dataTicksAccesint16(address) +
3678 codeTicksAccesint32(armNextPC);
3679 }
3680 break;
3681 CASE_16(0x4d0)
3682 CASE_16(0x4f0) // T versions should not be different
3683 {
3684 // LDRB Rd, [Rn], #
3685 if (busPrefetchCount==0)
3686 busPrefetch = busPrefetchEnable;
3687 int offset = opcode & 0xFFF;
3688 int dest = (opcode >> 12) & 15;
3689 int base = (opcode >> 16) & 15;
3690 uint32 address = reg[base].I;
3691 reg[dest].I = CPUReadByte(address);
3692 if(dest != base)
3693 reg[base].I += offset;
3694 clockTicks = 0;
3695 if(dest == 15) {
3696 reg[15].I &= 0xFFFFFFFC;
3697 armNextPC = reg[15].I;
3698 reg[15].I += 4;
3699 ARM_PREFETCH;
3700 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3701 }
3702 clockTicks += 3 + dataTicksAccesint16(address) +
3703 codeTicksAccesint32(armNextPC);
3704 }
3705 break;
3706 CASE_16(0x550)
3707 {
3708 // LDRB Rd, [Rn, -#]
3709 if (busPrefetchCount==0)
3710 busPrefetch = busPrefetchEnable;
3711 int offset = opcode & 0xFFF;
3712 int dest = (opcode >> 12) & 15;
3713 int base = (opcode >> 16) & 15;
3714 uint32 address = reg[base].I - offset;
3715 reg[dest].I = CPUReadByte(address);
3716 clockTicks = 0;
3717 if(dest == 15) {
3718 reg[15].I &= 0xFFFFFFFC;
3719 armNextPC = reg[15].I;
3720 reg[15].I += 4;
3721 ARM_PREFETCH;
3722 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3723 }
3724 clockTicks += 3 + dataTicksAccesint16(address) +
3725 codeTicksAccesint32(armNextPC);
3726 }
3727 break;
3728 CASE_16(0x570)
3729 {
3730 // LDRB Rd, [Rn, -#]!
3731 if (busPrefetchCount==0)
3732 busPrefetch = busPrefetchEnable;
3733 int offset = opcode & 0xFFF;
3734 int dest = (opcode >> 12) & 15;
3735 int base = (opcode >> 16) & 15;
3736 uint32 address = reg[base].I - offset;
3737 reg[dest].I = CPUReadByte(address);
3738 if(dest != base)
3739 reg[base].I = address;
3740 clockTicks = 0;
3741 if(dest == 15) {
3742 reg[15].I &= 0xFFFFFFFC;
3743 armNextPC = reg[15].I;
3744 reg[15].I += 4;
3745 ARM_PREFETCH;
3746 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3747 }
3748 clockTicks += 3 + dataTicksAccesint16(address) +
3749 codeTicksAccesint32(armNextPC);
3750 }
3751 break;
3752 CASE_16(0x5d0)
3753 {
3754 // LDRB Rd, [Rn, #]
3755 if (busPrefetchCount==0)
3756 busPrefetch = busPrefetchEnable;
3757 int offset = opcode & 0xFFF;
3758 int dest = (opcode >> 12) & 15;
3759 int base = (opcode >> 16) & 15;
3760 uint32 address = reg[base].I + offset;
3761 reg[dest].I = CPUReadByte(address);
3762 clockTicks = 0;
3763 if(dest == 15) {
3764 reg[15].I &= 0xFFFFFFFC;
3765 armNextPC = reg[15].I;
3766 reg[15].I += 4;
3767 ARM_PREFETCH;
3768 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3769 }
3770 clockTicks += 3 + dataTicksAccesint16(address) +
3771 codeTicksAccesint32(armNextPC);
3772 }
3773 break;
3774 CASE_16(0x5f0)
3775 {
3776 // LDRB Rd, [Rn, #]!
3777 if (busPrefetchCount==0)
3778 busPrefetch = busPrefetchEnable;
3779 int offset = opcode & 0xFFF;
3780 int dest = (opcode >> 12) & 15;
3781 int base = (opcode >> 16) & 15;
3782 uint32 address = reg[base].I + offset;
3783 reg[dest].I = CPUReadByte(address);
3784 if(dest != base)
3785 reg[base].I = address;
3786 clockTicks = 0;
3787 if(dest == 15) {
3788 reg[15].I &= 0xFFFFFFFC;
3789 armNextPC = reg[15].I;
3790 reg[15].I += 4;
3791 ARM_PREFETCH;
3792 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
3793 }
3794 clockTicks += 3 + dataTicksAccesint16(address) +
3795 codeTicksAccesint32(armNextPC);
3796 }
3797 break;
3798 case 0x600:
3799 case 0x608:
3800 // T versions are the same
3801 case 0x620:
3802 case 0x628:
3803 {
3804 // STR Rd, [Rn], -Rm, LSL #
3805 if (busPrefetchCount==0)
3806 busPrefetch = busPrefetchEnable;
3807 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
3808 int dest = (opcode >> 12) & 15;
3809 int base = (opcode >> 16) & 15;
3810 uint32 address = reg[base].I;
3811 CPUWriteMemory(address, reg[dest].I);
3812 reg[base].I = address - offset;
3813 clockTicks = 2 + dataTicksAccesint32(address) +
3814 codeTicksAccesint32(armNextPC);
3815 }
3816 break;
3817 case 0x602:
3818 case 0x60a:
3819 // T versions are the same
3820 case 0x622:
3821 case 0x62a:
3822 {
3823 // STR Rd, [Rn], -Rm, LSR #
3824 if (busPrefetchCount==0)
3825 busPrefetch = busPrefetchEnable;
3826 int shift = (opcode >> 7) & 31;
3827 int offset = shift ? reg[opcode & 15].I >> shift : 0;
3828 int dest = (opcode >> 12) & 15;
3829 int base = (opcode >> 16) & 15;
3830 uint32 address = reg[base].I;
3831 CPUWriteMemory(address, reg[dest].I);
3832 reg[base].I = address - offset;
3833 clockTicks = 2 + dataTicksAccesint32(address) +
3834 codeTicksAccesint32(armNextPC);
3835 }
3836 break;
3837 case 0x604:
3838 case 0x60c:
3839 // T versions are the same
3840 case 0x624:
3841 case 0x62c:
3842 {
3843 // STR Rd, [Rn], -Rm, ASR #
3844 if (busPrefetchCount==0)
3845 busPrefetch = busPrefetchEnable;
3846 int shift = (opcode >> 7) & 31;
3847 int offset;
3848 if(shift)
3849 offset = (int)((int32)reg[opcode & 15].I >> shift);
3850 else if(reg[opcode & 15].I & 0x80000000)
3851 offset = 0xFFFFFFFF;
3852 else
3853 offset = 0;
3854 int dest = (opcode >> 12) & 15;
3855 int base = (opcode >> 16) & 15;
3856 uint32 address = reg[base].I;
3857 CPUWriteMemory(address, reg[dest].I);
3858 reg[base].I = address - offset;
3859 clockTicks = 2 + dataTicksAccesint32(address) +
3860 codeTicksAccesint32(armNextPC);
3861 }
3862 break;
3863 case 0x606:
3864 case 0x60e:
3865 // T versions are the same
3866 case 0x626:
3867 case 0x62e:
3868 {
3869 // STR Rd, [Rn], -Rm, ROR #
3870 if (busPrefetchCount==0)
3871 busPrefetch = busPrefetchEnable;
3872 int shift = (opcode >> 7) & 31;
3873 uint32 value = reg[opcode & 15].I;
3874 if(shift) {
3875 ROR_VALUE;
3876 } else {
3877 RCR_VALUE;
3878 }
3879 int dest = (opcode >> 12) & 15;
3880 int base = (opcode >> 16) & 15;
3881 uint32 address = reg[base].I;
3882 CPUWriteMemory(address, reg[dest].I);
3883 reg[base].I = address - value;
3884 clockTicks = 2 + dataTicksAccesint32(address) +
3885 codeTicksAccesint32(armNextPC);
3886 }
3887 break;
3888 case 0x680:
3889 case 0x688:
3890 // T versions are the same
3891 case 0x6a0:
3892 case 0x6a8:
3893 {
3894 // STR Rd, [Rn], Rm, LSL #
3895 if (busPrefetchCount==0)
3896 busPrefetch = busPrefetchEnable;
3897 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
3898 int dest = (opcode >> 12) & 15;
3899 int base = (opcode >> 16) & 15;
3900 uint32 address = reg[base].I;
3901 CPUWriteMemory(address, reg[dest].I);
3902 reg[base].I = address + offset;
3903 clockTicks = 2 + dataTicksAccesint32(address) +
3904 codeTicksAccesint32(armNextPC);
3905 }
3906 break;
3907 case 0x682:
3908 case 0x68a:
3909 // T versions are the same
3910 case 0x6a2:
3911 case 0x6aa:
3912 {
3913 // STR Rd, [Rn], Rm, LSR #
3914 if (busPrefetchCount==0)
3915 busPrefetch = busPrefetchEnable;
3916 int shift = (opcode >> 7) & 31;
3917 int offset = shift ? reg[opcode & 15].I >> shift : 0;
3918 int dest = (opcode >> 12) & 15;
3919 int base = (opcode >> 16) & 15;
3920 uint32 address = reg[base].I;
3921 CPUWriteMemory(address, reg[dest].I);
3922 reg[base].I = address + offset;
3923 clockTicks = 2 + dataTicksAccesint32(address) +
3924 codeTicksAccesint32(armNextPC);
3925 }
3926 break;
3927 case 0x684:
3928 case 0x68c:
3929 // T versions are the same
3930 case 0x6a4:
3931 case 0x6ac:
3932 {
3933 // STR Rd, [Rn], Rm, ASR #
3934 if (busPrefetchCount==0)
3935 busPrefetch = busPrefetchEnable;
3936 int shift = (opcode >> 7) & 31;
3937 int offset;
3938 if(shift)
3939 offset = (int)((int32)reg[opcode & 15].I >> shift);
3940 else if(reg[opcode & 15].I & 0x80000000)
3941 offset = 0xFFFFFFFF;
3942 else
3943 offset = 0;
3944 int dest = (opcode >> 12) & 15;
3945 int base = (opcode >> 16) & 15;
3946 uint32 address = reg[base].I;
3947 CPUWriteMemory(address, reg[dest].I);
3948 reg[base].I = address + offset;
3949 clockTicks = 2 + dataTicksAccesint32(address) +
3950 codeTicksAccesint32(armNextPC);
3951 }
3952 break;
3953 case 0x686:
3954 case 0x68e:
3955 // T versions are the same
3956 case 0x6a6:
3957 case 0x6ae:
3958 {
3959 // STR Rd, [Rn], Rm, ROR #
3960 if (busPrefetchCount==0)
3961 busPrefetch = busPrefetchEnable;
3962 int shift = (opcode >> 7) & 31;
3963 uint32 value = reg[opcode & 15].I;
3964 if(shift) {
3965 ROR_VALUE;
3966 } else {
3967 RCR_VALUE;
3968 }
3969 int dest = (opcode >> 12) & 15;
3970 int base = (opcode >> 16) & 15;
3971 uint32 address = reg[base].I;
3972 CPUWriteMemory(address, reg[dest].I);
3973 reg[base].I = address + value;
3974 clockTicks = 2 + dataTicksAccesint32(address) +
3975 codeTicksAccesint32(armNextPC);
3976 }
3977 break;
3978 case 0x700:
3979 case 0x708:
3980 {
3981 // STR Rd, [Rn, -Rm, LSL #]
3982 if (busPrefetchCount==0)
3983 busPrefetch = busPrefetchEnable;
3984 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
3985 int dest = (opcode >> 12) & 15;
3986 int base = (opcode >> 16) & 15;
3987 uint32 address = reg[base].I - offset;
3988 CPUWriteMemory(address, reg[dest].I);
3989 clockTicks = 2 + dataTicksAccesint32(address) +
3990 codeTicksAccesint32(armNextPC);
3991 }
3992 break;
3993 case 0x702:
3994 case 0x70a:
3995 {
3996 // STR Rd, [Rn, -Rm, LSR #]
3997 if (busPrefetchCount==0)
3998 busPrefetch = busPrefetchEnable;
3999 int shift = (opcode >> 7) & 31;
4000 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4001 int dest = (opcode >> 12) & 15;
4002 int base = (opcode >> 16) & 15;
4003 uint32 address = reg[base].I - offset;
4004 CPUWriteMemory(address, reg[dest].I);
4005 clockTicks = 2 + dataTicksAccesint32(address) +
4006 codeTicksAccesint32(armNextPC);
4007 }
4008 break;
4009 case 0x704:
4010 case 0x70c:
4011 {
4012 // STR Rd, [Rn, -Rm, ASR #]
4013 if (busPrefetchCount==0)
4014 busPrefetch = busPrefetchEnable;
4015 int shift = (opcode >> 7) & 31;
4016 int offset;
4017 if(shift)
4018 offset = (int)((int32)reg[opcode & 15].I >> shift);
4019 else if(reg[opcode & 15].I & 0x80000000)
4020 offset = 0xFFFFFFFF;
4021 else
4022 offset = 0;
4023 int dest = (opcode >> 12) & 15;
4024 int base = (opcode >> 16) & 15;
4025 uint32 address = reg[base].I - offset;
4026 CPUWriteMemory(address, reg[dest].I);
4027 clockTicks = 2 + dataTicksAccesint32(address) +
4028 codeTicksAccesint32(armNextPC);
4029 }
4030 break;
4031 case 0x706:
4032 case 0x70e:
4033 {
4034 // STR Rd, [Rn, -Rm, ROR #]
4035 if (busPrefetchCount==0)
4036 busPrefetch = busPrefetchEnable;
4037 int shift = (opcode >> 7) & 31;
4038 uint32 value = reg[opcode & 15].I;
4039 if(shift) {
4040 ROR_VALUE;
4041 } else {
4042 RCR_VALUE;
4043 }
4044 int dest = (opcode >> 12) & 15;
4045 int base = (opcode >> 16) & 15;
4046 uint32 address = reg[base].I - value;
4047 CPUWriteMemory(address, reg[dest].I);
4048 clockTicks = 2 + dataTicksAccesint32(address) +
4049 codeTicksAccesint32(armNextPC);
4050 }
4051 break;
4052 case 0x720:
4053 case 0x728:
4054 {
4055 // STR Rd, [Rn, -Rm, LSL #]!
4056 if (busPrefetchCount==0)
4057 busPrefetch = busPrefetchEnable;
4058 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4059 int dest = (opcode >> 12) & 15;
4060 int base = (opcode >> 16) & 15;
4061 uint32 address = reg[base].I - offset;
4062 reg[base].I = address;
4063 CPUWriteMemory(address, reg[dest].I);
4064 clockTicks = 2 + dataTicksAccesint32(address) +
4065 codeTicksAccesint32(armNextPC);
4066 }
4067 break;
4068 case 0x722:
4069 case 0x72a:
4070 {
4071 // STR Rd, [Rn, -Rm, LSR #]!
4072 if (busPrefetchCount==0)
4073 busPrefetch = busPrefetchEnable;
4074 int shift = (opcode >> 7) & 31;
4075 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4076 int dest = (opcode >> 12) & 15;
4077 int base = (opcode >> 16) & 15;
4078 uint32 address = reg[base].I - offset;
4079 reg[base].I = address;
4080 CPUWriteMemory(address, reg[dest].I);
4081 clockTicks = 2 + dataTicksAccesint32(address) +
4082 codeTicksAccesint32(armNextPC);
4083 }
4084 break;
4085 case 0x724:
4086 case 0x72c:
4087 {
4088 // STR Rd, [Rn, -Rm, ASR #]!
4089 if (busPrefetchCount==0)
4090 busPrefetch = busPrefetchEnable;
4091 int shift = (opcode >> 7) & 31;
4092 int offset;
4093 if(shift)
4094 offset = (int)((int32)reg[opcode & 15].I >> shift);
4095 else if(reg[opcode & 15].I & 0x80000000)
4096 offset = 0xFFFFFFFF;
4097 else
4098 offset = 0;
4099 int dest = (opcode >> 12) & 15;
4100 int base = (opcode >> 16) & 15;
4101 uint32 address = reg[base].I - offset;
4102 reg[base].I = address;
4103 CPUWriteMemory(address, reg[dest].I);
4104 clockTicks = 2 + dataTicksAccesint32(address) +
4105 codeTicksAccesint32(armNextPC);
4106 }
4107 break;
4108 case 0x726:
4109 case 0x72e:
4110 {
4111 // STR Rd, [Rn, -Rm, ROR #]!
4112 if (busPrefetchCount==0)
4113 busPrefetch = busPrefetchEnable;
4114 int shift = (opcode >> 7) & 31;
4115 uint32 value = reg[opcode & 15].I;
4116 if(shift) {
4117 ROR_VALUE;
4118 } else {
4119 RCR_VALUE;
4120 }
4121 int dest = (opcode >> 12) & 15;
4122 int base = (opcode >> 16) & 15;
4123 uint32 address = reg[base].I - value;
4124 reg[base].I = address;
4125 CPUWriteMemory(address, reg[dest].I);
4126 clockTicks = 2 + dataTicksAccesint32(address) +
4127 codeTicksAccesint32(armNextPC);
4128 }
4129 break;
4130 case 0x780:
4131 case 0x788:
4132 {
4133 // STR Rd, [Rn, Rm, LSL #]
4134 if (busPrefetchCount==0)
4135 busPrefetch = busPrefetchEnable;
4136 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4137 int dest = (opcode >> 12) & 15;
4138 int base = (opcode >> 16) & 15;
4139 uint32 address = reg[base].I + offset;
4140 CPUWriteMemory(address, reg[dest].I);
4141 clockTicks = 2 + dataTicksAccesint32(address) +
4142 codeTicksAccesint32(armNextPC);
4143 }
4144 break;
4145 case 0x782:
4146 case 0x78a:
4147 {
4148 // STR Rd, [Rn, Rm, LSR #]
4149 if (busPrefetchCount==0)
4150 busPrefetch = busPrefetchEnable;
4151 int shift = (opcode >> 7) & 31;
4152 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4153 int dest = (opcode >> 12) & 15;
4154 int base = (opcode >> 16) & 15;
4155 uint32 address = reg[base].I + offset;
4156 CPUWriteMemory(address, reg[dest].I);
4157 clockTicks = 2 + dataTicksAccesint32(address) +
4158 codeTicksAccesint32(armNextPC);
4159 }
4160 break;
4161 case 0x784:
4162 case 0x78c:
4163 {
4164 // STR Rd, [Rn, Rm, ASR #]
4165 if (busPrefetchCount==0)
4166 busPrefetch = busPrefetchEnable;
4167 int shift = (opcode >> 7) & 31;
4168 int offset;
4169 if(shift)
4170 offset = (int)((int32)reg[opcode & 15].I >> shift);
4171 else if(reg[opcode & 15].I & 0x80000000)
4172 offset = 0xFFFFFFFF;
4173 else
4174 offset = 0;
4175 int dest = (opcode >> 12) & 15;
4176 int base = (opcode >> 16) & 15;
4177 uint32 address = reg[base].I + offset;
4178 CPUWriteMemory(address, reg[dest].I);
4179 clockTicks = 2 + dataTicksAccesint32(address) +
4180 codeTicksAccesint32(armNextPC);
4181 }
4182 break;
4183 case 0x786:
4184 case 0x78e:
4185 {
4186 // STR Rd, [Rn, Rm, ROR #]
4187 if (busPrefetchCount==0)
4188 busPrefetch = busPrefetchEnable;
4189 int shift = (opcode >> 7) & 31;
4190 uint32 value = reg[opcode & 15].I;
4191 if(shift) {
4192 ROR_VALUE;
4193 } else {
4194 RCR_VALUE;
4195 }
4196 int dest = (opcode >> 12) & 15;
4197 int base = (opcode >> 16) & 15;
4198 uint32 address = reg[base].I + value;
4199 CPUWriteMemory(address, reg[dest].I);
4200 clockTicks = 2 + dataTicksAccesint32(address) +
4201 codeTicksAccesint32(armNextPC);
4202 }
4203 break;
4204 case 0x7a0:
4205 case 0x7a8:
4206 {
4207 // STR Rd, [Rn, Rm, LSL #]!
4208 if (busPrefetchCount==0)
4209 busPrefetch = busPrefetchEnable;
4210 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4211 int dest = (opcode >> 12) & 15;
4212 int base = (opcode >> 16) & 15;
4213 uint32 address = reg[base].I + offset;
4214 reg[base].I = address;
4215 CPUWriteMemory(address, reg[dest].I);
4216 clockTicks = 2 + dataTicksAccesint32(address) +
4217 codeTicksAccesint32(armNextPC);
4218 }
4219 break;
4220 case 0x7a2:
4221 case 0x7aa:
4222 {
4223 // STR Rd, [Rn, Rm, LSR #]!
4224 if (busPrefetchCount==0)
4225 busPrefetch = busPrefetchEnable;
4226 int shift = (opcode >> 7) & 31;
4227 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4228 int dest = (opcode >> 12) & 15;
4229 int base = (opcode >> 16) & 15;
4230 uint32 address = reg[base].I + offset;
4231 reg[base].I = address;
4232 CPUWriteMemory(address, reg[dest].I);
4233 clockTicks = 2 + dataTicksAccesint32(address) +
4234 codeTicksAccesint32(armNextPC);
4235 }
4236 break;
4237 case 0x7a4:
4238 case 0x7ac:
4239 {
4240 // STR Rd, [Rn, Rm, ASR #]!
4241 if (busPrefetchCount==0)
4242 busPrefetch = busPrefetchEnable;
4243 int shift = (opcode >> 7) & 31;
4244 int offset;
4245 if(shift)
4246 offset = (int)((int32)reg[opcode & 15].I >> shift);
4247 else if(reg[opcode & 15].I & 0x80000000)
4248 offset = 0xFFFFFFFF;
4249 else
4250 offset = 0;
4251 int dest = (opcode >> 12) & 15;
4252 int base = (opcode >> 16) & 15;
4253 uint32 address = reg[base].I + offset;
4254 reg[base].I = address;
4255 CPUWriteMemory(address, reg[dest].I);
4256 clockTicks = 2 + dataTicksAccesint32(address) +
4257 codeTicksAccesint32(armNextPC);
4258 }
4259 break;
4260 case 0x7a6:
4261 case 0x7ae:
4262 {
4263 // STR Rd, [Rn, Rm, ROR #]!
4264 if (busPrefetchCount==0)
4265 busPrefetch = busPrefetchEnable;
4266 int shift = (opcode >> 7) & 31;
4267 uint32 value = reg[opcode & 15].I;
4268 if(shift) {
4269 ROR_VALUE;
4270 } else {
4271 RCR_VALUE;
4272 }
4273 int dest = (opcode >> 12) & 15;
4274 int base = (opcode >> 16) & 15;
4275 uint32 address = reg[base].I + value;
4276 reg[base].I = address;
4277 CPUWriteMemory(address, reg[dest].I);
4278 clockTicks = 2 + dataTicksAccesint32(address) +
4279 codeTicksAccesint32(armNextPC);
4280 }
4281 break;
4282 case 0x610:
4283 case 0x618:
4284 // T versions are the same
4285 case 0x630:
4286 case 0x638:
4287 {
4288 // LDR Rd, [Rn], -Rm, LSL #
4289 if (busPrefetchCount==0)
4290 busPrefetch = busPrefetchEnable;
4291 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4292 int dest = (opcode >> 12) & 15;
4293 int base = (opcode >> 16) & 15;
4294 uint32 address = reg[base].I;
4295 reg[dest].I = CPUReadMemory(address);
4296 if(dest != base)
4297 reg[base].I = address - offset;
4298 clockTicks = 0;
4299 if(dest == 15) {
4300 reg[15].I &= 0xFFFFFFFC;
4301 armNextPC = reg[15].I;
4302 reg[15].I += 4;
4303 ARM_PREFETCH;
4304 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4305 }
4306 clockTicks += 3 + dataTicksAccesint32(address) +
4307 codeTicksAccesint32(armNextPC);
4308 }
4309 break;
4310 case 0x612:
4311 case 0x61a:
4312 // T versions are the same
4313 case 0x632:
4314 case 0x63a:
4315 {
4316 // LDR Rd, [Rn], -Rm, LSR #
4317 if (busPrefetchCount==0)
4318 busPrefetch = busPrefetchEnable;
4319 int shift = (opcode >> 7) & 31;
4320 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4321 int dest = (opcode >> 12) & 15;
4322 int base = (opcode >> 16) & 15;
4323 uint32 address = reg[base].I;
4324 reg[dest].I = CPUReadMemory(address);
4325 if(dest != base)
4326 reg[base].I = address - offset;
4327 clockTicks = 0;
4328 if(dest == 15) {
4329 reg[15].I &= 0xFFFFFFFC;
4330 armNextPC = reg[15].I;
4331 reg[15].I += 4;
4332 ARM_PREFETCH;
4333 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4334 }
4335 clockTicks += 3 + dataTicksAccesint32(address) +
4336 codeTicksAccesint32(armNextPC);
4337 }
4338 break;
4339 case 0x614:
4340 case 0x61c:
4341 // T versions are the same
4342 case 0x634:
4343 case 0x63c:
4344 {
4345 // LDR Rd, [Rn], -Rm, ASR #
4346 if (busPrefetchCount==0)
4347 busPrefetch = busPrefetchEnable;
4348 int shift = (opcode >> 7) & 31;
4349 int offset;
4350 if(shift)
4351 offset = (int)((int32)reg[opcode & 15].I >> shift);
4352 else if(reg[opcode & 15].I & 0x80000000)
4353 offset = 0xFFFFFFFF;
4354 else
4355 offset = 0;
4356 int dest = (opcode >> 12) & 15;
4357 int base = (opcode >> 16) & 15;
4358 uint32 address = reg[base].I;
4359 reg[dest].I = CPUReadMemory(address);
4360 if(dest != base)
4361 reg[base].I = address - offset;
4362 clockTicks = 0;
4363 if(dest == 15) {
4364 reg[15].I &= 0xFFFFFFFC;
4365 armNextPC = reg[15].I;
4366 reg[15].I += 4;
4367 ARM_PREFETCH;
4368 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4369 }
4370 clockTicks += 3 + dataTicksAccesint32(address) +
4371 codeTicksAccesint32(armNextPC);
4372 }
4373 break;
4374 case 0x616:
4375 case 0x61e:
4376 // T versions are the same
4377 case 0x636:
4378 case 0x63e:
4379 {
4380 // LDR Rd, [Rn], -Rm, ROR #
4381 if (busPrefetchCount==0)
4382 busPrefetch = busPrefetchEnable;
4383 int shift = (opcode >> 7) & 31;
4384 uint32 value = reg[opcode & 15].I;
4385 if(shift) {
4386 ROR_VALUE;
4387 } else {
4388 RCR_VALUE;
4389 }
4390 int dest = (opcode >> 12) & 15;
4391 int base = (opcode >> 16) & 15;
4392 uint32 address = reg[base].I;
4393 reg[dest].I = CPUReadMemory(address);
4394 if(dest != base)
4395 reg[base].I = address - value;
4396 clockTicks = 0;
4397 if(dest == 15) {
4398 reg[15].I &= 0xFFFFFFFC;
4399 armNextPC = reg[15].I;
4400 reg[15].I += 4;
4401 ARM_PREFETCH;
4402 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4403 }
4404 clockTicks += 3 + dataTicksAccesint32(address) +
4405 codeTicksAccesint32(armNextPC);
4406 }
4407 break;
4408 case 0x690:
4409 case 0x698:
4410 // T versions are the same
4411 case 0x6b0:
4412 case 0x6b8:
4413 {
4414 // LDR Rd, [Rn], Rm, LSL #
4415 if (busPrefetchCount==0)
4416 busPrefetch = busPrefetchEnable;
4417 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4418 int dest = (opcode >> 12) & 15;
4419 int base = (opcode >> 16) & 15;
4420 uint32 address = reg[base].I;
4421 reg[dest].I = CPUReadMemory(address);
4422 if(dest != base)
4423 reg[base].I = address + offset;
4424 clockTicks = 0;
4425 if(dest == 15) {
4426 reg[15].I &= 0xFFFFFFFC;
4427 armNextPC = reg[15].I;
4428 reg[15].I += 4;
4429 ARM_PREFETCH;
4430 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4431 }
4432 clockTicks += 3 + dataTicksAccesint32(address) +
4433 codeTicksAccesint32(armNextPC);
4434 }
4435 break;
4436 case 0x692:
4437 case 0x69a:
4438 // T versions are the same
4439 case 0x6b2:
4440 case 0x6ba:
4441 {
4442 // LDR Rd, [Rn], Rm, LSR #
4443 if (busPrefetchCount==0)
4444 busPrefetch = busPrefetchEnable;
4445 int shift = (opcode >> 7) & 31;
4446 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4447 int dest = (opcode >> 12) & 15;
4448 int base = (opcode >> 16) & 15;
4449 uint32 address = reg[base].I;
4450 reg[dest].I = CPUReadMemory(address);
4451 if(dest != base)
4452 reg[base].I = address + offset;
4453 clockTicks = 0;
4454 if(dest == 15) {
4455 reg[15].I &= 0xFFFFFFFC;
4456 armNextPC = reg[15].I;
4457 reg[15].I += 4;
4458 ARM_PREFETCH;
4459 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4460 }
4461 clockTicks += 3 + dataTicksAccesint32(address) +
4462 codeTicksAccesint32(armNextPC);
4463 }
4464 break;
4465 case 0x694:
4466 case 0x69c:
4467 // T versions are the same
4468 case 0x6b4:
4469 case 0x6bc:
4470 {
4471 // LDR Rd, [Rn], Rm, ASR #
4472 if (busPrefetchCount==0)
4473 busPrefetch = busPrefetchEnable;
4474 int shift = (opcode >> 7) & 31;
4475 int offset;
4476 if(shift)
4477 offset = (int)((int32)reg[opcode & 15].I >> shift);
4478 else if(reg[opcode & 15].I & 0x80000000)
4479 offset = 0xFFFFFFFF;
4480 else
4481 offset = 0;
4482 int dest = (opcode >> 12) & 15;
4483 int base = (opcode >> 16) & 15;
4484 uint32 address = reg[base].I;
4485 reg[dest].I = CPUReadMemory(address);
4486 if(dest != base)
4487 reg[base].I = address + offset;
4488 clockTicks = 0;
4489 if(dest == 15) {
4490 reg[15].I &= 0xFFFFFFFC;
4491 armNextPC = reg[15].I;
4492 reg[15].I += 4;
4493 ARM_PREFETCH;
4494 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4495 }
4496 clockTicks += 3 + dataTicksAccesint32(address) +
4497 codeTicksAccesint32(armNextPC);
4498 }
4499 break;
4500 case 0x696:
4501 case 0x69e:
4502 // T versions are the same
4503 case 0x6b6:
4504 case 0x6be:
4505 {
4506 // LDR Rd, [Rn], Rm, ROR #
4507 if (busPrefetchCount==0)
4508 busPrefetch = busPrefetchEnable;
4509 int shift = (opcode >> 7) & 31;
4510 uint32 value = reg[opcode & 15].I;
4511 if(shift) {
4512 ROR_VALUE;
4513 } else {
4514 RCR_VALUE;
4515 }
4516 int dest = (opcode >> 12) & 15;
4517 int base = (opcode >> 16) & 15;
4518 uint32 address = reg[base].I;
4519 reg[dest].I = CPUReadMemory(address);
4520 if(dest != base)
4521 reg[base].I = address + value;
4522 clockTicks = 0;
4523 if(dest == 15) {
4524 reg[15].I &= 0xFFFFFFFC;
4525 armNextPC = reg[15].I;
4526 reg[15].I += 4;
4527 ARM_PREFETCH;
4528 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4529 }
4530 clockTicks += 3 + dataTicksAccesint32(address) +
4531 codeTicksAccesint32(armNextPC);
4532 }
4533 break;
4534 case 0x710:
4535 case 0x718:
4536 {
4537 // LDR Rd, [Rn, -Rm, LSL #]
4538 if (busPrefetchCount==0)
4539 busPrefetch = busPrefetchEnable;
4540 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4541 int dest = (opcode >> 12) & 15;
4542 int base = (opcode >> 16) & 15;
4543 uint32 address = reg[base].I - offset;
4544 reg[dest].I = CPUReadMemory(address);
4545 clockTicks = 0;
4546 if(dest == 15) {
4547 reg[15].I &= 0xFFFFFFFC;
4548 armNextPC = reg[15].I;
4549 reg[15].I += 4;
4550 ARM_PREFETCH;
4551 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4552 }
4553 clockTicks += 3 + dataTicksAccesint32(address) +
4554 codeTicksAccesint32(armNextPC);
4555 }
4556 break;
4557 case 0x712:
4558 case 0x71a:
4559 {
4560 // LDR Rd, [Rn, -Rm, LSR #]
4561 if (busPrefetchCount==0)
4562 busPrefetch = busPrefetchEnable;
4563 int shift = (opcode >> 7) & 31;
4564 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4565 int dest = (opcode >> 12) & 15;
4566 int base = (opcode >> 16) & 15;
4567 uint32 address = reg[base].I - offset;
4568 reg[dest].I = CPUReadMemory(address);
4569 clockTicks = 0;
4570 if(dest == 15) {
4571 reg[15].I &= 0xFFFFFFFC;
4572 armNextPC = reg[15].I;
4573 reg[15].I += 4;
4574 ARM_PREFETCH;
4575 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4576 }
4577 clockTicks += 3 + dataTicksAccesint32(address) +
4578 codeTicksAccesint32(armNextPC);
4579 }
4580 break;
4581 case 0x714:
4582 case 0x71c:
4583 {
4584 // LDR Rd, [Rn, -Rm, ASR #]
4585 if (busPrefetchCount==0)
4586 busPrefetch = busPrefetchEnable;
4587 int shift = (opcode >> 7) & 31;
4588 int offset;
4589 if(shift)
4590 offset = (int)((int32)reg[opcode & 15].I >> shift);
4591 else if(reg[opcode & 15].I & 0x80000000)
4592 offset = 0xFFFFFFFF;
4593 else
4594 offset = 0;
4595 int dest = (opcode >> 12) & 15;
4596 int base = (opcode >> 16) & 15;
4597 uint32 address = reg[base].I - offset;
4598 reg[dest].I = CPUReadMemory(address);
4599 clockTicks = 0;
4600 if(dest == 15) {
4601 reg[15].I &= 0xFFFFFFFC;
4602 armNextPC = reg[15].I;
4603 reg[15].I += 4;
4604 ARM_PREFETCH;
4605 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4606 }
4607 clockTicks += 3 + dataTicksAccesint32(address) +
4608 codeTicksAccesint32(armNextPC);
4609 }
4610 break;
4611 case 0x716:
4612 case 0x71e:
4613 {
4614 // LDR Rd, [Rn, -Rm, ROR #]
4615 if (busPrefetchCount==0)
4616 busPrefetch = busPrefetchEnable;
4617 int shift = (opcode >> 7) & 31;
4618 uint32 value = reg[opcode & 15].I;
4619 if(shift) {
4620 ROR_VALUE;
4621 } else {
4622 RCR_VALUE;
4623 }
4624 int dest = (opcode >> 12) & 15;
4625 int base = (opcode >> 16) & 15;
4626 uint32 address = reg[base].I - value;
4627 reg[dest].I = CPUReadMemory(address);
4628 clockTicks = 0;
4629 if(dest == 15) {
4630 reg[15].I &= 0xFFFFFFFC;
4631 armNextPC = reg[15].I;
4632 reg[15].I += 4;
4633 ARM_PREFETCH;
4634 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4635 }
4636 clockTicks += 3 + dataTicksAccesint32(address) +
4637 codeTicksAccesint32(armNextPC);
4638 }
4639 break;
4640 case 0x730:
4641 case 0x738:
4642 {
4643 // LDR Rd, [Rn, -Rm, LSL #]!
4644 if (busPrefetchCount==0)
4645 busPrefetch = busPrefetchEnable;
4646 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4647 int dest = (opcode >> 12) & 15;
4648 int base = (opcode >> 16) & 15;
4649 uint32 address = reg[base].I - offset;
4650 reg[dest].I = CPUReadMemory(address);
4651 if(dest != base)
4652 reg[base].I = address;
4653 clockTicks = 0;
4654 if(dest == 15) {
4655 reg[15].I &= 0xFFFFFFFC;
4656 armNextPC = reg[15].I;
4657 reg[15].I += 4;
4658 ARM_PREFETCH;
4659 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4660 }
4661 clockTicks += 3 + dataTicksAccesint32(address) +
4662 codeTicksAccesint32(armNextPC);
4663 }
4664 break;
4665 case 0x732:
4666 case 0x73a:
4667 {
4668 // LDR Rd, [Rn, -Rm, LSR #]!
4669 if (busPrefetchCount==0)
4670 busPrefetch = busPrefetchEnable;
4671 int shift = (opcode >> 7) & 31;
4672 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4673 int dest = (opcode >> 12) & 15;
4674 int base = (opcode >> 16) & 15;
4675 uint32 address = reg[base].I - offset;
4676 reg[dest].I = CPUReadMemory(address);
4677 if(dest != base)
4678 reg[base].I = address;
4679 clockTicks = 0;
4680 if(dest == 15) {
4681 reg[15].I &= 0xFFFFFFFC;
4682 armNextPC = reg[15].I;
4683 reg[15].I += 4;
4684 ARM_PREFETCH;
4685 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4686 }
4687 clockTicks += 3 + dataTicksAccesint32(address) +
4688 codeTicksAccesint32(armNextPC);
4689 }
4690 break;
4691 case 0x734:
4692 case 0x73c:
4693 {
4694 // LDR Rd, [Rn, -Rm, ASR #]!
4695 if (busPrefetchCount==0)
4696 busPrefetch = busPrefetchEnable;
4697 int shift = (opcode >> 7) & 31;
4698 int offset;
4699 if(shift)
4700 offset = (int)((int32)reg[opcode & 15].I >> shift);
4701 else if(reg[opcode & 15].I & 0x80000000)
4702 offset = 0xFFFFFFFF;
4703 else
4704 offset = 0;
4705 int dest = (opcode >> 12) & 15;
4706 int base = (opcode >> 16) & 15;
4707 uint32 address = reg[base].I - offset;
4708 reg[dest].I = CPUReadMemory(address);
4709 if(dest != base)
4710 reg[base].I = address;
4711 clockTicks = 0;
4712 if(dest == 15) {
4713 reg[15].I &= 0xFFFFFFFC;
4714 armNextPC = reg[15].I;
4715 reg[15].I += 4;
4716 ARM_PREFETCH;
4717 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4718 }
4719 clockTicks += 3 + dataTicksAccesint32(address) +
4720 codeTicksAccesint32(armNextPC);
4721 }
4722 break;
4723 case 0x736:
4724 case 0x73e:
4725 {
4726 // LDR Rd, [Rn, -Rm, ROR #]!
4727 if (busPrefetchCount==0)
4728 busPrefetch = busPrefetchEnable;
4729 int shift = (opcode >> 7) & 31;
4730 uint32 value = reg[opcode & 15].I;
4731 if(shift) {
4732 ROR_VALUE;
4733 } else {
4734 RCR_VALUE;
4735 }
4736 int dest = (opcode >> 12) & 15;
4737 int base = (opcode >> 16) & 15;
4738 uint32 address = reg[base].I - value;
4739 reg[dest].I = CPUReadMemory(address);
4740 if(dest != base)
4741 reg[base].I = address;
4742 clockTicks = 0;
4743 if(dest == 15) {
4744 reg[15].I &= 0xFFFFFFFC;
4745 armNextPC = reg[15].I;
4746 reg[15].I += 4;
4747 ARM_PREFETCH;
4748 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4749 }
4750 clockTicks += 3 + dataTicksAccesint32(address) +
4751 codeTicksAccesint32(armNextPC);
4752 }
4753 break;
4754 case 0x790:
4755 case 0x798:
4756 {
4757 // LDR Rd, [Rn, Rm, LSL #]
4758 if (busPrefetchCount==0)
4759 busPrefetch = busPrefetchEnable;
4760 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4761 int dest = (opcode >> 12) & 15;
4762 int base = (opcode >> 16) & 15;
4763 uint32 address = reg[base].I + offset;
4764 reg[dest].I = CPUReadMemory(address);
4765 clockTicks = 0;
4766 if(dest == 15) {
4767 reg[15].I &= 0xFFFFFFFC;
4768 armNextPC = reg[15].I;
4769 reg[15].I += 4;
4770 ARM_PREFETCH;
4771 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4772 }
4773 clockTicks += 3 + dataTicksAccesint32(address) +
4774 codeTicksAccesint32(armNextPC);
4775 }
4776 break;
4777 case 0x792:
4778 case 0x79a:
4779 {
4780 // LDR Rd, [Rn, Rm, LSR #]
4781 if (busPrefetchCount==0)
4782 busPrefetch = busPrefetchEnable;
4783 int shift = (opcode >> 7) & 31;
4784 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4785 int dest = (opcode >> 12) & 15;
4786 int base = (opcode >> 16) & 15;
4787 uint32 address = reg[base].I + offset;
4788 reg[dest].I = CPUReadMemory(address);
4789 clockTicks = 0;
4790 if(dest == 15) {
4791 reg[15].I &= 0xFFFFFFFC;
4792 armNextPC = reg[15].I;
4793 reg[15].I += 4;
4794 ARM_PREFETCH;
4795 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4796 }
4797 clockTicks += 3 + dataTicksAccesint32(address) +
4798 codeTicksAccesint32(armNextPC);
4799 }
4800 break;
4801 case 0x794:
4802 case 0x79c:
4803 {
4804 // LDR Rd, [Rn, Rm, ASR #]
4805 if (busPrefetchCount==0)
4806 busPrefetch = busPrefetchEnable;
4807 int shift = (opcode >> 7) & 31;
4808 int offset;
4809 if(shift)
4810 offset = (int)((int32)reg[opcode & 15].I >> shift);
4811 else if(reg[opcode & 15].I & 0x80000000)
4812 offset = 0xFFFFFFFF;
4813 else
4814 offset = 0;
4815 int dest = (opcode >> 12) & 15;
4816 int base = (opcode >> 16) & 15;
4817 uint32 address = reg[base].I + offset;
4818 reg[dest].I = CPUReadMemory(address);
4819 clockTicks = 0;
4820 if(dest == 15) {
4821 reg[15].I &= 0xFFFFFFFC;
4822 armNextPC = reg[15].I;
4823 reg[15].I += 4;
4824 ARM_PREFETCH;
4825 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4826 }
4827 clockTicks += 3 + dataTicksAccesint32(address) +
4828 codeTicksAccesint32(armNextPC);
4829 }
4830 break;
4831 case 0x796:
4832 case 0x79e:
4833 {
4834 // LDR Rd, [Rn, Rm, ROR #]
4835 if (busPrefetchCount==0)
4836 busPrefetch = busPrefetchEnable;
4837 int shift = (opcode >> 7) & 31;
4838 uint32 value = reg[opcode & 15].I;
4839 if(shift) {
4840 ROR_VALUE;
4841 } else {
4842 RCR_VALUE;
4843 }
4844 int dest = (opcode >> 12) & 15;
4845 int base = (opcode >> 16) & 15;
4846 uint32 address = reg[base].I + value;
4847 reg[dest].I = CPUReadMemory(address);
4848 clockTicks = 0;
4849 if(dest == 15) {
4850 reg[15].I &= 0xFFFFFFFC;
4851 armNextPC = reg[15].I;
4852 reg[15].I += 4;
4853 ARM_PREFETCH;
4854 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4855 }
4856 clockTicks += 3 + dataTicksAccesint32(address) +
4857 codeTicksAccesint32(armNextPC);
4858 }
4859 break;
4860 case 0x7b0:
4861 case 0x7b8:
4862 {
4863 // LDR Rd, [Rn, Rm, LSL #]!
4864 if (busPrefetchCount==0)
4865 busPrefetch = busPrefetchEnable;
4866 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4867 int dest = (opcode >> 12) & 15;
4868 int base = (opcode >> 16) & 15;
4869 uint32 address = reg[base].I + offset;
4870 reg[dest].I = CPUReadMemory(address);
4871 if(dest != base)
4872 reg[base].I = address;
4873 clockTicks = 0;
4874 if(dest == 15) {
4875 reg[15].I &= 0xFFFFFFFC;
4876 armNextPC = reg[15].I;
4877 reg[15].I += 4;
4878 ARM_PREFETCH;
4879 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4880 }
4881 clockTicks += 3 + dataTicksAccesint32(address) +
4882 codeTicksAccesint32(armNextPC);
4883 }
4884 break;
4885 case 0x7b2:
4886 case 0x7ba:
4887 {
4888 // LDR Rd, [Rn, Rm, LSR #]!
4889 if (busPrefetchCount==0)
4890 busPrefetch = busPrefetchEnable;
4891 int shift = (opcode >> 7) & 31;
4892 int offset = shift ? reg[opcode & 15].I >> shift : 0;
4893 int dest = (opcode >> 12) & 15;
4894 int base = (opcode >> 16) & 15;
4895 uint32 address = reg[base].I + offset;
4896 reg[dest].I = CPUReadMemory(address);
4897 if(dest != base)
4898 reg[base].I = address;
4899 clockTicks = 0;
4900 if(dest == 15) {
4901 reg[15].I &= 0xFFFFFFFC;
4902 armNextPC = reg[15].I;
4903 reg[15].I += 4;
4904 ARM_PREFETCH;
4905 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4906 }
4907 clockTicks += 3 + dataTicksAccesint32(address) +
4908 codeTicksAccesint32(armNextPC);
4909 }
4910 break;
4911 case 0x7b4:
4912 case 0x7bc:
4913 {
4914 // LDR Rd, [Rn, Rm, ASR #]!
4915 if (busPrefetchCount==0)
4916 busPrefetch = busPrefetchEnable;
4917 int shift = (opcode >> 7) & 31;
4918 int offset;
4919 if(shift)
4920 offset = (int)((int32)reg[opcode & 15].I >> shift);
4921 else if(reg[opcode & 15].I & 0x80000000)
4922 offset = 0xFFFFFFFF;
4923 else
4924 offset = 0;
4925 int dest = (opcode >> 12) & 15;
4926 int base = (opcode >> 16) & 15;
4927 uint32 address = reg[base].I + offset;
4928 reg[dest].I = CPUReadMemory(address);
4929 if(dest != base)
4930 reg[base].I = address;
4931 clockTicks = 0;
4932 if(dest == 15) {
4933 reg[15].I &= 0xFFFFFFFC;
4934 armNextPC = reg[15].I;
4935 reg[15].I += 4;
4936 ARM_PREFETCH;
4937 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4938 }
4939 clockTicks += 3 + dataTicksAccesint32(address) +
4940 codeTicksAccesint32(armNextPC);
4941 }
4942 break;
4943 case 0x7b6:
4944 case 0x7be:
4945 {
4946 // LDR Rd, [Rn, Rm, ROR #]!
4947 if (busPrefetchCount==0)
4948 busPrefetch = busPrefetchEnable;
4949 int shift = (opcode >> 7) & 31;
4950 uint32 value = reg[opcode & 15].I;
4951 if(shift) {
4952 ROR_VALUE;
4953 } else {
4954 RCR_VALUE;
4955 }
4956 int dest = (opcode >> 12) & 15;
4957 int base = (opcode >> 16) & 15;
4958 uint32 address = reg[base].I + value;
4959 reg[dest].I = CPUReadMemory(address);
4960 if(dest != base)
4961 reg[base].I = address;
4962 clockTicks = 0;
4963 if(dest == 15) {
4964 reg[15].I &= 0xFFFFFFFC;
4965 armNextPC = reg[15].I;
4966 reg[15].I += 4;
4967 ARM_PREFETCH;
4968 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
4969 }
4970 clockTicks += 3 + dataTicksAccesint32(address) +
4971 codeTicksAccesint32(armNextPC);
4972 }
4973 break;
4974 case 0x640:
4975 case 0x648:
4976 // T versions are the same
4977 case 0x660:
4978 case 0x668:
4979 {
4980 // STRB Rd, [Rn], -Rm, LSL #
4981 if (busPrefetchCount==0)
4982 busPrefetch = busPrefetchEnable;
4983 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
4984 int dest = (opcode >> 12) & 15;
4985 int base = (opcode >> 16) & 15;
4986 uint32 address = reg[base].I;
4987 CPUWriteByte(address, reg[dest].B.B0);
4988 reg[base].I = address - offset;
4989 clockTicks = 2 + dataTicksAccesint16(address) +
4990 codeTicksAccesint32(armNextPC);
4991 }
4992 break;
4993 case 0x642:
4994 case 0x64a:
4995 // T versions are the same
4996 case 0x662:
4997 case 0x66a:
4998 {
4999 // STRB Rd, [Rn], -Rm, LSR #
5000 if (busPrefetchCount==0)
5001 busPrefetch = busPrefetchEnable;
5002 int shift = (opcode >> 7) & 31;
5003 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5004 int dest = (opcode >> 12) & 15;
5005 int base = (opcode >> 16) & 15;
5006 uint32 address = reg[base].I;
5007 CPUWriteByte(address, reg[dest].B.B0);
5008 reg[base].I = address - offset;
5009 clockTicks = 2 + dataTicksAccesint16(address) +
5010 codeTicksAccesint32(armNextPC);
5011 }
5012 break;
5013 case 0x644:
5014 case 0x64c:
5015 // T versions are the same
5016 case 0x664:
5017 case 0x66c:
5018 {
5019 // STRB Rd, [Rn], -Rm, ASR #
5020 if (busPrefetchCount==0)
5021 busPrefetch = busPrefetchEnable;
5022 int shift = (opcode >> 7) & 31;
5023 int offset;
5024 if(shift)
5025 offset = (int)((int32)reg[opcode & 15].I >> shift);
5026 else if(reg[opcode & 15].I & 0x80000000)
5027 offset = 0xFFFFFFFF;
5028 else
5029 offset = 0;
5030 int dest = (opcode >> 12) & 15;
5031 int base = (opcode >> 16) & 15;
5032 uint32 address = reg[base].I;
5033 CPUWriteByte(address, reg[dest].B.B0);
5034 reg[base].I = address - offset;
5035 clockTicks = 2 + dataTicksAccesint16(address) +
5036 codeTicksAccesint32(armNextPC);
5037 }
5038 break;
5039 case 0x646:
5040 case 0x64e:
5041 // T versions are the same
5042 case 0x666:
5043 case 0x66e:
5044 {
5045 // STRB Rd, [Rn], -Rm, ROR #
5046 if (busPrefetchCount==0)
5047 busPrefetch = busPrefetchEnable;
5048 int shift = (opcode >> 7) & 31;
5049 uint32 value = reg[opcode & 15].I;
5050 if(shift) {
5051 ROR_VALUE;
5052 } else {
5053 RCR_VALUE;
5054 }
5055 int dest = (opcode >> 12) & 15;
5056 int base = (opcode >> 16) & 15;
5057 uint32 address = reg[base].I;
5058 CPUWriteByte(address, reg[dest].B.B0);
5059 reg[base].I = address - value;
5060 clockTicks = 2 + dataTicksAccesint16(address) +
5061 codeTicksAccesint32(armNextPC);
5062 }
5063 break;
5064 case 0x6c0:
5065 case 0x6c8:
5066 // T versions are the same
5067 case 0x6e0:
5068 case 0x6e8:
5069 {
5070 // STRB Rd, [Rn], Rm, LSL #
5071 if (busPrefetchCount==0)
5072 busPrefetch = busPrefetchEnable;
5073 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5074 int dest = (opcode >> 12) & 15;
5075 int base = (opcode >> 16) & 15;
5076 uint32 address = reg[base].I;
5077 CPUWriteByte(address, reg[dest].B.B0);
5078 reg[base].I = address + offset;
5079 clockTicks = 2 + dataTicksAccesint16(address) +
5080 codeTicksAccesint32(armNextPC);
5081 }
5082 break;
5083 case 0x6c2:
5084 case 0x6ca:
5085 // T versions are the same
5086 case 0x6e2:
5087 case 0x6ea:
5088 {
5089 // STRB Rd, [Rn], Rm, LSR #
5090 if (busPrefetchCount==0)
5091 busPrefetch = busPrefetchEnable;
5092 int shift = (opcode >> 7) & 31;
5093 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5094 int dest = (opcode >> 12) & 15;
5095 int base = (opcode >> 16) & 15;
5096 uint32 address = reg[base].I;
5097 CPUWriteByte(address, reg[dest].B.B0);
5098 reg[base].I = address + offset;
5099 clockTicks = 2 + dataTicksAccesint16(address) +
5100 codeTicksAccesint32(armNextPC);
5101 }
5102 break;
5103 case 0x6c4:
5104 case 0x6cc:
5105 // T versions are the same
5106 case 0x6e4:
5107 case 0x6ec:
5108 {
5109 // STRB Rd, [Rn], Rm, ASR #
5110 if (busPrefetchCount==0)
5111 busPrefetch = busPrefetchEnable;
5112 int shift = (opcode >> 7) & 31;
5113 int offset;
5114 if(shift)
5115 offset = (int)((int32)reg[opcode & 15].I >> shift);
5116 else if(reg[opcode & 15].I & 0x80000000)
5117 offset = 0xFFFFFFFF;
5118 else
5119 offset = 0;
5120 int dest = (opcode >> 12) & 15;
5121 int base = (opcode >> 16) & 15;
5122 uint32 address = reg[base].I;
5123 CPUWriteByte(address, reg[dest].B.B0);
5124 reg[base].I = address + offset;
5125 clockTicks = 2 + dataTicksAccesint16(address) +
5126 codeTicksAccesint32(armNextPC);
5127 }
5128 break;
5129 case 0x6c6:
5130 case 0x6ce:
5131 // T versions are the same
5132 case 0x6e6:
5133 case 0x6ee:
5134 {
5135 // STRB Rd, [Rn], Rm, ROR #
5136 if (busPrefetchCount==0)
5137 busPrefetch = busPrefetchEnable;
5138 int shift = (opcode >> 7) & 31;
5139 uint32 value = reg[opcode & 15].I;
5140 if(shift) {
5141 ROR_VALUE;
5142 } else {
5143 RCR_VALUE;
5144 }
5145 int dest = (opcode >> 12) & 15;
5146 int base = (opcode >> 16) & 15;
5147 uint32 address = reg[base].I;
5148 CPUWriteByte(address, reg[dest].B.B0);
5149 reg[base].I = address + value;
5150 clockTicks = 2 + dataTicksAccesint16(address) +
5151 codeTicksAccesint32(armNextPC);
5152 }
5153 break;
5154 case 0x740:
5155 case 0x748:
5156 {
5157 // STRB Rd, [Rn, -Rm, LSL #]
5158 if (busPrefetchCount==0)
5159 busPrefetch = busPrefetchEnable;
5160 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5161 int dest = (opcode >> 12) & 15;
5162 int base = (opcode >> 16) & 15;
5163 uint32 address = reg[base].I - offset;
5164 CPUWriteByte(address, reg[dest].B.B0);
5165 clockTicks = 2 + dataTicksAccesint16(address) +
5166 codeTicksAccesint32(armNextPC);
5167 }
5168 break;
5169 case 0x742:
5170 case 0x74a:
5171 {
5172 // STRB Rd, [Rn, -Rm, LSR #]
5173 if (busPrefetchCount==0)
5174 busPrefetch = busPrefetchEnable;
5175 int shift = (opcode >> 7) & 31;
5176 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5177 int dest = (opcode >> 12) & 15;
5178 int base = (opcode >> 16) & 15;
5179 uint32 address = reg[base].I - offset;
5180 CPUWriteByte(address, reg[dest].B.B0);
5181 clockTicks = 2 + dataTicksAccesint16(address) +
5182 codeTicksAccesint32(armNextPC);
5183 }
5184 break;
5185 case 0x744:
5186 case 0x74c:
5187 {
5188 // STRB Rd, [Rn, -Rm, ASR #]
5189 if (busPrefetchCount==0)
5190 busPrefetch = busPrefetchEnable;
5191 int shift = (opcode >> 7) & 31;
5192 int offset;
5193 if(shift)
5194 offset = (int)((int32)reg[opcode & 15].I >> shift);
5195 else if(reg[opcode & 15].I & 0x80000000)
5196 offset = 0xFFFFFFFF;
5197 else
5198 offset = 0;
5199 int dest = (opcode >> 12) & 15;
5200 int base = (opcode >> 16) & 15;
5201 uint32 address = reg[base].I - offset;
5202 CPUWriteByte(address, reg[dest].B.B0);
5203 clockTicks = 2 + dataTicksAccesint16(address) +
5204 codeTicksAccesint32(armNextPC);
5205 }
5206 break;
5207 case 0x746:
5208 case 0x74e:
5209 {
5210 // STRB Rd, [Rn, -Rm, ROR #]
5211 if (busPrefetchCount==0)
5212 busPrefetch = busPrefetchEnable;
5213 int shift = (opcode >> 7) & 31;
5214 uint32 value = reg[opcode & 15].I;
5215 if(shift) {
5216 ROR_VALUE;
5217 } else {
5218 RCR_VALUE;
5219 }
5220 int dest = (opcode >> 12) & 15;
5221 int base = (opcode >> 16) & 15;
5222 uint32 address = reg[base].I - value;
5223 CPUWriteByte(address, reg[dest].B.B0);
5224 clockTicks = 2 + dataTicksAccesint16(address) +
5225 codeTicksAccesint32(armNextPC);
5226 }
5227 break;
5228 case 0x760:
5229 case 0x768:
5230 {
5231 // STRB Rd, [Rn, -Rm, LSL #]!
5232 if (busPrefetchCount==0)
5233 busPrefetch = busPrefetchEnable;
5234 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5235 int dest = (opcode >> 12) & 15;
5236 int base = (opcode >> 16) & 15;
5237 uint32 address = reg[base].I - offset;
5238 reg[base].I = address;
5239 CPUWriteByte(address, reg[dest].B.B0);
5240 clockTicks = 2 + dataTicksAccesint16(address) +
5241 codeTicksAccesint32(armNextPC);
5242 }
5243 break;
5244 case 0x762:
5245 case 0x76a:
5246 {
5247 // STRB Rd, [Rn, -Rm, LSR #]!
5248 if (busPrefetchCount==0)
5249 busPrefetch = busPrefetchEnable;
5250 int shift = (opcode >> 7) & 31;
5251 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5252 int dest = (opcode >> 12) & 15;
5253 int base = (opcode >> 16) & 15;
5254 uint32 address = reg[base].I - offset;
5255 reg[base].I = address;
5256 CPUWriteByte(address, reg[dest].B.B0);
5257 clockTicks = 2 + dataTicksAccesint16(address) +
5258 codeTicksAccesint32(armNextPC);
5259 }
5260 break;
5261 case 0x764:
5262 case 0x76c:
5263 {
5264 // STRB Rd, [Rn, -Rm, ASR #]!
5265 if (busPrefetchCount==0)
5266 busPrefetch = busPrefetchEnable;
5267 int shift = (opcode >> 7) & 31;
5268 int offset;
5269 if(shift)
5270 offset = (int)((int32)reg[opcode & 15].I >> shift);
5271 else if(reg[opcode & 15].I & 0x80000000)
5272 offset = 0xFFFFFFFF;
5273 else
5274 offset = 0;
5275 int dest = (opcode >> 12) & 15;
5276 int base = (opcode >> 16) & 15;
5277 uint32 address = reg[base].I - offset;
5278 reg[base].I = address;
5279 CPUWriteByte(address, reg[dest].B.B0);
5280 clockTicks = 2 + dataTicksAccesint16(address) +
5281 codeTicksAccesint32(armNextPC);
5282 }
5283 break;
5284 case 0x766:
5285 case 0x76e:
5286 {
5287 // STRB Rd, [Rn, -Rm, ROR #]!
5288 if (busPrefetchCount==0)
5289 busPrefetch = busPrefetchEnable;
5290 int shift = (opcode >> 7) & 31;
5291 uint32 value = reg[opcode & 15].I;
5292 if(shift) {
5293 ROR_VALUE;
5294 } else {
5295 RCR_VALUE;
5296 }
5297 int dest = (opcode >> 12) & 15;
5298 int base = (opcode >> 16) & 15;
5299 uint32 address = reg[base].I - value;
5300 reg[base].I = address;
5301 CPUWriteByte(address, reg[dest].B.B0);
5302 clockTicks = 2 + dataTicksAccesint16(address) +
5303 codeTicksAccesint32(armNextPC);
5304 }
5305 break;
5306 case 0x7c0:
5307 case 0x7c8:
5308 {
5309 // STRB Rd, [Rn, Rm, LSL #]
5310 if (busPrefetchCount==0)
5311 busPrefetch = busPrefetchEnable;
5312 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5313 int dest = (opcode >> 12) & 15;
5314 int base = (opcode >> 16) & 15;
5315 uint32 address = reg[base].I + offset;
5316 CPUWriteByte(address, reg[dest].B.B0);
5317 clockTicks = 2 + dataTicksAccesint16(address) +
5318 codeTicksAccesint32(armNextPC);
5319 }
5320 break;
5321 case 0x7c2:
5322 case 0x7ca:
5323 {
5324 // STRB Rd, [Rn, Rm, LSR #]
5325 if (busPrefetchCount==0)
5326 busPrefetch = busPrefetchEnable;
5327 int shift = (opcode >> 7) & 31;
5328 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5329 int dest = (opcode >> 12) & 15;
5330 int base = (opcode >> 16) & 15;
5331 uint32 address = reg[base].I + offset;
5332 CPUWriteByte(address, reg[dest].B.B0);
5333 clockTicks = 2 + dataTicksAccesint16(address) +
5334 codeTicksAccesint32(armNextPC);
5335 }
5336 break;
5337 case 0x7c4:
5338 case 0x7cc:
5339 {
5340 // STRB Rd, [Rn, Rm, ASR #]
5341 if (busPrefetchCount==0)
5342 busPrefetch = busPrefetchEnable;
5343 int shift = (opcode >> 7) & 31;
5344 int offset;
5345 if(shift)
5346 offset = (int)((int32)reg[opcode & 15].I >> shift);
5347 else if(reg[opcode & 15].I & 0x80000000)
5348 offset = 0xFFFFFFFF;
5349 else
5350 offset = 0;
5351 int dest = (opcode >> 12) & 15;
5352 int base = (opcode >> 16) & 15;
5353 uint32 address = reg[base].I + offset;
5354 CPUWriteByte(address, reg[dest].B.B0);
5355 clockTicks = 2 + dataTicksAccesint16(address) +
5356 codeTicksAccesint32(armNextPC);
5357 }
5358 break;
5359 case 0x7c6:
5360 case 0x7ce:
5361 {
5362 // STRB Rd, [Rn, Rm, ROR #]
5363 if (busPrefetchCount==0)
5364 busPrefetch = busPrefetchEnable;
5365 int shift = (opcode >> 7) & 31;
5366 uint32 value = reg[opcode & 15].I;
5367 if(shift) {
5368 ROR_VALUE;
5369 } else {
5370 RCR_VALUE;
5371 }
5372 int dest = (opcode >> 12) & 15;
5373 int base = (opcode >> 16) & 15;
5374 uint32 address = reg[base].I + value;
5375 CPUWriteByte(address, reg[dest].B.B0);
5376 clockTicks = 2 + dataTicksAccesint16(address) +
5377 codeTicksAccesint32(armNextPC);
5378 }
5379 break;
5380 case 0x7e0:
5381 case 0x7e8:
5382 {
5383 // STRB Rd, [Rn, Rm, LSL #]!
5384 if (busPrefetchCount==0)
5385 busPrefetch = busPrefetchEnable;
5386 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5387 int dest = (opcode >> 12) & 15;
5388 int base = (opcode >> 16) & 15;
5389 uint32 address = reg[base].I + offset;
5390 reg[base].I = address;
5391 CPUWriteByte(address, reg[dest].B.B0);
5392 clockTicks = 2 + dataTicksAccesint16(address) +
5393 codeTicksAccesint32(armNextPC);
5394 }
5395 break;
5396 case 0x7e2:
5397 case 0x7ea:
5398 {
5399 // STRB Rd, [Rn, Rm, LSR #]!
5400 if (busPrefetchCount==0)
5401 busPrefetch = busPrefetchEnable;
5402 int shift = (opcode >> 7) & 31;
5403 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5404 int dest = (opcode >> 12) & 15;
5405 int base = (opcode >> 16) & 15;
5406 uint32 address = reg[base].I + offset;
5407 reg[base].I = address;
5408 CPUWriteByte(address, reg[dest].B.B0);
5409 clockTicks = 2 + dataTicksAccesint16(address) +
5410 codeTicksAccesint32(armNextPC);
5411 }
5412 break;
5413 case 0x7e4:
5414 case 0x7ec:
5415 {
5416 // STRB Rd, [Rn, Rm, ASR #]!
5417 if (busPrefetchCount==0)
5418 busPrefetch = busPrefetchEnable;
5419 int shift = (opcode >> 7) & 31;
5420 int offset;
5421 if(shift)
5422 offset = (int)((int32)reg[opcode & 15].I >> shift);
5423 else if(reg[opcode & 15].I & 0x80000000)
5424 offset = 0xFFFFFFFF;
5425 else
5426 offset = 0;
5427 int dest = (opcode >> 12) & 15;
5428 int base = (opcode >> 16) & 15;
5429 uint32 address = reg[base].I + offset;
5430 reg[base].I = address;
5431 CPUWriteByte(address, reg[dest].B.B0);
5432 clockTicks = 2 + dataTicksAccesint16(address) +
5433 codeTicksAccesint32(armNextPC);
5434 }
5435 break;
5436 case 0x7e6:
5437 case 0x7ee:
5438 {
5439 // STRB Rd, [Rn, Rm, ROR #]!
5440 if (busPrefetchCount==0)
5441 busPrefetch = busPrefetchEnable;
5442 int shift = (opcode >> 7) & 31;
5443 uint32 value = reg[opcode & 15].I;
5444 if(shift) {
5445 ROR_VALUE;
5446 } else {
5447 RCR_VALUE;
5448 }
5449 int dest = (opcode >> 12) & 15;
5450 int base = (opcode >> 16) & 15;
5451 uint32 address = reg[base].I + value;
5452 reg[base].I = address;
5453 CPUWriteByte(address, reg[dest].B.B0);
5454 clockTicks = 2 + dataTicksAccesint16(address) +
5455 codeTicksAccesint32(armNextPC);
5456 }
5457 break;
5458 case 0x650:
5459 case 0x658:
5460 // T versions are the same
5461 case 0x670:
5462 case 0x678:
5463 {
5464 // LDRB Rd, [Rn], -Rm, LSL #
5465 if (busPrefetchCount==0)
5466 busPrefetch = busPrefetchEnable;
5467 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5468 int dest = (opcode >> 12) & 15;
5469 int base = (opcode >> 16) & 15;
5470 uint32 address = reg[base].I;
5471 reg[dest].I = CPUReadByte(address);
5472 if(dest != base)
5473 reg[base].I = address - offset;
5474 clockTicks = 0;
5475 if(dest == 15) {
5476 reg[15].I &= 0xFFFFFFFC;
5477 armNextPC = reg[15].I;
5478 reg[15].I += 4;
5479 ARM_PREFETCH;
5480 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5481 }
5482 clockTicks += 3 + dataTicksAccesint16(address) +
5483 codeTicksAccesint32(armNextPC);
5484 }
5485 break;
5486 case 0x652:
5487 case 0x65a:
5488 // T versions are the same
5489 case 0x672:
5490 case 0x67a:
5491 {
5492 // LDRB Rd, [Rn], -Rm, LSR #
5493 if (busPrefetchCount==0)
5494 busPrefetch = busPrefetchEnable;
5495 int shift = (opcode >> 7) & 31;
5496 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5497 int dest = (opcode >> 12) & 15;
5498 int base = (opcode >> 16) & 15;
5499 uint32 address = reg[base].I;
5500 reg[dest].I = CPUReadByte(address);
5501 if(dest != base)
5502 reg[base].I = address - offset;
5503 clockTicks = 0;
5504 if(dest == 15) {
5505 reg[15].I &= 0xFFFFFFFC;
5506 armNextPC = reg[15].I;
5507 reg[15].I += 4;
5508 ARM_PREFETCH;
5509 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5510 }
5511 clockTicks += 3 + dataTicksAccesint16(address) +
5512 codeTicksAccesint32(armNextPC);
5513 }
5514 break;
5515 case 0x654:
5516 case 0x65c:
5517 // T versions are the same
5518 case 0x674:
5519 case 0x67c:
5520 {
5521 // LDRB Rd, [Rn], -Rm, ASR #
5522 if (busPrefetchCount==0)
5523 busPrefetch = busPrefetchEnable;
5524 int shift = (opcode >> 7) & 31;
5525 int offset;
5526 if(shift)
5527 offset = (int)((int32)reg[opcode & 15].I >> shift);
5528 else if(reg[opcode & 15].I & 0x80000000)
5529 offset = 0xFFFFFFFF;
5530 else
5531 offset = 0;
5532 int dest = (opcode >> 12) & 15;
5533 int base = (opcode >> 16) & 15;
5534 uint32 address = reg[base].I;
5535 reg[dest].I = CPUReadByte(address);
5536 if(dest != base)
5537 reg[base].I = address - offset;
5538 clockTicks = 0;
5539 if(dest == 15) {
5540 reg[15].I &= 0xFFFFFFFC;
5541 armNextPC = reg[15].I;
5542 reg[15].I += 4;
5543 ARM_PREFETCH;
5544 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5545 }
5546 clockTicks += 3 + dataTicksAccesint16(address) +
5547 codeTicksAccesint32(armNextPC);
5548 }
5549 break;
5550 case 0x656:
5551 case 0x65e:
5552 // T versions are the same
5553 case 0x676:
5554 case 0x67e:
5555 {
5556 // LDRB Rd, [Rn], -Rm, ROR #
5557 if (busPrefetchCount==0)
5558 busPrefetch = busPrefetchEnable;
5559 int shift = (opcode >> 7) & 31;
5560 uint32 value = reg[opcode & 15].I;
5561 if(shift) {
5562 ROR_VALUE;
5563 } else {
5564 RCR_VALUE;
5565 }
5566 int dest = (opcode >> 12) & 15;
5567 int base = (opcode >> 16) & 15;
5568 uint32 address = reg[base].I;
5569 reg[dest].I = CPUReadByte(address);
5570 if(dest != base)
5571 reg[base].I = address - value;
5572 clockTicks = 0;
5573 if(dest == 15) {
5574 reg[15].I &= 0xFFFFFFFC;
5575 armNextPC = reg[15].I;
5576 reg[15].I += 4;
5577 ARM_PREFETCH;
5578 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5579 }
5580 clockTicks += 3 + dataTicksAccesint16(address) +
5581 codeTicksAccesint32(armNextPC);
5582 }
5583 break;
5584 case 0x6d0:
5585 case 0x6d8:
5586 // T versions are the same
5587 case 0x6f0:
5588 case 0x6f8:
5589 {
5590 // LDRB Rd, [Rn], Rm, LSL #
5591 if (busPrefetchCount==0)
5592 busPrefetch = busPrefetchEnable;
5593 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5594 int dest = (opcode >> 12) & 15;
5595 int base = (opcode >> 16) & 15;
5596 uint32 address = reg[base].I;
5597 reg[dest].I = CPUReadByte(address);
5598 if(dest != base)
5599 reg[base].I = address + offset;
5600 clockTicks = 0;
5601 if(dest == 15) {
5602 reg[15].I &= 0xFFFFFFFC;
5603 armNextPC = reg[15].I;
5604 reg[15].I += 4;
5605 ARM_PREFETCH;
5606 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5607 }
5608 clockTicks += 3 + dataTicksAccesint16(address) +
5609 codeTicksAccesint32(armNextPC);
5610 }
5611 break;
5612 case 0x6d2:
5613 case 0x6da:
5614 // T versions are the same
5615 case 0x6f2:
5616 case 0x6fa:
5617 {
5618 // LDRB Rd, [Rn], Rm, LSR #
5619 if (busPrefetchCount==0)
5620 busPrefetch = busPrefetchEnable;
5621 int shift = (opcode >> 7) & 31;
5622 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5623 int dest = (opcode >> 12) & 15;
5624 int base = (opcode >> 16) & 15;
5625 uint32 address = reg[base].I;
5626 reg[dest].I = CPUReadByte(address);
5627 if(dest != base)
5628 reg[base].I = address + offset;
5629 clockTicks = 0;
5630 if(dest == 15) {
5631 reg[15].I &= 0xFFFFFFFC;
5632 armNextPC = reg[15].I;
5633 reg[15].I += 4;
5634 ARM_PREFETCH;
5635 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5636 }
5637 clockTicks += 3 + dataTicksAccesint16(address) +
5638 codeTicksAccesint32(armNextPC);
5639 }
5640 break;
5641 case 0x6d4:
5642 case 0x6dc:
5643 // T versions are the same
5644 case 0x6f4:
5645 case 0x6fc:
5646 {
5647 // LDRB Rd, [Rn], Rm, ASR #
5648 if (busPrefetchCount==0)
5649 busPrefetch = busPrefetchEnable;
5650 int shift = (opcode >> 7) & 31;
5651 int offset;
5652 if(shift)
5653 offset = (int)((int32)reg[opcode & 15].I >> shift);
5654 else if(reg[opcode & 15].I & 0x80000000)
5655 offset = 0xFFFFFFFF;
5656 else
5657 offset = 0;
5658 int dest = (opcode >> 12) & 15;
5659 int base = (opcode >> 16) & 15;
5660 uint32 address = reg[base].I;
5661 reg[dest].I = CPUReadByte(address);
5662 if(dest != base)
5663 reg[base].I = address + offset;
5664 clockTicks = 0;
5665 if(dest == 15) {
5666 reg[15].I &= 0xFFFFFFFC;
5667 armNextPC = reg[15].I;
5668 reg[15].I += 4;
5669 ARM_PREFETCH;
5670 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5671 }
5672 clockTicks += 3 + dataTicksAccesint16(address) +
5673 codeTicksAccesint32(armNextPC);
5674 }
5675 break;
5676 case 0x6d6:
5677 case 0x6de:
5678 // T versions are the same
5679 case 0x6f6:
5680 case 0x6fe:
5681 {
5682 // LDRB Rd, [Rn], Rm, ROR #
5683 if (busPrefetchCount==0)
5684 busPrefetch = busPrefetchEnable;
5685 int shift = (opcode >> 7) & 31;
5686 uint32 value = reg[opcode & 15].I;
5687 if(shift) {
5688 ROR_VALUE;
5689 } else {
5690 RCR_VALUE;
5691 }
5692 int dest = (opcode >> 12) & 15;
5693 int base = (opcode >> 16) & 15;
5694 uint32 address = reg[base].I;
5695 reg[dest].I = CPUReadByte(address);
5696 if(dest != base)
5697 reg[base].I = address + value;
5698 clockTicks = 0;
5699 if(dest == 15) {
5700 reg[15].I &= 0xFFFFFFFC;
5701 armNextPC = reg[15].I;
5702 reg[15].I += 4;
5703 ARM_PREFETCH;
5704 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5705 }
5706 clockTicks += 3 + dataTicksAccesint16(address) +
5707 codeTicksAccesint32(armNextPC);
5708 }
5709 break;
5710 case 0x750:
5711 case 0x758:
5712 {
5713 // LDRB Rd, [Rn, -Rm, LSL #]
5714 if (busPrefetchCount==0)
5715 busPrefetch = busPrefetchEnable;
5716 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5717 int dest = (opcode >> 12) & 15;
5718 int base = (opcode >> 16) & 15;
5719 uint32 address = reg[base].I - offset;
5720 reg[dest].I = CPUReadByte(address);
5721 clockTicks = 0;
5722 if(dest == 15) {
5723 reg[15].I &= 0xFFFFFFFC;
5724 armNextPC = reg[15].I;
5725 reg[15].I += 4;
5726 ARM_PREFETCH;
5727 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5728 }
5729 clockTicks += 3 + dataTicksAccesint16(address) +
5730 codeTicksAccesint32(armNextPC);
5731 }
5732 break;
5733 case 0x752:
5734 case 0x75a:
5735 {
5736 // LDRB Rd, [Rn, -Rm, LSR #]
5737 if (busPrefetchCount==0)
5738 busPrefetch = busPrefetchEnable;
5739 int shift = (opcode >> 7) & 31;
5740 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5741 int dest = (opcode >> 12) & 15;
5742 int base = (opcode >> 16) & 15;
5743 uint32 address = reg[base].I - offset;
5744 reg[dest].I = CPUReadByte(address);
5745 clockTicks = 0;
5746 if(dest == 15) {
5747 reg[15].I &= 0xFFFFFFFC;
5748 armNextPC = reg[15].I;
5749 reg[15].I += 4;
5750 ARM_PREFETCH;
5751 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5752 }
5753 clockTicks += 3 + dataTicksAccesint16(address) +
5754 codeTicksAccesint32(armNextPC);
5755 }
5756 break;
5757 case 0x754:
5758 case 0x75c:
5759 {
5760 // LDRB Rd, [Rn, -Rm, ASR #]
5761 if (busPrefetchCount==0)
5762 busPrefetch = busPrefetchEnable;
5763 int shift = (opcode >> 7) & 31;
5764 int offset;
5765 if(shift)
5766 offset = (int)((int32)reg[opcode & 15].I >> shift);
5767 else if(reg[opcode & 15].I & 0x80000000)
5768 offset = 0xFFFFFFFF;
5769 else
5770 offset = 0;
5771 int dest = (opcode >> 12) & 15;
5772 int base = (opcode >> 16) & 15;
5773 uint32 address = reg[base].I - offset;
5774 reg[dest].I = CPUReadByte(address);
5775 clockTicks = 0;
5776 if(dest == 15) {
5777 reg[15].I &= 0xFFFFFFFC;
5778 armNextPC = reg[15].I;
5779 reg[15].I += 4;
5780 ARM_PREFETCH;
5781 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5782 }
5783 clockTicks += 3 + dataTicksAccesint16(address) +
5784 codeTicksAccesint32(armNextPC);
5785 }
5786 break;
5787 case 0x756:
5788 case 0x75e:
5789 {
5790 // LDRB Rd, [Rn, -Rm, ROR #]
5791 if (busPrefetchCount==0)
5792 busPrefetch = busPrefetchEnable;
5793 int shift = (opcode >> 7) & 31;
5794 uint32 value = reg[opcode & 15].I;
5795 if(shift) {
5796 ROR_VALUE;
5797 } else {
5798 RCR_VALUE;
5799 }
5800 int dest = (opcode >> 12) & 15;
5801 int base = (opcode >> 16) & 15;
5802 uint32 address = reg[base].I - value;
5803 reg[dest].I = CPUReadByte(address);
5804 clockTicks = 0;
5805 if(dest == 15) {
5806 reg[15].I &= 0xFFFFFFFC;
5807 armNextPC = reg[15].I;
5808 reg[15].I += 4;
5809 ARM_PREFETCH;
5810 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5811 }
5812 clockTicks += 3 + dataTicksAccesint16(address) +
5813 codeTicksAccesint32(armNextPC);
5814 }
5815 break;
5816 case 0x770:
5817 case 0x778:
5818 {
5819 // LDRB Rd, [Rn, -Rm, LSL #]!
5820 if (busPrefetchCount==0)
5821 busPrefetch = busPrefetchEnable;
5822 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5823 int dest = (opcode >> 12) & 15;
5824 int base = (opcode >> 16) & 15;
5825 uint32 address = reg[base].I - offset;
5826 reg[dest].I = CPUReadByte(address);
5827 if(dest != base)
5828 reg[base].I = address;
5829 clockTicks = 0;
5830 if(dest == 15) {
5831 reg[15].I &= 0xFFFFFFFC;
5832 armNextPC = reg[15].I;
5833 reg[15].I += 4;
5834 ARM_PREFETCH;
5835 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5836 }
5837 clockTicks += 3 + dataTicksAccesint16(address) +
5838 codeTicksAccesint32(armNextPC);
5839 }
5840 break;
5841 case 0x772:
5842 case 0x77a:
5843 {
5844 // LDRB Rd, [Rn, -Rm, LSR #]!
5845 if (busPrefetchCount==0)
5846 busPrefetch = busPrefetchEnable;
5847 int shift = (opcode >> 7) & 31;
5848 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5849 int dest = (opcode >> 12) & 15;
5850 int base = (opcode >> 16) & 15;
5851 uint32 address = reg[base].I - offset;
5852 reg[dest].I = CPUReadByte(address);
5853 if(dest != base)
5854 reg[base].I = address;
5855 clockTicks = 0;
5856 if(dest == 15) {
5857 reg[15].I &= 0xFFFFFFFC;
5858 armNextPC = reg[15].I;
5859 reg[15].I += 4;
5860 ARM_PREFETCH;
5861 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5862 }
5863 clockTicks += 3 + dataTicksAccesint16(address) +
5864 codeTicksAccesint32(armNextPC);
5865 }
5866 break;
5867 case 0x774:
5868 case 0x77c:
5869 {
5870 // LDRB Rd, [Rn, -Rm, ASR #]!
5871 if (busPrefetchCount==0)
5872 busPrefetch = busPrefetchEnable;
5873 int shift = (opcode >> 7) & 31;
5874 int offset;
5875 if(shift)
5876 offset = (int)((int32)reg[opcode & 15].I >> shift);
5877 else if(reg[opcode & 15].I & 0x80000000)
5878 offset = 0xFFFFFFFF;
5879 else
5880 offset = 0;
5881 int dest = (opcode >> 12) & 15;
5882 int base = (opcode >> 16) & 15;
5883 uint32 address = reg[base].I - offset;
5884 reg[dest].I = CPUReadByte(address);
5885 if(dest != base)
5886 reg[base].I = address;
5887 clockTicks = 0;
5888 if(dest == 15) {
5889 reg[15].I &= 0xFFFFFFFC;
5890 armNextPC = reg[15].I;
5891 reg[15].I += 4;
5892 ARM_PREFETCH;
5893 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5894 }
5895 clockTicks += 3 + dataTicksAccesint16(address) +
5896 codeTicksAccesint32(armNextPC);
5897 }
5898 break;
5899 case 0x776:
5900 case 0x77e:
5901 {
5902 // LDRB Rd, [Rn, -Rm, ROR #]!
5903 if (busPrefetchCount==0)
5904 busPrefetch = busPrefetchEnable;
5905 int shift = (opcode >> 7) & 31;
5906 uint32 value = reg[opcode & 15].I;
5907 if(shift) {
5908 ROR_VALUE;
5909 } else {
5910 RCR_VALUE;
5911 }
5912 int dest = (opcode >> 12) & 15;
5913 int base = (opcode >> 16) & 15;
5914 uint32 address = reg[base].I - value;
5915 reg[dest].I = CPUReadByte(address);
5916 if(dest != base)
5917 reg[base].I = address;
5918 clockTicks = 0;
5919 if(dest == 15) {
5920 reg[15].I &= 0xFFFFFFFC;
5921 armNextPC = reg[15].I;
5922 reg[15].I += 4;
5923 ARM_PREFETCH;
5924 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5925 }
5926 clockTicks += 3 + dataTicksAccesint16(address) +
5927 codeTicksAccesint32(armNextPC);
5928 }
5929 break;
5930 case 0x7d0:
5931 case 0x7d8:
5932 {
5933 // LDRB Rd, [Rn, Rm, LSL #]
5934 if (busPrefetchCount==0)
5935 busPrefetch = busPrefetchEnable;
5936 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
5937 int dest = (opcode >> 12) & 15;
5938 int base = (opcode >> 16) & 15;
5939 uint32 address = reg[base].I + offset;
5940 reg[dest].I = CPUReadByte(address);
5941 clockTicks = 0;
5942 if(dest == 15) {
5943 reg[15].I &= 0xFFFFFFFC;
5944 armNextPC = reg[15].I;
5945 reg[15].I += 4;
5946 ARM_PREFETCH;
5947 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5948 }
5949 clockTicks += 3 + dataTicksAccesint16(address) +
5950 codeTicksAccesint32(armNextPC);
5951 }
5952 break;
5953 case 0x7d2:
5954 case 0x7da:
5955 {
5956 // LDRB Rd, [Rn, Rm, LSR #]
5957 if (busPrefetchCount==0)
5958 busPrefetch = busPrefetchEnable;
5959 int shift = (opcode >> 7) & 31;
5960 int offset = shift ? reg[opcode & 15].I >> shift : 0;
5961 int dest = (opcode >> 12) & 15;
5962 int base = (opcode >> 16) & 15;
5963 uint32 address = reg[base].I + offset;
5964 reg[dest].I = CPUReadByte(address);
5965 clockTicks = 0;
5966 if(dest == 15) {
5967 reg[15].I &= 0xFFFFFFFC;
5968 armNextPC = reg[15].I;
5969 reg[15].I += 4;
5970 ARM_PREFETCH;
5971 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
5972 }
5973 clockTicks += 3 + dataTicksAccesint16(address) +
5974 codeTicksAccesint32(armNextPC);
5975 }
5976 break;
5977 case 0x7d4:
5978 case 0x7dc:
5979 {
5980 // LDRB Rd, [Rn, Rm, ASR #]
5981 if (busPrefetchCount==0)
5982 busPrefetch = busPrefetchEnable;
5983 int shift = (opcode >> 7) & 31;
5984 int offset;
5985 if(shift)
5986 offset = (int)((int32)reg[opcode & 15].I >> shift);
5987 else if(reg[opcode & 15].I & 0x80000000)
5988 offset = 0xFFFFFFFF;
5989 else
5990 offset = 0;
5991 int dest = (opcode >> 12) & 15;
5992 int base = (opcode >> 16) & 15;
5993 uint32 address = reg[base].I + offset;
5994 reg[dest].I = CPUReadByte(address);
5995 clockTicks = 0;
5996 if(dest == 15) {
5997 reg[15].I &= 0xFFFFFFFC;
5998 armNextPC = reg[15].I;
5999 reg[15].I += 4;
6000 ARM_PREFETCH;
6001 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6002 }
6003 clockTicks += 3 + dataTicksAccesint16(address) +
6004 codeTicksAccesint32(armNextPC);
6005 }
6006 break;
6007 case 0x7d6:
6008 case 0x7de:
6009 {
6010 // LDRB Rd, [Rn, Rm, ROR #]
6011 if (busPrefetchCount==0)
6012 busPrefetch = busPrefetchEnable;
6013 int shift = (opcode >> 7) & 31;
6014 uint32 value = reg[opcode & 15].I;
6015 if(shift) {
6016 ROR_VALUE;
6017 } else {
6018 RCR_VALUE;
6019 }
6020 int dest = (opcode >> 12) & 15;
6021 int base = (opcode >> 16) & 15;
6022 uint32 address = reg[base].I + value;
6023 reg[dest].I = CPUReadByte(address);
6024 clockTicks = 0;
6025 if(dest == 15) {
6026 reg[15].I &= 0xFFFFFFFC;
6027 armNextPC = reg[15].I;
6028 reg[15].I += 4;
6029 ARM_PREFETCH;
6030 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6031 }
6032 clockTicks += 3 + dataTicksAccesint16(address) +
6033 codeTicksAccesint32(armNextPC);
6034 }
6035 break;
6036 case 0x7f0:
6037 case 0x7f8:
6038 {
6039 // LDRB Rd, [Rn, Rm, LSL #]!
6040 if (busPrefetchCount==0)
6041 busPrefetch = busPrefetchEnable;
6042 int offset = reg[opcode & 15].I << ((opcode>>7)& 31);
6043 int dest = (opcode >> 12) & 15;
6044 int base = (opcode >> 16) & 15;
6045 uint32 address = reg[base].I + offset;
6046 reg[dest].I = CPUReadByte(address);
6047 if(dest != base)
6048 reg[base].I = address;
6049 clockTicks = 0;
6050 if(dest == 15) {
6051 reg[15].I &= 0xFFFFFFFC;
6052 armNextPC = reg[15].I;
6053 reg[15].I += 4;
6054 ARM_PREFETCH;
6055 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6056 }
6057 clockTicks += 3 + dataTicksAccesint16(address) +
6058 codeTicksAccesint32(armNextPC);
6059 }
6060 break;
6061 case 0x7f2:
6062 case 0x7fa:
6063 {
6064 // LDRB Rd, [Rn, Rm, LSR #]!
6065 if (busPrefetchCount==0)
6066 busPrefetch = busPrefetchEnable;
6067 int shift = (opcode >> 7) & 31;
6068 int offset = shift ? reg[opcode & 15].I >> shift : 0;
6069 int dest = (opcode >> 12) & 15;
6070 int base = (opcode >> 16) & 15;
6071 uint32 address = reg[base].I + offset;
6072 reg[dest].I = CPUReadByte(address);
6073 if(dest != base)
6074 reg[base].I = address;
6075 clockTicks = 0;
6076 if(dest == 15) {
6077 reg[15].I &= 0xFFFFFFFC;
6078 armNextPC = reg[15].I;
6079 reg[15].I += 4;
6080 ARM_PREFETCH;
6081 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6082 }
6083 clockTicks += 3 + dataTicksAccesint16(address) +
6084 codeTicksAccesint32(armNextPC);
6085 }
6086 break;
6087 case 0x7f4:
6088 case 0x7fc:
6089 {
6090 // LDRB Rd, [Rn, Rm, ASR #]!
6091 if (busPrefetchCount==0)
6092 busPrefetch = busPrefetchEnable;
6093 int shift = (opcode >> 7) & 31;
6094 int offset;
6095 if(shift)
6096 offset = (int)((int32)reg[opcode & 15].I >> shift);
6097 else if(reg[opcode & 15].I & 0x80000000)
6098 offset = 0xFFFFFFFF;
6099 else
6100 offset = 0;
6101 int dest = (opcode >> 12) & 15;
6102 int base = (opcode >> 16) & 15;
6103 uint32 address = reg[base].I + offset;
6104 reg[dest].I = CPUReadByte(address);
6105 if(dest != base)
6106 reg[base].I = address;
6107 clockTicks = 0;
6108 if(dest == 15) {
6109 reg[15].I &= 0xFFFFFFFC;
6110 armNextPC = reg[15].I;
6111 reg[15].I += 4;
6112 ARM_PREFETCH;
6113 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6114 }
6115 clockTicks += 3 + dataTicksAccesint16(address) +
6116 codeTicksAccesint32(armNextPC);
6117 }
6118 break;
6119 case 0x7f6:
6120 case 0x7fe:
6121 {
6122 // LDRB Rd, [Rn, Rm, ROR #]!
6123 if (busPrefetchCount==0)
6124 busPrefetch = busPrefetchEnable;
6125 int shift = (opcode >> 7) & 31;
6126 uint32 value = reg[opcode & 15].I;
6127 if(shift) {
6128 ROR_VALUE;
6129 } else {
6130 RCR_VALUE;
6131 }
6132 int dest = (opcode >> 12) & 15;
6133 int base = (opcode >> 16) & 15;
6134 uint32 address = reg[base].I + value;
6135 reg[dest].I = CPUReadByte(address);
6136 if(dest != base)
6137 reg[base].I = address;
6138 clockTicks = 0;
6139 if(dest == 15) {
6140 reg[15].I &= 0xFFFFFFFC;
6141 armNextPC = reg[15].I;
6142 reg[15].I += 4;
6143 ARM_PREFETCH;
6144 clockTicks += 2 + dataTicksAccessSeq32(address) + dataTicksAccessSeq32(address);
6145 }
6146 clockTicks += 3 + dataTicksAccesint16(address) +
6147 codeTicksAccesint32(armNextPC);
6148 }
6149 break;
6150 #define STMW_REG(val,num) \
6151 if(opcode & (val)) {\
6152 CPUWriteMemory(address, reg[(num)].I);\
6153 if(!offset) {\
6154 reg[base].I = temp;\
6155 clockTicks += 1 + dataTicksAccesint32(address);\
6156 offset = 1;\
6157 } else {\
6158 clockTicks += 1 + dataTicksAccessSeq32(address);\
6159 }\
6160 address += 4;\
6161 }
6162 #define STM_REG(val,num) \
6163 if(opcode & (val)) {\
6164 CPUWriteMemory(address, reg[(num)].I);\
6165 if(!offset) {\
6166 clockTicks += 1 + dataTicksAccesint32(address);\
6167 offset = 1;\
6168 } else {\
6169 clockTicks += 1 + dataTicksAccessSeq32(address);\
6170 }\
6171 address += 4;\
6172 }
6173
6174 CASE_16(0x800)
6175 {
6176 // STMDA Rn, {Rlist}
6177 if (busPrefetchCount==0)
6178 busPrefetch = busPrefetchEnable;
6179 int base = (opcode & 0x000F0000) >> 16;
6180 uint32 temp = reg[base].I -
6181 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6182 uint32 address = (temp + 4) & 0xFFFFFFFC;
6183 int offset = 0;
6184 STM_REG(1, 0);
6185 STM_REG(2, 1);
6186 STM_REG(4, 2);
6187 STM_REG(8, 3);
6188 STM_REG(16, 4);
6189 STM_REG(32, 5);
6190 STM_REG(64, 6);
6191 STM_REG(128, 7);
6192 STM_REG(256, 8);
6193 STM_REG(512, 9);
6194 STM_REG(1024, 10);
6195 STM_REG(2048, 11);
6196 STM_REG(4096, 12);
6197 STM_REG(8192, 13);
6198 STM_REG(16384, 14);
6199 if(opcode & 32768) {
6200 CPUWriteMemory(address, reg[15].I+4);
6201 if(!offset)
6202 clockTicks += 1 + dataTicksAccesint32(address);
6203 else
6204 clockTicks += 1 + dataTicksAccessSeq32(address);
6205 }
6206 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6207 }
6208 break;
6209 CASE_16(0x820)
6210 {
6211 // STMDA Rn!, {Rlist}
6212 if (busPrefetchCount==0)
6213 busPrefetch = busPrefetchEnable;
6214 int base = (opcode & 0x000F0000) >> 16;
6215 uint32 temp = reg[base].I -
6216 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6217 uint32 address = (temp+4) & 0xFFFFFFFC;
6218 int offset = 0;
6219
6220 STMW_REG(1, 0);
6221 STMW_REG(2, 1);
6222 STMW_REG(4, 2);
6223 STMW_REG(8, 3);
6224 STMW_REG(16, 4);
6225 STMW_REG(32, 5);
6226 STMW_REG(64, 6);
6227 STMW_REG(128, 7);
6228 STMW_REG(256, 8);
6229 STMW_REG(512, 9);
6230 STMW_REG(1024, 10);
6231 STMW_REG(2048, 11);
6232 STMW_REG(4096, 12);
6233 STMW_REG(8192, 13);
6234 STMW_REG(16384, 14);
6235 if(opcode & 32768) {
6236 CPUWriteMemory(address, reg[15].I+4);
6237 if(!offset)
6238 clockTicks += 1 + dataTicksAccesint32(address);
6239 else
6240 clockTicks += 1 + dataTicksAccessSeq32(address);
6241 reg[base].I = temp;
6242 }
6243 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6244 }
6245 break;
6246 CASE_16(0x840)
6247 {
6248 // STMDA Rn, {Rlist}^
6249 if (busPrefetchCount==0)
6250 busPrefetch = busPrefetchEnable;
6251 int base = (opcode & 0x000F0000) >> 16;
6252 uint32 temp = reg[base].I -
6253 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6254 uint32 address = (temp+4) & 0xFFFFFFFC;
6255 int offset = 0;
6256
6257 STM_REG(1, 0);
6258 STM_REG(2, 1);
6259 STM_REG(4, 2);
6260 STM_REG(8, 3);
6261 STM_REG(16, 4);
6262 STM_REG(32, 5);
6263 STM_REG(64, 6);
6264 STM_REG(128, 7);
6265
6266 if(armMode == 0x11) {
6267 STM_REG(256, R8_FIQ);
6268 STM_REG(512, R9_FIQ);
6269 STM_REG(1024, R10_FIQ);
6270 STM_REG(2048, R11_FIQ);
6271 STM_REG(4096, R12_FIQ);
6272 } else {
6273 STM_REG(256, 8);
6274 STM_REG(512, 9);
6275 STM_REG(1024, 10);
6276 STM_REG(2048, 11);
6277 STM_REG(4096, 12);
6278 }
6279
6280 if(armMode != 0x10 && armMode != 0x1f) {
6281 STM_REG(8192, R13_USR);
6282 STM_REG(16384, R14_USR);
6283 } else {
6284 STM_REG(8192, 13);
6285 STM_REG(16384, 14);
6286 }
6287
6288 if(opcode & 32768) {
6289 CPUWriteMemory(address, reg[15].I+4);
6290 if(!offset)
6291 clockTicks += 1 + dataTicksAccesint32(address);
6292 else
6293 clockTicks += 1 + dataTicksAccessSeq32(address);
6294 }
6295 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6296 }
6297 break;
6298 CASE_16(0x860)
6299 {
6300 // STMDA Rn!, {Rlist}^
6301 if (busPrefetchCount==0)
6302 busPrefetch = busPrefetchEnable;
6303 int base = (opcode & 0x000F0000) >> 16;
6304 uint32 temp = reg[base].I -
6305 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6306 uint32 address = (temp+4) & 0xFFFFFFFC;
6307 int offset = 0;
6308
6309 STMW_REG(1, 0);
6310 STMW_REG(2, 1);
6311 STMW_REG(4, 2);
6312 STMW_REG(8, 3);
6313 STMW_REG(16, 4);
6314 STMW_REG(32, 5);
6315 STMW_REG(64, 6);
6316 STMW_REG(128, 7);
6317
6318 if(armMode == 0x11) {
6319 STMW_REG(256, R8_FIQ);
6320 STMW_REG(512, R9_FIQ);
6321 STMW_REG(1024, R10_FIQ);
6322 STMW_REG(2048, R11_FIQ);
6323 STMW_REG(4096, R12_FIQ);
6324 } else {
6325 STMW_REG(256, 8);
6326 STMW_REG(512, 9);
6327 STMW_REG(1024, 10);
6328 STMW_REG(2048, 11);
6329 STMW_REG(4096, 12);
6330 }
6331
6332 if(armMode != 0x10 && armMode != 0x1f) {
6333 STMW_REG(8192, R13_USR);
6334 STMW_REG(16384, R14_USR);
6335 } else {
6336 STMW_REG(8192, 13);
6337 STMW_REG(16384, 14);
6338 }
6339
6340 if(opcode & 32768) {
6341 CPUWriteMemory(address, reg[15].I+4);
6342 if(!offset)
6343 clockTicks += 1 + dataTicksAccesint32(address);
6344 else
6345 clockTicks += 1 + dataTicksAccessSeq32(address);
6346 reg[base].I = temp;
6347 }
6348 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6349 }
6350 break;
6351
6352 CASE_16(0x880)
6353 {
6354 // STMIA Rn, {Rlist}
6355 if (busPrefetchCount==0)
6356 busPrefetch = busPrefetchEnable;
6357 int base = (opcode & 0x000F0000) >> 16;
6358 uint32 address = reg[base].I & 0xFFFFFFFC;
6359 int offset = 0;
6360 STM_REG(1, 0);
6361 STM_REG(2, 1);
6362 STM_REG(4, 2);
6363 STM_REG(8, 3);
6364 STM_REG(16, 4);
6365 STM_REG(32, 5);
6366 STM_REG(64, 6);
6367 STM_REG(128, 7);
6368 STM_REG(256, 8);
6369 STM_REG(512, 9);
6370 STM_REG(1024, 10);
6371 STM_REG(2048, 11);
6372 STM_REG(4096, 12);
6373 STM_REG(8192, 13);
6374 STM_REG(16384, 14);
6375 if(opcode & 32768) {
6376 CPUWriteMemory(address, reg[15].I+4);
6377 if(!offset)
6378 clockTicks += 1 + dataTicksAccesint32(address);
6379 else
6380 clockTicks += 1 + dataTicksAccessSeq32(address);
6381 }
6382 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6383 }
6384 break;
6385 CASE_16(0x8a0)
6386 {
6387 // STMIA Rn!, {Rlist}
6388 if (busPrefetchCount==0)
6389 busPrefetch = busPrefetchEnable;
6390 int base = (opcode & 0x000F0000) >> 16;
6391 uint32 address = reg[base].I & 0xFFFFFFFC;
6392 int offset = 0;
6393 uint32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
6394 cpuBitsSet[(opcode >> 8) & 255]);
6395 STMW_REG(1, 0);
6396 STMW_REG(2, 1);
6397 STMW_REG(4, 2);
6398 STMW_REG(8, 3);
6399 STMW_REG(16, 4);
6400 STMW_REG(32, 5);
6401 STMW_REG(64, 6);
6402 STMW_REG(128, 7);
6403 STMW_REG(256, 8);
6404 STMW_REG(512, 9);
6405 STMW_REG(1024, 10);
6406 STMW_REG(2048, 11);
6407 STMW_REG(4096, 12);
6408 STMW_REG(8192, 13);
6409 STMW_REG(16384, 14);
6410 if(opcode & 32768) {
6411 CPUWriteMemory(address, reg[15].I+4);
6412 if(!offset) {
6413 reg[base].I = temp;
6414 clockTicks += 1 + dataTicksAccesint32(address);
6415 } else
6416 clockTicks += 1 + dataTicksAccessSeq32(address);
6417 }
6418 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6419 }
6420 break;
6421 CASE_16(0x8c0)
6422 {
6423 // STMIA Rn, {Rlist}^
6424 if (busPrefetchCount==0)
6425 busPrefetch = busPrefetchEnable;
6426 int base = (opcode & 0x000F0000) >> 16;
6427 uint32 address = reg[base].I & 0xFFFFFFFC;
6428 int offset = 0;
6429 STM_REG(1, 0);
6430 STM_REG(2, 1);
6431 STM_REG(4, 2);
6432 STM_REG(8, 3);
6433 STM_REG(16, 4);
6434 STM_REG(32, 5);
6435 STM_REG(64, 6);
6436 STM_REG(128, 7);
6437 if(armMode == 0x11) {
6438 STM_REG(256, R8_FIQ);
6439 STM_REG(512, R9_FIQ);
6440 STM_REG(1024, R10_FIQ);
6441 STM_REG(2048, R11_FIQ);
6442 STM_REG(4096, R12_FIQ);
6443 } else {
6444 STM_REG(256, 8);
6445 STM_REG(512, 9);
6446 STM_REG(1024, 10);
6447 STM_REG(2048, 11);
6448 STM_REG(4096, 12);
6449 }
6450 if(armMode != 0x10 && armMode != 0x1f) {
6451 STM_REG(8192, R13_USR);
6452 STM_REG(16384, R14_USR);
6453 } else {
6454 STM_REG(8192, 13);
6455 STM_REG(16384, 14);
6456 }
6457 if(opcode & 32768) {
6458 CPUWriteMemory(address, reg[15].I+4);
6459 if(!offset)
6460 clockTicks += 1 + dataTicksAccesint32(address);
6461 else
6462 clockTicks += 1 + dataTicksAccessSeq32(address);
6463 }
6464 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6465 }
6466 break;
6467 CASE_16(0x8e0)
6468 {
6469 // STMIA Rn!, {Rlist}^
6470 if (busPrefetchCount==0)
6471 busPrefetch = busPrefetchEnable;
6472 int base = (opcode & 0x000F0000) >> 16;
6473 uint32 address = reg[base].I & 0xFFFFFFFC;
6474 int offset = 0;
6475 uint32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
6476 cpuBitsSet[(opcode >> 8) & 255]);
6477 STMW_REG(1, 0);
6478 STMW_REG(2, 1);
6479 STMW_REG(4, 2);
6480 STMW_REG(8, 3);
6481 STMW_REG(16, 4);
6482 STMW_REG(32, 5);
6483 STMW_REG(64, 6);
6484 STMW_REG(128, 7);
6485 if(armMode == 0x11) {
6486 STMW_REG(256, R8_FIQ);
6487 STMW_REG(512, R9_FIQ);
6488 STMW_REG(1024, R10_FIQ);
6489 STMW_REG(2048, R11_FIQ);
6490 STMW_REG(4096, R12_FIQ);
6491 } else {
6492 STMW_REG(256, 8);
6493 STMW_REG(512, 9);
6494 STMW_REG(1024, 10);
6495 STMW_REG(2048, 11);
6496 STMW_REG(4096, 12);
6497 }
6498 if(armMode != 0x10 && armMode != 0x1f) {
6499 STMW_REG(8192, R13_USR);
6500 STMW_REG(16384, R14_USR);
6501 } else {
6502 STMW_REG(8192, 13);
6503 STMW_REG(16384, 14);
6504 }
6505 if(opcode & 32768) {
6506 CPUWriteMemory(address, reg[15].I+4);
6507 if(!offset) {
6508 reg[base].I = temp;
6509 clockTicks += 1 + dataTicksAccesint32(address);
6510 } else
6511 clockTicks += 1 + dataTicksAccessSeq32(address);
6512 }
6513 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6514 }
6515 break;
6516
6517 CASE_16(0x900)
6518 {
6519 // STMDB Rn, {Rlist}
6520 if (busPrefetchCount==0)
6521 busPrefetch = busPrefetchEnable;
6522 int base = (opcode & 0x000F0000) >> 16;
6523 uint32 temp = reg[base].I -
6524 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6525 uint32 address = temp & 0xFFFFFFFC;
6526 int offset = 0;
6527 STM_REG(1, 0);
6528 STM_REG(2, 1);
6529 STM_REG(4, 2);
6530 STM_REG(8, 3);
6531 STM_REG(16, 4);
6532 STM_REG(32, 5);
6533 STM_REG(64, 6);
6534 STM_REG(128, 7);
6535 STM_REG(256, 8);
6536 STM_REG(512, 9);
6537 STM_REG(1024, 10);
6538 STM_REG(2048, 11);
6539 STM_REG(4096, 12);
6540 STM_REG(8192, 13);
6541 STM_REG(16384, 14);
6542 if(opcode & 32768) {
6543 CPUWriteMemory(address, reg[15].I+4);
6544 if(!offset)
6545 clockTicks += 1 + dataTicksAccesint32(address);
6546 else
6547 clockTicks += 1 + dataTicksAccessSeq32(address);
6548 }
6549 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6550 }
6551 break;
6552 CASE_16(0x920)
6553 {
6554 // STMDB Rn!, {Rlist}
6555 if (busPrefetchCount==0)
6556 busPrefetch = busPrefetchEnable;
6557 int base = (opcode & 0x000F0000) >> 16;
6558 uint32 temp = reg[base].I -
6559 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6560 uint32 address = temp & 0xFFFFFFFC;
6561 int offset = 0;
6562
6563 STMW_REG(1, 0);
6564 STMW_REG(2, 1);
6565 STMW_REG(4, 2);
6566 STMW_REG(8, 3);
6567 STMW_REG(16, 4);
6568 STMW_REG(32, 5);
6569 STMW_REG(64, 6);
6570 STMW_REG(128, 7);
6571 STMW_REG(256, 8);
6572 STMW_REG(512, 9);
6573 STMW_REG(1024, 10);
6574 STMW_REG(2048, 11);
6575 STMW_REG(4096, 12);
6576 STMW_REG(8192, 13);
6577 STMW_REG(16384, 14);
6578 if(opcode & 32768) {
6579 CPUWriteMemory(address, reg[15].I+4);
6580 if(!offset)
6581 clockTicks += 1 + dataTicksAccesint32(address);
6582 else
6583 clockTicks += 1 + dataTicksAccessSeq32(address);
6584 reg[base].I = temp;
6585 }
6586 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6587 }
6588 break;
6589 CASE_16(0x940)
6590 {
6591 // STMDB Rn, {Rlist}^
6592 if (busPrefetchCount==0)
6593 busPrefetch = busPrefetchEnable;
6594 int base = (opcode & 0x000F0000) >> 16;
6595 uint32 temp = reg[base].I -
6596 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6597 uint32 address = temp & 0xFFFFFFFC;
6598 int offset = 0;
6599
6600 STM_REG(1, 0);
6601 STM_REG(2, 1);
6602 STM_REG(4, 2);
6603 STM_REG(8, 3);
6604 STM_REG(16, 4);
6605 STM_REG(32, 5);
6606 STM_REG(64, 6);
6607 STM_REG(128, 7);
6608
6609 if(armMode == 0x11) {
6610 STM_REG(256, R8_FIQ);
6611 STM_REG(512, R9_FIQ);
6612 STM_REG(1024, R10_FIQ);
6613 STM_REG(2048, R11_FIQ);
6614 STM_REG(4096, R12_FIQ);
6615 } else {
6616 STM_REG(256, 8);
6617 STM_REG(512, 9);
6618 STM_REG(1024, 10);
6619 STM_REG(2048, 11);
6620 STM_REG(4096, 12);
6621 }
6622
6623 if(armMode != 0x10 && armMode != 0x1f) {
6624 STM_REG(8192, R13_USR);
6625 STM_REG(16384, R14_USR);
6626 } else {
6627 STM_REG(8192, 13);
6628 STM_REG(16384, 14);
6629 }
6630
6631 if(opcode & 32768) {
6632 CPUWriteMemory(address, reg[15].I+4);
6633 if(!offset)
6634 clockTicks += 1 + dataTicksAccesint32(address);
6635 else
6636 clockTicks += 1 + dataTicksAccessSeq32(address);
6637 }
6638 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6639 }
6640 break;
6641 CASE_16(0x960)
6642 {
6643 // STMDB Rn!, {Rlist}^
6644 if (busPrefetchCount==0)
6645 busPrefetch = busPrefetchEnable;
6646 int base = (opcode & 0x000F0000) >> 16;
6647 uint32 temp = reg[base].I -
6648 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6649 uint32 address = temp & 0xFFFFFFFC;
6650 int offset = 0;
6651
6652 STMW_REG(1, 0);
6653 STMW_REG(2, 1);
6654 STMW_REG(4, 2);
6655 STMW_REG(8, 3);
6656 STMW_REG(16, 4);
6657 STMW_REG(32, 5);
6658 STMW_REG(64, 6);
6659 STMW_REG(128, 7);
6660
6661 if(armMode == 0x11) {
6662 STMW_REG(256, R8_FIQ);
6663 STMW_REG(512, R9_FIQ);
6664 STMW_REG(1024, R10_FIQ);
6665 STMW_REG(2048, R11_FIQ);
6666 STMW_REG(4096, R12_FIQ);
6667 } else {
6668 STMW_REG(256, 8);
6669 STMW_REG(512, 9);
6670 STMW_REG(1024, 10);
6671 STMW_REG(2048, 11);
6672 STMW_REG(4096, 12);
6673 }
6674
6675 if(armMode != 0x10 && armMode != 0x1f) {
6676 STMW_REG(8192, R13_USR);
6677 STMW_REG(16384, R14_USR);
6678 } else {
6679 STMW_REG(8192, 13);
6680 STMW_REG(16384, 14);
6681 }
6682
6683 if(opcode & 32768) {
6684 CPUWriteMemory(address, reg[15].I+4);
6685 if(!offset)
6686 clockTicks += 1 + dataTicksAccesint32(address);
6687 else
6688 clockTicks += 1 + dataTicksAccessSeq32(address);
6689 reg[base].I = temp;
6690 }
6691 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6692 }
6693 break;
6694
6695 CASE_16(0x980)
6696 {
6697 // STMIB Rn, {Rlist}
6698 if (busPrefetchCount==0)
6699 busPrefetch = busPrefetchEnable;
6700 int base = (opcode & 0x000F0000) >> 16;
6701 uint32 address = (reg[base].I+4) & 0xFFFFFFFC;
6702 int offset = 0;
6703 STM_REG(1, 0);
6704 STM_REG(2, 1);
6705 STM_REG(4, 2);
6706 STM_REG(8, 3);
6707 STM_REG(16, 4);
6708 STM_REG(32, 5);
6709 STM_REG(64, 6);
6710 STM_REG(128, 7);
6711 STM_REG(256, 8);
6712 STM_REG(512, 9);
6713 STM_REG(1024, 10);
6714 STM_REG(2048, 11);
6715 STM_REG(4096, 12);
6716 STM_REG(8192, 13);
6717 STM_REG(16384, 14);
6718 if(opcode & 32768) {
6719 CPUWriteMemory(address, reg[15].I+4);
6720 if(!offset)
6721 clockTicks += 1 + dataTicksAccesint32(address);
6722 else
6723 clockTicks += 1 + dataTicksAccessSeq32(address);
6724 }
6725 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6726 }
6727 break;
6728 CASE_16(0x9a0)
6729 {
6730 // STMIB Rn!, {Rlist}
6731 if (busPrefetchCount==0)
6732 busPrefetch = busPrefetchEnable;
6733 int base = (opcode & 0x000F0000) >> 16;
6734 uint32 address = (reg[base].I+4) & 0xFFFFFFFC;
6735 int offset = 0;
6736 uint32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
6737 cpuBitsSet[(opcode >> 8) & 255]);
6738 STMW_REG(1, 0);
6739 STMW_REG(2, 1);
6740 STMW_REG(4, 2);
6741 STMW_REG(8, 3);
6742 STMW_REG(16, 4);
6743 STMW_REG(32, 5);
6744 STMW_REG(64, 6);
6745 STMW_REG(128, 7);
6746 STMW_REG(256, 8);
6747 STMW_REG(512, 9);
6748 STMW_REG(1024, 10);
6749 STMW_REG(2048, 11);
6750 STMW_REG(4096, 12);
6751 STMW_REG(8192, 13);
6752 STMW_REG(16384, 14);
6753 if(opcode & 32768) {
6754 CPUWriteMemory(address, reg[15].I+4);
6755 if(!offset) {
6756 reg[base].I = temp;
6757 clockTicks += 1 + dataTicksAccesint32(address);
6758 } else
6759 clockTicks += 1 + dataTicksAccessSeq32(address);
6760 }
6761 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6762 }
6763 break;
6764 CASE_16(0x9c0)
6765 {
6766 // STMIB Rn, {Rlist}^
6767 if (busPrefetchCount==0)
6768 busPrefetch = busPrefetchEnable;
6769 int base = (opcode & 0x000F0000) >> 16;
6770 uint32 address = (reg[base].I+4) & 0xFFFFFFFC;
6771 int offset = 0;
6772 STM_REG(1, 0);
6773 STM_REG(2, 1);
6774 STM_REG(4, 2);
6775 STM_REG(8, 3);
6776 STM_REG(16, 4);
6777 STM_REG(32, 5);
6778 STM_REG(64, 6);
6779 STM_REG(128, 7);
6780 if(armMode == 0x11) {
6781 STM_REG(256, R8_FIQ);
6782 STM_REG(512, R9_FIQ);
6783 STM_REG(1024, R10_FIQ);
6784 STM_REG(2048, R11_FIQ);
6785 STM_REG(4096, R12_FIQ);
6786 } else {
6787 STM_REG(256, 8);
6788 STM_REG(512, 9);
6789 STM_REG(1024, 10);
6790 STM_REG(2048, 11);
6791 STM_REG(4096, 12);
6792 }
6793 if(armMode != 0x10 && armMode != 0x1f) {
6794 STM_REG(8192, R13_USR);
6795 STM_REG(16384, R14_USR);
6796 } else {
6797 STM_REG(8192, 13);
6798 STM_REG(16384, 14);
6799 }
6800 if(opcode & 32768) {
6801 CPUWriteMemory(address, reg[15].I+4);
6802 if(!offset)
6803 clockTicks += 1 + dataTicksAccesint32(address);
6804 else
6805 clockTicks += 1 + dataTicksAccessSeq32(address);
6806 }
6807 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6808 }
6809 break;
6810 CASE_16(0x9e0)
6811 {
6812 // STMIB Rn!, {Rlist}^
6813 if (busPrefetchCount==0)
6814 busPrefetch = busPrefetchEnable;
6815 int base = (opcode & 0x000F0000) >> 16;
6816 uint32 address = (reg[base].I+4) & 0xFFFFFFFC;
6817 int offset = 0;
6818 uint32 temp = reg[base].I + 4*(cpuBitsSet[opcode & 0xFF] +
6819 cpuBitsSet[(opcode >> 8) & 255]);
6820 STMW_REG(1, 0);
6821 STMW_REG(2, 1);
6822 STMW_REG(4, 2);
6823 STMW_REG(8, 3);
6824 STMW_REG(16, 4);
6825 STMW_REG(32, 5);
6826 STMW_REG(64, 6);
6827 STMW_REG(128, 7);
6828 if(armMode == 0x11) {
6829 STMW_REG(256, R8_FIQ);
6830 STMW_REG(512, R9_FIQ);
6831 STMW_REG(1024, R10_FIQ);
6832 STMW_REG(2048, R11_FIQ);
6833 STMW_REG(4096, R12_FIQ);
6834 } else {
6835 STMW_REG(256, 8);
6836 STMW_REG(512, 9);
6837 STMW_REG(1024, 10);
6838 STMW_REG(2048, 11);
6839 STMW_REG(4096, 12);
6840 }
6841 if(armMode != 0x10 && armMode != 0x1f) {
6842 STMW_REG(8192, R13_USR);
6843 STMW_REG(16384, R14_USR);
6844 } else {
6845 STMW_REG(8192, 13);
6846 STMW_REG(16384, 14);
6847 }
6848 if(opcode & 32768) {
6849 CPUWriteMemory(address, reg[15].I+4);
6850 if(!offset) {
6851 reg[base].I = temp;
6852 clockTicks += 1 + dataTicksAccesint32(address);
6853 } else
6854 clockTicks += 1 + dataTicksAccessSeq32(address);
6855 }
6856 clockTicks += 1 + codeTicksAccesint32(armNextPC);
6857 }
6858 break;
6859
6860 #define LDM_REG(val,num) \
6861 if(opcode & (val)) {\
6862 reg[(num)].I = CPUReadMemory(address);\
6863 if(offset)\
6864 clockTicks += 1 + dataTicksAccessSeq32(address);\
6865 else {\
6866 clockTicks += 1 + dataTicksAccesint32(address);\
6867 offset = 1;\
6868 }\
6869 address += 4;\
6870 }
6871
6872 CASE_16(0x810)
6873 {
6874 // LDMDA Rn, {Rlist}
6875 if (busPrefetchCount==0)
6876 busPrefetch = busPrefetchEnable;
6877 int base = (opcode & 0x000F0000) >> 16;
6878 uint32 temp = reg[base].I -
6879 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6880 uint32 address = (temp + 4) & 0xFFFFFFFC;
6881 clockTicks = 0;
6882 int offset = 0;
6883 LDM_REG(1, 0);
6884 LDM_REG(2, 1);
6885 LDM_REG(4, 2);
6886 LDM_REG(8, 3);
6887 LDM_REG(16, 4);
6888 LDM_REG(32, 5);
6889 LDM_REG(64, 6);
6890 LDM_REG(128, 7);
6891 LDM_REG(256, 8);
6892 LDM_REG(512, 9);
6893 LDM_REG(1024, 10);
6894 LDM_REG(2048, 11);
6895 LDM_REG(4096, 12);
6896 LDM_REG(8192, 13);
6897 LDM_REG(16384, 14);
6898 if(opcode & 32768) {
6899 reg[15].I = CPUReadMemory(address);
6900 armNextPC = reg[15].I;
6901 reg[15].I += 4;
6902 ARM_PREFETCH;
6903 if (!offset)
6904 clockTicks += 1 + dataTicksAccesint32(address);
6905 else
6906 clockTicks += 1 + dataTicksAccessSeq32(address);
6907 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
6908 }
6909 clockTicks += 2 + codeTicksAccesint32(armNextPC);
6910 }
6911 break;
6912 CASE_16(0x830)
6913 {
6914 // LDMDA Rn!, {Rlist}
6915 if (busPrefetchCount==0)
6916 busPrefetch = busPrefetchEnable;
6917 int base = (opcode & 0x000F0000) >> 16;
6918 uint32 temp = reg[base].I -
6919 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6920 uint32 address = (temp + 4) & 0xFFFFFFFC;
6921 clockTicks = 0;
6922 int offset = 0;
6923 LDM_REG(1, 0);
6924 LDM_REG(2, 1);
6925 LDM_REG(4, 2);
6926 LDM_REG(8, 3);
6927 LDM_REG(16, 4);
6928 LDM_REG(32, 5);
6929 LDM_REG(64, 6);
6930 LDM_REG(128, 7);
6931 LDM_REG(256, 8);
6932 LDM_REG(512, 9);
6933 LDM_REG(1024, 10);
6934 LDM_REG(2048, 11);
6935 LDM_REG(4096, 12);
6936 LDM_REG(8192, 13);
6937 LDM_REG(16384, 14);
6938 if(opcode & 32768) {
6939 reg[15].I = CPUReadMemory(address);
6940
6941 armNextPC = reg[15].I;
6942 reg[15].I += 4;
6943 ARM_PREFETCH;
6944 if (!offset)
6945 clockTicks += 1 + dataTicksAccesint32(address);
6946 else
6947 clockTicks += 1 + dataTicksAccessSeq32(address);
6948 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
6949 }
6950 clockTicks += 2 + codeTicksAccesint32(armNextPC);
6951 if(!(opcode & (1 << base)))
6952 reg[base].I = temp;
6953 }
6954 break;
6955 CASE_16(0x850)
6956 {
6957 // LDMDA Rn, {Rlist}^
6958 if (busPrefetchCount==0)
6959 busPrefetch = busPrefetchEnable;
6960 int base = (opcode & 0x000F0000) >> 16;
6961 uint32 temp = reg[base].I -
6962 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
6963 uint32 address = (temp + 4) & 0xFFFFFFFC;
6964 clockTicks = 0;
6965 int offset = 0;
6966 if(opcode & 0x8000) {
6967 LDM_REG(1, 0);
6968 LDM_REG(2, 1);
6969 LDM_REG(4, 2);
6970 LDM_REG(8, 3);
6971 LDM_REG(16, 4);
6972 LDM_REG(32, 5);
6973 LDM_REG(64, 6);
6974 LDM_REG(128, 7);
6975 LDM_REG(256, 8);
6976 LDM_REG(512, 9);
6977 LDM_REG(1024, 10);
6978 LDM_REG(2048, 11);
6979 LDM_REG(4096, 12);
6980 LDM_REG(8192, 13);
6981 LDM_REG(16384, 14);
6982
6983 reg[15].I = CPUReadMemory(address);
6984
6985 CPUSwitchMode(reg[17].I & 0x1f, false);
6986 if(armState) {
6987 armNextPC = reg[15].I & 0xFFFFFFFC;
6988 reg[15].I = armNextPC + 4;
6989 ARM_PREFETCH;
6990 } else {
6991 armNextPC = reg[15].I & 0xFFFFFFFE;
6992 reg[15].I = armNextPC + 2;
6993 THUMB_PREFETCH;
6994 }
6995 } else {
6996 LDM_REG(1, 0);
6997 LDM_REG(2, 1);
6998 LDM_REG(4, 2);
6999 LDM_REG(8, 3);
7000 LDM_REG(16, 4);
7001 LDM_REG(32, 5);
7002 LDM_REG(64, 6);
7003 LDM_REG(128, 7);
7004
7005 if(armMode == 0x11) {
7006 LDM_REG(256, R8_FIQ);
7007 LDM_REG(512, R9_FIQ);
7008 LDM_REG(1024, R10_FIQ);
7009 LDM_REG(2048, R11_FIQ);
7010 LDM_REG(4096, R12_FIQ);
7011 } else {
7012 LDM_REG(256, 8);
7013 LDM_REG(512, 9);
7014 LDM_REG(1024, 10);
7015 LDM_REG(2048, 11);
7016 LDM_REG(4096, 12);
7017 }
7018
7019 if(armMode != 0x10 && armMode != 0x1f) {
7020 LDM_REG(8192, R13_USR);
7021 LDM_REG(16384, R14_USR);
7022 } else {
7023 LDM_REG(8192, 13);
7024 LDM_REG(16384, 14);
7025 }
7026 if (!offset)
7027 clockTicks += 1 + dataTicksAccesint32(address);
7028 else
7029 clockTicks += 1 + dataTicksAccessSeq32(address);
7030 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7031 }
7032 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7033 }
7034 break;
7035 CASE_16(0x870)
7036 {
7037 // LDMDA Rn!, {Rlist}^
7038 if (busPrefetchCount==0)
7039 busPrefetch = busPrefetchEnable;
7040 int base = (opcode & 0x000F0000) >> 16;
7041 uint32 temp = reg[base].I -
7042 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7043 uint32 address = (temp + 4) & 0xFFFFFFFC;
7044 clockTicks = 0;
7045 int offset = 0;
7046 if(opcode & 0x8000) {
7047 LDM_REG(1, 0);
7048 LDM_REG(2, 1);
7049 LDM_REG(4, 2);
7050 LDM_REG(8, 3);
7051 LDM_REG(16, 4);
7052 LDM_REG(32, 5);
7053 LDM_REG(64, 6);
7054 LDM_REG(128, 7);
7055 LDM_REG(256, 8);
7056 LDM_REG(512, 9);
7057 LDM_REG(1024, 10);
7058 LDM_REG(2048, 11);
7059 LDM_REG(4096, 12);
7060 LDM_REG(8192, 13);
7061 LDM_REG(16384, 14);
7062
7063 reg[15].I = CPUReadMemory(address);
7064
7065 if(!(opcode & (1 << base)))
7066 reg[base].I = temp;
7067
7068 CPUSwitchMode(reg[17].I & 0x1f, false);
7069 if(armState) {
7070 armNextPC = reg[15].I & 0xFFFFFFFC;
7071 reg[15].I = armNextPC + 4;
7072 ARM_PREFETCH;
7073 } else {
7074 armNextPC = reg[15].I & 0xFFFFFFFE;
7075 reg[15].I = armNextPC + 2;
7076 THUMB_PREFETCH;
7077 }
7078 } else {
7079 LDM_REG(1, 0);
7080 LDM_REG(2, 1);
7081 LDM_REG(4, 2);
7082 LDM_REG(8, 3);
7083 LDM_REG(16, 4);
7084 LDM_REG(32, 5);
7085 LDM_REG(64, 6);
7086 LDM_REG(128, 7);
7087
7088 if(armMode == 0x11) {
7089 LDM_REG(256, R8_FIQ);
7090 LDM_REG(512, R9_FIQ);
7091 LDM_REG(1024, R10_FIQ);
7092 LDM_REG(2048, R11_FIQ);
7093 LDM_REG(4096, R12_FIQ);
7094 } else {
7095 LDM_REG(256, 8);
7096 LDM_REG(512, 9);
7097 LDM_REG(1024, 10);
7098 LDM_REG(2048, 11);
7099 LDM_REG(4096, 12);
7100 }
7101
7102 if(armMode != 0x10 && armMode != 0x1f) {
7103 LDM_REG(8192, R13_USR);
7104 LDM_REG(16384, R14_USR);
7105 } else {
7106 LDM_REG(8192, 13);
7107 LDM_REG(16384, 14);
7108 }
7109
7110 if(!(opcode & (1 << base)))
7111 reg[base].I = temp;
7112 if (!offset)
7113 clockTicks += 1 + dataTicksAccesint32(address);
7114 else
7115 clockTicks += 1 + dataTicksAccessSeq32(address);
7116 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7117 }
7118 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7119 }
7120 break;
7121
7122 CASE_16(0x890)
7123 {
7124 // LDMIA Rn, {Rlist}
7125 if (busPrefetchCount==0)
7126 busPrefetch = busPrefetchEnable;
7127 int base = (opcode & 0x000F0000) >> 16;
7128 uint32 address = reg[base].I & 0xFFFFFFFC;
7129 clockTicks = 0;
7130 int offset = 0;
7131 LDM_REG(1, 0);
7132 LDM_REG(2, 1);
7133 LDM_REG(4, 2);
7134 LDM_REG(8, 3);
7135 LDM_REG(16, 4);
7136 LDM_REG(32, 5);
7137 LDM_REG(64, 6);
7138 LDM_REG(128, 7);
7139 LDM_REG(256, 8);
7140 LDM_REG(512, 9);
7141 LDM_REG(1024, 10);
7142 LDM_REG(2048, 11);
7143 LDM_REG(4096, 12);
7144 LDM_REG(8192, 13);
7145 LDM_REG(16384, 14);
7146 if(opcode & 32768) {
7147 reg[15].I = CPUReadMemory(address);
7148
7149 armNextPC = reg[15].I;
7150 reg[15].I += 4;
7151 ARM_PREFETCH;
7152 if (!offset)
7153 clockTicks += 1 + dataTicksAccesint32(address);
7154 else
7155 clockTicks += 1 + dataTicksAccessSeq32(address);
7156 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7157 }
7158 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7159 }
7160 break;
7161 CASE_16(0x8b0)
7162 {
7163 // LDMIA Rn!, {Rlist}
7164 if (busPrefetchCount==0)
7165 busPrefetch = busPrefetchEnable;
7166 int base = (opcode & 0x000F0000) >> 16;
7167 uint32 temp = reg[base].I +
7168 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7169 uint32 address = reg[base].I & 0xFFFFFFFC;
7170 clockTicks = 0;
7171 int offset = 0;
7172 LDM_REG(1, 0);
7173 LDM_REG(2, 1);
7174 LDM_REG(4, 2);
7175 LDM_REG(8, 3);
7176 LDM_REG(16, 4);
7177 LDM_REG(32, 5);
7178 LDM_REG(64, 6);
7179 LDM_REG(128, 7);
7180 LDM_REG(256, 8);
7181 LDM_REG(512, 9);
7182 LDM_REG(1024, 10);
7183 LDM_REG(2048, 11);
7184 LDM_REG(4096, 12);
7185 LDM_REG(8192, 13);
7186 LDM_REG(16384, 14);
7187 if(opcode & 32768) {
7188 reg[15].I = CPUReadMemory(address);
7189
7190 armNextPC = reg[15].I;
7191 reg[15].I += 4;
7192 ARM_PREFETCH;
7193 if (!offset)
7194 clockTicks += 1 + dataTicksAccesint32(address);
7195 else
7196 clockTicks += 1 + dataTicksAccessSeq32(address);
7197 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7198 }
7199 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7200 if(!(opcode & (1 << base)))
7201 reg[base].I = temp;
7202 }
7203 break;
7204 CASE_16(0x8d0)
7205 {
7206 // LDMIA Rn, {Rlist}^
7207 if (busPrefetchCount==0)
7208 busPrefetch = busPrefetchEnable;
7209 int base = (opcode & 0x000F0000) >> 16;
7210 uint32 address = reg[base].I & 0xFFFFFFFC;
7211 clockTicks = 0;
7212 int offset = 0;
7213 if(opcode & 0x8000) {
7214 LDM_REG(1, 0);
7215 LDM_REG(2, 1);
7216 LDM_REG(4, 2);
7217 LDM_REG(8, 3);
7218 LDM_REG(16, 4);
7219 LDM_REG(32, 5);
7220 LDM_REG(64, 6);
7221 LDM_REG(128, 7);
7222 LDM_REG(256, 8);
7223 LDM_REG(512, 9);
7224 LDM_REG(1024, 10);
7225 LDM_REG(2048, 11);
7226 LDM_REG(4096, 12);
7227 LDM_REG(8192, 13);
7228 LDM_REG(16384, 14);
7229
7230 reg[15].I = CPUReadMemory(address);
7231
7232 CPUSwitchMode(reg[17].I & 0x1f, false);
7233 if(armState) {
7234 armNextPC = reg[15].I & 0xFFFFFFFC;
7235 reg[15].I = armNextPC + 4;
7236 ARM_PREFETCH;
7237 } else {
7238 armNextPC = reg[15].I & 0xFFFFFFFE;
7239 reg[15].I = armNextPC + 2;
7240 THUMB_PREFETCH;
7241 }
7242 } else {
7243 LDM_REG(1, 0);
7244 LDM_REG(2, 1);
7245 LDM_REG(4, 2);
7246 LDM_REG(8, 3);
7247 LDM_REG(16, 4);
7248 LDM_REG(32, 5);
7249 LDM_REG(64, 6);
7250 LDM_REG(128, 7);
7251
7252 if(armMode == 0x11) {
7253 LDM_REG(256, R8_FIQ);
7254 LDM_REG(512, R9_FIQ);
7255 LDM_REG(1024, R10_FIQ);
7256 LDM_REG(2048, R11_FIQ);
7257 LDM_REG(4096, R12_FIQ);
7258 } else {
7259 LDM_REG(256, 8);
7260 LDM_REG(512, 9);
7261 LDM_REG(1024, 10);
7262 LDM_REG(2048, 11);
7263 LDM_REG(4096, 12);
7264 }
7265
7266 if(armMode != 0x10 && armMode != 0x1f) {
7267 LDM_REG(8192, R13_USR);
7268 LDM_REG(16384, R14_USR);
7269 } else {
7270 LDM_REG(8192, 13);
7271 LDM_REG(16384, 14);
7272 }
7273 if (!offset)
7274 clockTicks += 1 + dataTicksAccesint32(address);
7275 else
7276 clockTicks += 1 + dataTicksAccessSeq32(address);
7277 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7278 }
7279 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7280 }
7281 break;
7282 CASE_16(0x8f0)
7283 {
7284 // LDMIA Rn!, {Rlist}^
7285 if (busPrefetchCount==0)
7286 busPrefetch = busPrefetchEnable;
7287 int base = (opcode & 0x000F0000) >> 16;
7288 uint32 temp = reg[base].I +
7289 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7290 uint32 address = reg[base].I & 0xFFFFFFFC;
7291 clockTicks = 0;
7292 int offset = 0;
7293 if(opcode & 0x8000) {
7294 LDM_REG(1, 0);
7295 LDM_REG(2, 1);
7296 LDM_REG(4, 2);
7297 LDM_REG(8, 3);
7298 LDM_REG(16, 4);
7299 LDM_REG(32, 5);
7300 LDM_REG(64, 6);
7301 LDM_REG(128, 7);
7302 LDM_REG(256, 8);
7303 LDM_REG(512, 9);
7304 LDM_REG(1024, 10);
7305 LDM_REG(2048, 11);
7306 LDM_REG(4096, 12);
7307 LDM_REG(8192, 13);
7308 LDM_REG(16384, 14);
7309
7310 reg[15].I = CPUReadMemory(address);
7311
7312 if(!(opcode & (1 << base)))
7313 reg[base].I = temp;
7314
7315 CPUSwitchMode(reg[17].I & 0x1f, false);
7316 if(armState) {
7317 armNextPC = reg[15].I & 0xFFFFFFFC;
7318 reg[15].I = armNextPC + 4;
7319 ARM_PREFETCH;
7320 } else {
7321 armNextPC = reg[15].I & 0xFFFFFFFE;
7322 reg[15].I = armNextPC + 2;
7323 THUMB_PREFETCH;
7324 }
7325 } else {
7326 LDM_REG(1, 0);
7327 LDM_REG(2, 1);
7328 LDM_REG(4, 2);
7329 LDM_REG(8, 3);
7330 LDM_REG(16, 4);
7331 LDM_REG(32, 5);
7332 LDM_REG(64, 6);
7333 LDM_REG(128, 7);
7334
7335 if(armMode == 0x11) {
7336 LDM_REG(256, R8_FIQ);
7337 LDM_REG(512, R9_FIQ);
7338 LDM_REG(1024, R10_FIQ);
7339 LDM_REG(2048, R11_FIQ);
7340 LDM_REG(4096, R12_FIQ);
7341 } else {
7342 LDM_REG(256, 8);
7343 LDM_REG(512, 9);
7344 LDM_REG(1024, 10);
7345 LDM_REG(2048, 11);
7346 LDM_REG(4096, 12);
7347 }
7348
7349 if(armMode != 0x10 && armMode != 0x1f) {
7350 LDM_REG(8192, R13_USR);
7351 LDM_REG(16384, R14_USR);
7352 } else {
7353 LDM_REG(8192, 13);
7354 LDM_REG(16384, 14);
7355 }
7356
7357 if(!(opcode & (1 << base)))
7358 reg[base].I = temp;
7359 if (!offset)
7360 clockTicks += 1 + dataTicksAccesint32(address);
7361 else
7362 clockTicks += 1 + dataTicksAccessSeq32(address);
7363 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7364 }
7365 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7366 }
7367 break;
7368
7369 CASE_16(0x910)
7370 {
7371 // LDMDB Rn, {Rlist}
7372 if (busPrefetchCount==0)
7373 busPrefetch = busPrefetchEnable;
7374 int base = (opcode & 0x000F0000) >> 16;
7375 uint32 temp = reg[base].I -
7376 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7377 uint32 address = temp & 0xFFFFFFFC;
7378 clockTicks = 0;
7379 int offset = 0;
7380 LDM_REG(1, 0);
7381 LDM_REG(2, 1);
7382 LDM_REG(4, 2);
7383 LDM_REG(8, 3);
7384 LDM_REG(16, 4);
7385 LDM_REG(32, 5);
7386 LDM_REG(64, 6);
7387 LDM_REG(128, 7);
7388 LDM_REG(256, 8);
7389 LDM_REG(512, 9);
7390 LDM_REG(1024, 10);
7391 LDM_REG(2048, 11);
7392 LDM_REG(4096, 12);
7393 LDM_REG(8192, 13);
7394 LDM_REG(16384, 14);
7395 if(opcode & 32768) {
7396 reg[15].I = CPUReadMemory(address);
7397
7398 armNextPC = reg[15].I;
7399 reg[15].I += 4;
7400 ARM_PREFETCH;
7401 if (!offset)
7402 clockTicks += 1 + dataTicksAccesint32(address);
7403 else
7404 clockTicks += 1 + dataTicksAccessSeq32(address);
7405 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7406 }
7407 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7408 }
7409 break;
7410 CASE_16(0x930)
7411 {
7412 // LDMDB Rn!, {Rlist}
7413 if (busPrefetchCount==0)
7414 busPrefetch = busPrefetchEnable;
7415 int base = (opcode & 0x000F0000) >> 16;
7416 uint32 temp = reg[base].I -
7417 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7418 uint32 address = temp & 0xFFFFFFFC;
7419 clockTicks = 0;
7420 int offset = 0;
7421 LDM_REG(1, 0);
7422 LDM_REG(2, 1);
7423 LDM_REG(4, 2);
7424 LDM_REG(8, 3);
7425 LDM_REG(16, 4);
7426 LDM_REG(32, 5);
7427 LDM_REG(64, 6);
7428 LDM_REG(128, 7);
7429 LDM_REG(256, 8);
7430 LDM_REG(512, 9);
7431 LDM_REG(1024, 10);
7432 LDM_REG(2048, 11);
7433 LDM_REG(4096, 12);
7434 LDM_REG(8192, 13);
7435 LDM_REG(16384, 14);
7436 if(opcode & 32768) {
7437 reg[15].I = CPUReadMemory(address);
7438
7439 armNextPC = reg[15].I;
7440 reg[15].I += 4;
7441 ARM_PREFETCH;
7442 if (!offset)
7443 clockTicks += 1 + dataTicksAccesint32(address);
7444 else
7445 clockTicks += 1 + dataTicksAccessSeq32(address);
7446 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7447 }
7448 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7449 if(!(opcode & (1 << base)))
7450 reg[base].I = temp;
7451 }
7452 break;
7453 CASE_16(0x950)
7454 {
7455 // LDMDB Rn, {Rlist}^
7456 if (busPrefetchCount==0)
7457 busPrefetch = busPrefetchEnable;
7458 int base = (opcode & 0x000F0000) >> 16;
7459 uint32 temp = reg[base].I -
7460 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7461 uint32 address = temp & 0xFFFFFFFC;
7462 clockTicks = 0;
7463 int offset = 0;
7464 if(opcode & 0x8000) {
7465 LDM_REG(1, 0);
7466 LDM_REG(2, 1);
7467 LDM_REG(4, 2);
7468 LDM_REG(8, 3);
7469 LDM_REG(16, 4);
7470 LDM_REG(32, 5);
7471 LDM_REG(64, 6);
7472 LDM_REG(128, 7);
7473 LDM_REG(256, 8);
7474 LDM_REG(512, 9);
7475 LDM_REG(1024, 10);
7476 LDM_REG(2048, 11);
7477 LDM_REG(4096, 12);
7478 LDM_REG(8192, 13);
7479 LDM_REG(16384, 14);
7480
7481 reg[15].I = CPUReadMemory(address);
7482
7483 CPUSwitchMode(reg[17].I & 0x1f, false);
7484 if(armState) {
7485 armNextPC = reg[15].I & 0xFFFFFFFC;
7486 reg[15].I = armNextPC + 4;
7487 ARM_PREFETCH;
7488 } else {
7489 armNextPC = reg[15].I & 0xFFFFFFFE;
7490 reg[15].I = armNextPC + 2;
7491 THUMB_PREFETCH;
7492 }
7493 } else {
7494 LDM_REG(1, 0);
7495 LDM_REG(2, 1);
7496 LDM_REG(4, 2);
7497 LDM_REG(8, 3);
7498 LDM_REG(16, 4);
7499 LDM_REG(32, 5);
7500 LDM_REG(64, 6);
7501 LDM_REG(128, 7);
7502
7503 if(armMode == 0x11) {
7504 LDM_REG(256, R8_FIQ);
7505 LDM_REG(512, R9_FIQ);
7506 LDM_REG(1024, R10_FIQ);
7507 LDM_REG(2048, R11_FIQ);
7508 LDM_REG(4096, R12_FIQ);
7509 } else {
7510 LDM_REG(256, 8);
7511 LDM_REG(512, 9);
7512 LDM_REG(1024, 10);
7513 LDM_REG(2048, 11);
7514 LDM_REG(4096, 12);
7515 }
7516
7517 if(armMode != 0x10 && armMode != 0x1f) {
7518 LDM_REG(8192, R13_USR);
7519 LDM_REG(16384, R14_USR);
7520 } else {
7521 LDM_REG(8192, 13);
7522 LDM_REG(16384, 14);
7523 }
7524 if (!offset)
7525 clockTicks += 1 + dataTicksAccesint32(address);
7526 else
7527 clockTicks += 1 + dataTicksAccessSeq32(address);
7528 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7529 }
7530 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7531 }
7532 break;
7533 CASE_16(0x970)
7534 {
7535 // LDMDB Rn!, {Rlist}^
7536 if (busPrefetchCount==0)
7537 busPrefetch = busPrefetchEnable;
7538 int base = (opcode & 0x000F0000) >> 16;
7539 uint32 temp = reg[base].I -
7540 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7541 uint32 address = temp & 0xFFFFFFFC;
7542 clockTicks = 0;
7543 int offset = 0;
7544 if(opcode & 0x8000) {
7545 LDM_REG(1, 0);
7546 LDM_REG(2, 1);
7547 LDM_REG(4, 2);
7548 LDM_REG(8, 3);
7549 LDM_REG(16, 4);
7550 LDM_REG(32, 5);
7551 LDM_REG(64, 6);
7552 LDM_REG(128, 7);
7553 LDM_REG(256, 8);
7554 LDM_REG(512, 9);
7555 LDM_REG(1024, 10);
7556 LDM_REG(2048, 11);
7557 LDM_REG(4096, 12);
7558 LDM_REG(8192, 13);
7559 LDM_REG(16384, 14);
7560
7561 reg[15].I = CPUReadMemory(address);
7562
7563 if(!(opcode & (1 << base)))
7564 reg[base].I = temp;
7565
7566 CPUSwitchMode(reg[17].I & 0x1f, false);
7567 if(armState) {
7568 armNextPC = reg[15].I & 0xFFFFFFFC;
7569 reg[15].I = armNextPC + 4;
7570 ARM_PREFETCH;
7571 } else {
7572 armNextPC = reg[15].I & 0xFFFFFFFE;
7573 reg[15].I = armNextPC + 2;
7574 THUMB_PREFETCH;
7575 }
7576 } else {
7577 LDM_REG(1, 0);
7578 LDM_REG(2, 1);
7579 LDM_REG(4, 2);
7580 LDM_REG(8, 3);
7581 LDM_REG(16, 4);
7582 LDM_REG(32, 5);
7583 LDM_REG(64, 6);
7584 LDM_REG(128, 7);
7585
7586 if(armMode == 0x11) {
7587 LDM_REG(256, R8_FIQ);
7588 LDM_REG(512, R9_FIQ);
7589 LDM_REG(1024, R10_FIQ);
7590 LDM_REG(2048, R11_FIQ);
7591 LDM_REG(4096, R12_FIQ);
7592 } else {
7593 LDM_REG(256, 8);
7594 LDM_REG(512, 9);
7595 LDM_REG(1024, 10);
7596 LDM_REG(2048, 11);
7597 LDM_REG(4096, 12);
7598 }
7599
7600 if(armMode != 0x10 && armMode != 0x1f) {
7601 LDM_REG(8192, R13_USR);
7602 LDM_REG(16384, R14_USR);
7603 } else {
7604 LDM_REG(8192, 13);
7605 LDM_REG(16384, 14);
7606 }
7607
7608 if(!(opcode & (1 << base)))
7609 reg[base].I = temp;
7610 if (!offset)
7611 clockTicks += 1 + dataTicksAccesint32(address);
7612 else
7613 clockTicks += 1 + dataTicksAccessSeq32(address);
7614 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7615 }
7616 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7617 }
7618 break;
7619
7620 CASE_16(0x990)
7621 {
7622 // LDMIB Rn, {Rlist}
7623 if (busPrefetchCount==0)
7624 busPrefetch = busPrefetchEnable;
7625 int base = (opcode & 0x000F0000) >> 16;
7626 uint32 address = (reg[base].I+4) & 0xFFFFFFFC;
7627 clockTicks = 0;
7628 int offset = 0;
7629 LDM_REG(1, 0);
7630 LDM_REG(2, 1);
7631 LDM_REG(4, 2);
7632 LDM_REG(8, 3);
7633 LDM_REG(16, 4);
7634 LDM_REG(32, 5);
7635 LDM_REG(64, 6);
7636 LDM_REG(128, 7);
7637 LDM_REG(256, 8);
7638 LDM_REG(512, 9);
7639 LDM_REG(1024, 10);
7640 LDM_REG(2048, 11);
7641 LDM_REG(4096, 12);
7642 LDM_REG(8192, 13);
7643 LDM_REG(16384, 14);
7644 if(opcode & 32768) {
7645 reg[15].I = CPUReadMemory(address);
7646
7647 armNextPC = reg[15].I;
7648 reg[15].I += 4;
7649 ARM_PREFETCH;
7650 if (!offset)
7651 clockTicks += 1 + dataTicksAccesint32(address);
7652 else
7653 clockTicks += 1 + dataTicksAccessSeq32(address);
7654 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7655 }
7656 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7657 }
7658 break;
7659 CASE_16(0x9b0)
7660 {
7661 // LDMIB Rn!, {Rlist}
7662 if (busPrefetchCount==0)
7663 busPrefetch = busPrefetchEnable;
7664 int base = (opcode & 0x000F0000) >> 16;
7665 uint32 temp = reg[base].I +
7666 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7667 uint32 address = (reg[base].I+4) & 0xFFFFFFFC;
7668 clockTicks = 0;
7669 int offset = 0;
7670 LDM_REG(1, 0);
7671 LDM_REG(2, 1);
7672 LDM_REG(4, 2);
7673 LDM_REG(8, 3);
7674 LDM_REG(16, 4);
7675 LDM_REG(32, 5);
7676 LDM_REG(64, 6);
7677 LDM_REG(128, 7);
7678 LDM_REG(256, 8);
7679 LDM_REG(512, 9);
7680 LDM_REG(1024, 10);
7681 LDM_REG(2048, 11);
7682 LDM_REG(4096, 12);
7683 LDM_REG(8192, 13);
7684 LDM_REG(16384, 14);
7685 if(opcode & 32768) {
7686 reg[15].I = CPUReadMemory(address);
7687 if (!offset)
7688 clockTicks += 1 + dataTicksAccesint32(address);
7689 else
7690 clockTicks += 1 + dataTicksAccessSeq32(address);
7691 clockTicks += 1 + dataTicksAccessSeq32(address);
7692
7693 armNextPC = reg[15].I;
7694 reg[15].I += 4;
7695 ARM_PREFETCH;
7696 if (!offset)
7697 clockTicks += 1 + dataTicksAccesint32(address);
7698 else
7699 clockTicks += 1 + dataTicksAccessSeq32(address);
7700 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7701 }
7702 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7703 if(!(opcode & (1 << base)))
7704 reg[base].I = temp;
7705 }
7706 break;
7707 CASE_16(0x9d0)
7708 {
7709 // LDMIB Rn, {Rlist}^
7710 if (busPrefetchCount==0)
7711 busPrefetch = busPrefetchEnable;
7712 int base = (opcode & 0x000F0000) >> 16;
7713 uint32 address = (reg[base].I+4) & 0xFFFFFFFC;
7714 clockTicks = 0;
7715 int offset = 0;
7716 if(opcode & 0x8000) {
7717 LDM_REG(1, 0);
7718 LDM_REG(2, 1);
7719 LDM_REG(4, 2);
7720 LDM_REG(8, 3);
7721 LDM_REG(16, 4);
7722 LDM_REG(32, 5);
7723 LDM_REG(64, 6);
7724 LDM_REG(128, 7);
7725 LDM_REG(256, 8);
7726 LDM_REG(512, 9);
7727 LDM_REG(1024, 10);
7728 LDM_REG(2048, 11);
7729 LDM_REG(4096, 12);
7730 LDM_REG(8192, 13);
7731 LDM_REG(16384, 14);
7732
7733 reg[15].I = CPUReadMemory(address);
7734
7735 CPUSwitchMode(reg[17].I & 0x1f, false);
7736 if(armState) {
7737 armNextPC = reg[15].I & 0xFFFFFFFC;
7738 reg[15].I = armNextPC + 4;
7739 ARM_PREFETCH;
7740 } else {
7741 armNextPC = reg[15].I & 0xFFFFFFFE;
7742 reg[15].I = armNextPC + 2;
7743 THUMB_PREFETCH;
7744 }
7745 } else {
7746 LDM_REG(1, 0);
7747 LDM_REG(2, 1);
7748 LDM_REG(4, 2);
7749 LDM_REG(8, 3);
7750 LDM_REG(16, 4);
7751 LDM_REG(32, 5);
7752 LDM_REG(64, 6);
7753 LDM_REG(128, 7);
7754
7755 if(armMode == 0x11) {
7756 LDM_REG(256, R8_FIQ);
7757 LDM_REG(512, R9_FIQ);
7758 LDM_REG(1024, R10_FIQ);
7759 LDM_REG(2048, R11_FIQ);
7760 LDM_REG(4096, R12_FIQ);
7761 } else {
7762 LDM_REG(256, 8);
7763 LDM_REG(512, 9);
7764 LDM_REG(1024, 10);
7765 LDM_REG(2048, 11);
7766 LDM_REG(4096, 12);
7767 }
7768
7769 if(armMode != 0x10 && armMode != 0x1f) {
7770 LDM_REG(8192, R13_USR);
7771 LDM_REG(16384, R14_USR);
7772 } else {
7773 LDM_REG(8192, 13);
7774 LDM_REG(16384, 14);
7775 }
7776 if (!offset)
7777 clockTicks += 1 + dataTicksAccesint32(address);
7778 else
7779 clockTicks += 1 + dataTicksAccessSeq32(address);
7780 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7781 }
7782 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7783 }
7784 break;
7785 CASE_16(0x9f0)
7786 {
7787 // LDMIB Rn!, {Rlist}^
7788 if (busPrefetchCount==0)
7789 busPrefetch = busPrefetchEnable;
7790 int base = (opcode & 0x000F0000) >> 16;
7791 uint32 temp = reg[base].I +
7792 4 * (cpuBitsSet[opcode & 255] + cpuBitsSet[(opcode >> 8) & 255]);
7793 uint32 address = (reg[base].I+4) & 0xFFFFFFFC;
7794 clockTicks = 0;
7795 int offset = 0;
7796 if(opcode & 0x8000) {
7797 LDM_REG(1, 0);
7798 LDM_REG(2, 1);
7799 LDM_REG(4, 2);
7800 LDM_REG(8, 3);
7801 LDM_REG(16, 4);
7802 LDM_REG(32, 5);
7803 LDM_REG(64, 6);
7804 LDM_REG(128, 7);
7805 LDM_REG(256, 8);
7806 LDM_REG(512, 9);
7807 LDM_REG(1024, 10);
7808 LDM_REG(2048, 11);
7809 LDM_REG(4096, 12);
7810 LDM_REG(8192, 13);
7811 LDM_REG(16384, 14);
7812
7813 reg[15].I = CPUReadMemory(address);
7814
7815 if(!(opcode & (1 << base)))
7816 reg[base].I = temp;
7817
7818 CPUSwitchMode(reg[17].I & 0x1f, false);
7819 if(armState) {
7820 armNextPC = reg[15].I & 0xFFFFFFFC;
7821 reg[15].I = armNextPC + 4;
7822 ARM_PREFETCH;
7823 } else {
7824 armNextPC = reg[15].I & 0xFFFFFFFE;
7825 reg[15].I = armNextPC + 2;
7826 THUMB_PREFETCH;
7827 }
7828 } else {
7829 LDM_REG(1, 0);
7830 LDM_REG(2, 1);
7831 LDM_REG(4, 2);
7832 LDM_REG(8, 3);
7833 LDM_REG(16, 4);
7834 LDM_REG(32, 5);
7835 LDM_REG(64, 6);
7836 LDM_REG(128, 7);
7837
7838 if(armMode == 0x11) {
7839 LDM_REG(256, R8_FIQ);
7840 LDM_REG(512, R9_FIQ);
7841 LDM_REG(1024, R10_FIQ);
7842 LDM_REG(2048, R11_FIQ);
7843 LDM_REG(4096, R12_FIQ);
7844 } else {
7845 LDM_REG(256, 8);
7846 LDM_REG(512, 9);
7847 LDM_REG(1024, 10);
7848 LDM_REG(2048, 11);
7849 LDM_REG(4096, 12);
7850 }
7851
7852 if(armMode != 0x10 && armMode != 0x1f) {
7853 LDM_REG(8192, R13_USR);
7854 LDM_REG(16384, R14_USR);
7855 } else {
7856 LDM_REG(8192, 13);
7857 LDM_REG(16384, 14);
7858 }
7859
7860 if(!(opcode & (1 << base)))
7861 reg[base].I = temp;
7862 if (!offset)
7863 clockTicks += 1 + dataTicksAccesint32(address);
7864 else
7865 clockTicks += 1 + dataTicksAccessSeq32(address);
7866 clockTicks += 1 + codeTicksAccessSeq32(armNextPC);
7867 }
7868 clockTicks += 2 + codeTicksAccesint32(armNextPC);
7869 }
7870 break;
7871 CASE_256(0xa00)
7872 {
7873 // B <offset>
7874 const uint32 offset = ((int32)((opcode & 0x00FFFFFF) << 8)) >> 6;
7875
7876 reg[15].I += offset;
7877 armNextPC = reg[15].I;
7878 reg[15].I += 4;
7879 ARM_PREFETCH;
7880 clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
7881 clockTicks += 2 + codeTicksAccesint32(armNextPC) +
7882 codeTicksAccessSeq32(armNextPC);
7883 busPrefetchCount=0;
7884 }
7885 break;
7886 CASE_256(0xb00)
7887 {
7888 // BL <offset>
7889 const uint32 offset = ((int32)((opcode & 0x00FFFFFF) << 8)) >> 6;
7890
7891 reg[14].I = reg[15].I - 4;
7892 reg[15].I += offset;
7893 armNextPC = reg[15].I;
7894 reg[15].I += 4;
7895 ARM_PREFETCH;
7896 clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
7897 clockTicks += 2 + codeTicksAccesint32(armNextPC) +
7898 codeTicksAccessSeq32(armNextPC);
7899 busPrefetchCount=0;
7900 }
7901 break;
7902 CASE_256(0xf00)
7903 // SWI <comment>
7904 clockTicks = codeTicksAccessSeq32(armNextPC) + 1;
7905 clockTicks += 2 + codeTicksAccesint32(armNextPC) +
7906 codeTicksAccessSeq32(armNextPC);
7907 busPrefetchCount=0;
7908 CPUSoftwareInterrupt(opcode & 0x00FFFFFF);
7909
7910 break;
7911 #ifdef GP_SUPPORT
7912 case 0xe11:
7913 case 0xe13:
7914 case 0xe15:
7915 case 0xe17:
7916 case 0xe19:
7917 case 0xe1b:
7918 case 0xe1d:
7919 case 0xe1f:
7920 // MRC
7921 break;
7922 case 0xe01:
7923 case 0xe03:
7924 case 0xe05:
7925 case 0xe07:
7926 case 0xe09:
7927 case 0xe0b:
7928 case 0xe0d:
7929 case 0xe0f:
7930 // MRC
7931 break;
7932 #endif
7933 default:
7934 CPUUndefinedException();
7935 break;
7936 // END
7937 }
7938 }
7939
7940 if (clockTicks == 0)
7941 clockTicks = codeTicksAccessSeq32(oldArmNextPC) + 1;
7942
7943 return(clockTicks);
7944 }
7945
7946 }
7947