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