1 /*
2   www.freedo.org
3   The first working 3DO multiplayer emulator.
4 
5   The FreeDO licensed under modified GNU LGPL, with following notes:
6 
7   *   The owners and original authors of the FreeDO have full right to
8   *   develop closed source derivative work.
9 
10   *   Any non-commercial uses of the FreeDO sources or any knowledge
11   *   obtained by studying or reverse engineering of the sources, or
12   *   any other material published by FreeDO have to be accompanied
13   *   with full credits.
14 
15   *   Any commercial uses of FreeDO sources or any knowledge obtained
16   *   by studying or reverse engineering of the sources, or any other
17   *   material published by FreeDO is strictly forbidden without
18   *   owners approval.
19 
20   The above notes are taking precedence over GNU LGPL in conflicting
21   situations.
22 
23   Project authors:
24   *  Alexander Troosh
25   *  Maxim Grishin
26   *  Allen Wright
27   *  John Sammons
28   *  Felix Lazarev
29 */
30 
31 #include "bool.h"
32 #include "endianness.h"
33 #include "hack_flags.h"
34 #include "inline.h"
35 #include "opera_arm.h"
36 #include "opera_arm_core.h"
37 #include "opera_clio.h"
38 #include "opera_core.h"
39 #include "opera_diag_port.h"
40 #include "opera_fixedpoint_math.h"
41 #include "opera_madam.h"
42 #include "opera_sport.h"
43 #include "opera_swi_hle_0x5XXXX.h"
44 
45 #include <stdint.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 
50 #define ARM_INITIAL_PC  0x03000000
51 
52 #define ARM_MUL_MASK    0x0fc000f0
53 #define ARM_MUL_SIGN    0x00000090
54 #define ARM_SDS_MASK    0x0fb00ff0
55 #define ARM_SDS_SIGN    0x01000090
56 #define ARM_UND_MASK    0x0e000010
57 #define ARM_UND_SIGN    0x06000010
58 #define ARM_MRS_MASK    0x0fbf0fff
59 #define ARM_MRS_SIGN    0x010f0000
60 #define ARM_MSR_MASK    0x0fbffff0
61 #define ARM_MSR_SIGN    0x0129f000
62 #define ARM_MSRF_MASK   0x0dbff000
63 #define ARM_MSRF_SIGN   0x0128f000
64 
65 #define ARM_MODE_USER   0
66 #define ARM_MODE_FIQ    1
67 #define ARM_MODE_IRQ    2
68 #define ARM_MODE_SVC    3
69 #define ARM_MODE_ABT    4
70 #define ARM_MODE_UND    5
71 #define ARM_MODE_UNK    0xff
72 
73 const static uint8_t arm_mode_table[]=
74   {
75     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,
76     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,
77     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,
78     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,
79     ARM_MODE_USER,    ARM_MODE_FIQ,     ARM_MODE_IRQ,     ARM_MODE_SVC,
80     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_ABT,
81     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UND,
82     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK,     ARM_MODE_UNK
83   };
84 
85 #define NCYCLE 4
86 #define SCYCLE 1
87 #define ICYCLE 1
88 
89 //--------------------------Conditions-------------------------------------------
90 // flags - N Z C V  -  31...28
91 const static uint16_t cond_flags_cross[]=
92   {
93     0xf0f0, //EQ - Z set (equal)
94     0x0f0f, //NE - Z clear (not equal)
95     0xcccc, //CS - C set (unsigned higher or same)
96     0x3333, //CC - C clear (unsigned lower)
97     0xff00, //N set (negative)
98     0x00ff, //N clear (positive or zero)
99     0xaaaa, //V set (overflow)
100     0x5555, //V clear (no overflow)
101     0x0c0c, //C set and Z clear (unsigned higher)
102     0xf3f3, //C clear or Z set (unsigned lower or same)
103     0xaa55, //N set and V set, or N clear and V clear (greater or equal)
104     0x55aa, //N set and V clear, or N clear and V set (less than)
105     0x0a05, //Z clear, and either N set and V set, or N clear and V clear (greater than)
106     0xf5fa, //Z set, or N set and V clear, or N clear and V set (less than or equal)
107     0xffff, //always
108     0x0000  //never
109   };
110 
111 #define DRAM_SIZE  ( 2 * 1024 * 1024)
112 #define VRAM_SIZE  ( 1 * 1024 * 1024)
113 #define RAM_SIZE   ( 3 * 1024 * 1024)
114 #define ROM1_SIZE  ( 1 * 1024 * 1024)
115 #define ROM2_SIZE  ( 1 * 1024 * 1024)
116 #define NVRAM_SIZE (32 * 1024)
117 
118 static int        g_SWI_HLE;
119 static arm_core_t CPU;
120 static int        CYCLES;	//cycle counter
121 
122 static uint32_t readusr(uint32_t rn);
123 static void     loadusr(uint32_t rn, uint32_t val);
124 static uint32_t mreadb(uint32_t addr);
125 static void     mwriteb(uint32_t addr, uint8_t val);
126 static uint32_t mreadw(uint32_t addr);
127 static void     mwritew(uint32_t addr,uint32_t val);
128 
129 uint8_t*
opera_arm_nvram_get(void)130 opera_arm_nvram_get(void)
131 {
132   return CPU.nvram;
133 }
134 
135 uint64_t
opera_arm_nvram_size(void)136 opera_arm_nvram_size(void)
137 {
138   return NVRAM_SIZE;
139 }
140 
141 uint8_t*
opera_arm_rom1_get(void)142 opera_arm_rom1_get(void)
143 {
144   return CPU.rom1;
145 }
146 
147 uint64_t
opera_arm_rom1_size(void)148 opera_arm_rom1_size(void)
149 {
150   return ROM1_SIZE;
151 }
152 
153 void
opera_arm_rom1_byteswap_if_necessary(void)154 opera_arm_rom1_byteswap_if_necessary(void)
155 {
156   uint8_t *rom;
157   int64_t  size;
158 
159   rom  = opera_arm_rom1_get();
160   size = opera_arm_rom1_size();
161 
162   swap32_array_if_little_endian((uint32_t*)rom,(size / sizeof(uint32_t)));
163 }
164 
165 uint8_t*
opera_arm_rom2_get(void)166 opera_arm_rom2_get(void)
167 {
168   return CPU.rom2;
169 }
170 
171 uint64_t
opera_arm_rom2_size(void)172 opera_arm_rom2_size(void)
173 {
174   return ROM2_SIZE;
175 }
176 
177 void
opera_arm_rom2_byteswap_if_necessary(void)178 opera_arm_rom2_byteswap_if_necessary(void)
179 {
180   uint8_t *rom;
181   int64_t  size;
182 
183   rom  = opera_arm_rom2_get();
184   size = opera_arm_rom2_size();
185 
186   swap32_array_if_little_endian((uint32_t*)rom,(size / sizeof(uint32_t)));
187 }
188 
189 uint8_t*
opera_arm_ram_get(void)190 opera_arm_ram_get(void)
191 {
192   return CPU.ram;
193 }
194 
195 uint64_t
opera_arm_ram_size(void)196 opera_arm_ram_size(void)
197 {
198   return DRAM_SIZE;
199 }
200 
201 uint8_t*
opera_arm_vram_get(void)202 opera_arm_vram_get(void)
203 {
204   return (CPU.ram + DRAM_SIZE);
205 }
206 
207 uint64_t
opera_arm_vram_size(void)208 opera_arm_vram_size(void)
209 {
210   return VRAM_SIZE;
211 }
212 
213 uint32_t
opera_arm_state_size(void)214 opera_arm_state_size(void)
215 {
216   return (sizeof(arm_core_t) + RAM_SIZE + ROM1_SIZE + NVRAM_SIZE);
217 }
218 
219 void
opera_arm_state_save(void * buf_)220 opera_arm_state_save(void *buf_)
221 {
222   memcpy(buf_,&CPU,sizeof(arm_core_t));
223   memcpy(((uint8_t*)buf_)+sizeof(arm_core_t),CPU.ram,RAM_SIZE);
224   memcpy(((uint8_t*)buf_)+sizeof(arm_core_t)+RAM_SIZE,CPU.rom1,ROM1_SIZE);
225   memcpy(((uint8_t*)buf_)+sizeof(arm_core_t)+RAM_SIZE+ROM1_SIZE,CPU.nvram,NVRAM_SIZE);
226 }
227 
228 void
opera_arm_state_load(const void * buf_)229 opera_arm_state_load(const void *buf_)
230 {
231   uint8_t i;
232   uint8_t *ram   = CPU.ram;
233   uint8_t *rom1  = CPU.rom1;
234   uint8_t *rom2  = CPU.rom2;
235   uint8_t *nvram = CPU.nvram;
236 
237   memcpy(&CPU,buf_,sizeof(arm_core_t));
238   memcpy(ram,((uint8_t*)buf_)+sizeof(arm_core_t),RAM_SIZE);
239   memcpy(rom1,((uint8_t*)buf_)+sizeof(arm_core_t)+RAM_SIZE,ROM1_SIZE);
240   memcpy(nvram,((uint8_t*)buf_)+sizeof(arm_core_t)+RAM_SIZE+ROM1_SIZE,NVRAM_SIZE);
241 
242   for(i = 3; i < 18; i++)
243     memcpy(ram + (i * 1024 * 1024),
244            ram + (2 * 1024 * 1024),
245            1024 * 1024);
246 
247   CPU.ram   = ram;
248   CPU.rom1  = rom1;
249   CPU.rom2  = rom2;
250   CPU.nvram = nvram;
251 }
252 
253 static
254 void
ARM_RestUserRONS(void)255 ARM_RestUserRONS(void)
256 {
257   switch(arm_mode_table[CPU.CPSR & 0x1F])
258     {
259     case ARM_MODE_USER:
260       break;
261     case ARM_MODE_FIQ:
262       memcpy(CPU.FIQ,&CPU.USER[8],7<<2);
263       memcpy(&CPU.USER[8],CPU.CASH,7<<2);
264       break;
265     case ARM_MODE_IRQ:
266       CPU.IRQ[0]   = CPU.USER[13];
267       CPU.IRQ[1]   = CPU.USER[14];
268       CPU.USER[13] = CPU.CASH[5];
269       CPU.USER[14] = CPU.CASH[6];
270       break;
271     case ARM_MODE_SVC:
272       CPU.SVC[0]   = CPU.USER[13];
273       CPU.SVC[1]   = CPU.USER[14];
274       CPU.USER[13] = CPU.CASH[5];
275       CPU.USER[14] = CPU.CASH[6];
276       break;
277     case ARM_MODE_ABT:
278       CPU.ABT[0]   = CPU.USER[13];
279       CPU.ABT[1]   = CPU.USER[14];
280       CPU.USER[13] = CPU.CASH[5];
281       CPU.USER[14] = CPU.CASH[6];
282       break;
283     case ARM_MODE_UND:
284       CPU.UND[0]   = CPU.USER[13];
285       CPU.UND[1]   = CPU.USER[14];
286       CPU.USER[13] = CPU.CASH[5];
287       CPU.USER[14] = CPU.CASH[6];
288       break;
289     }
290 }
291 
292 static
293 void
ARM_RestFiqRONS(void)294 ARM_RestFiqRONS(void)
295 {
296   switch(arm_mode_table[CPU.CPSR & 0x1F])
297     {
298     case ARM_MODE_USER:
299       memcpy(CPU.CASH,&CPU.USER[8],7<<2);
300       memcpy(&CPU.USER[8],CPU.FIQ,7<<2);
301       break;
302     case ARM_MODE_FIQ:
303       break;
304     case ARM_MODE_IRQ:
305       memcpy(CPU.CASH,&CPU.USER[8],5<<2);
306       CPU.IRQ[0] = CPU.USER[13];
307       CPU.IRQ[1] = CPU.USER[14];
308       memcpy(&CPU.USER[8],CPU.FIQ,7<<2);
309       break;
310     case ARM_MODE_SVC:
311       memcpy(CPU.CASH,&CPU.USER[8],5<<2);
312       CPU.SVC[0] = CPU.USER[13];
313       CPU.SVC[1] = CPU.USER[14];
314       memcpy(&CPU.USER[8],CPU.FIQ,7<<2);
315       break;
316     case ARM_MODE_ABT:
317       memcpy(CPU.CASH,&CPU.USER[8],5<<2);
318       CPU.ABT[0] = CPU.USER[13];
319       CPU.ABT[1] = CPU.USER[14];
320       memcpy(&CPU.USER[8],CPU.FIQ,7<<2);
321       break;
322     case ARM_MODE_UND:
323       memcpy(CPU.CASH,&CPU.USER[8],5<<2);
324       CPU.UND[0] = CPU.USER[13];
325       CPU.UND[1] = CPU.USER[14];
326       memcpy(&CPU.USER[8],CPU.FIQ,7<<2);
327       break;
328     }
329 }
330 
331 static
332 void
ARM_RestIrqRONS(void)333 ARM_RestIrqRONS(void)
334 {
335   switch(arm_mode_table[CPU.CPSR & 0x1F])
336     {
337     case ARM_MODE_USER:
338       CPU.CASH[5]  = CPU.USER[13];
339       CPU.CASH[6]  = CPU.USER[14];
340       CPU.USER[13] = CPU.IRQ[0];
341       CPU.USER[14] = CPU.IRQ[1];
342       break;
343     case ARM_MODE_FIQ:
344       memcpy(CPU.FIQ,&CPU.USER[8],7<<2);
345       memcpy(&CPU.USER[8],CPU.CASH,5<<2);
346       CPU.USER[13] = CPU.IRQ[0];
347       CPU.USER[14] = CPU.IRQ[1];
348       break;
349     case ARM_MODE_IRQ:
350       break;
351     case ARM_MODE_SVC:
352       CPU.SVC[0]   = CPU.USER[13];
353       CPU.SVC[1]   = CPU.USER[14];
354       CPU.USER[13] = CPU.IRQ[0];
355       CPU.USER[14] = CPU.IRQ[1];
356       break;
357     case ARM_MODE_ABT:
358       CPU.ABT[0]   = CPU.USER[13];
359       CPU.ABT[1]   = CPU.USER[14];
360       CPU.USER[13] = CPU.IRQ[0];
361       CPU.USER[14] = CPU.IRQ[1];
362       break;
363     case ARM_MODE_UND:
364       CPU.UND[0]   = CPU.USER[13];
365       CPU.UND[1]   = CPU.USER[14];
366       CPU.USER[13] = CPU.IRQ[0];
367       CPU.USER[14] = CPU.IRQ[1];
368       break;
369     }
370 }
371 
372 static
373 void
ARM_RestSvcRONS(void)374 ARM_RestSvcRONS(void)
375 {
376   switch(arm_mode_table[CPU.CPSR & 0x1F])
377     {
378     case ARM_MODE_USER:
379       CPU.CASH[5]  = CPU.USER[13];
380       CPU.CASH[6]  = CPU.USER[14];
381       CPU.USER[13] = CPU.SVC[0];
382       CPU.USER[14] = CPU.SVC[1];
383       break;
384     case ARM_MODE_FIQ:
385       memcpy(CPU.FIQ,&CPU.USER[8],7<<2);
386       memcpy(&CPU.USER[8],CPU.CASH,5<<2);
387       CPU.USER[13] = CPU.SVC[0];
388       CPU.USER[14] = CPU.SVC[1];
389       break;
390     case ARM_MODE_IRQ:
391       CPU.IRQ[0]   = CPU.USER[13];
392       CPU.IRQ[1]   = CPU.USER[14];
393       CPU.USER[13] = CPU.SVC[0];
394       CPU.USER[14] = CPU.SVC[1];
395       break;
396     case ARM_MODE_SVC:
397       break;
398     case ARM_MODE_ABT:
399       CPU.ABT[0]   = CPU.USER[13];
400       CPU.ABT[1]   = CPU.USER[14];
401       CPU.USER[13] = CPU.SVC[0];
402       CPU.USER[14] = CPU.SVC[1];
403       break;
404     case ARM_MODE_UND:
405       CPU.UND[0]   = CPU.USER[13];
406       CPU.UND[1]   = CPU.USER[14];
407       CPU.USER[13] = CPU.SVC[0];
408       CPU.USER[14] = CPU.SVC[1];
409       break;
410     }
411 }
412 
413 static
414 void
ARM_RestAbtRONS(void)415 ARM_RestAbtRONS(void)
416 {
417   switch(arm_mode_table[CPU.CPSR & 0x1F])
418     {
419     case ARM_MODE_USER:
420       CPU.CASH[5]  = CPU.USER[13];
421       CPU.CASH[6]  = CPU.USER[14];
422       CPU.USER[13] = CPU.ABT[0];
423       CPU.USER[14] = CPU.ABT[1];
424       break;
425     case ARM_MODE_FIQ:
426       memcpy(CPU.FIQ,&CPU.USER[8],7<<2);
427       memcpy(&CPU.USER[8],CPU.CASH,5<<2);
428       CPU.USER[13] = CPU.ABT[0];
429       CPU.USER[14] = CPU.ABT[1];
430       break;
431     case ARM_MODE_IRQ:
432       CPU.IRQ[0]   = CPU.USER[13];
433       CPU.IRQ[1]   = CPU.USER[14];
434       CPU.USER[13] = CPU.ABT[0];
435       CPU.USER[14] = CPU.ABT[1];
436       break;
437     case ARM_MODE_SVC:
438       CPU.SVC[0]   = CPU.USER[13];
439       CPU.SVC[1]   = CPU.USER[14];
440       CPU.USER[13] = CPU.ABT[0];
441       CPU.USER[14] = CPU.ABT[1];
442       break;
443     case ARM_MODE_ABT:
444       break;
445     case ARM_MODE_UND:
446       CPU.UND[0]   = CPU.USER[13];
447       CPU.UND[1]   = CPU.USER[14];
448       CPU.USER[13] = CPU.ABT[0];
449       CPU.USER[14] = CPU.ABT[1];
450       break;
451     }
452 }
453 
454 static
455 void
ARM_RestUndRONS(void)456 ARM_RestUndRONS(void)
457 {
458   switch(arm_mode_table[CPU.CPSR & 0x1F])
459     {
460     case ARM_MODE_USER:
461       CPU.CASH[5]  = CPU.USER[13];
462       CPU.CASH[6]  = CPU.USER[14];
463       CPU.USER[13] = CPU.UND[0];
464       CPU.USER[14] = CPU.UND[1];
465       break;
466     case ARM_MODE_FIQ:
467       memcpy(CPU.FIQ,&CPU.USER[8],7<<2);
468       memcpy(&CPU.USER[8],CPU.CASH,5<<2);
469       CPU.USER[13] = CPU.UND[0];
470       CPU.USER[14] = CPU.UND[1];
471       break;
472     case ARM_MODE_IRQ:
473       CPU.IRQ[0]   = CPU.USER[13];
474       CPU.IRQ[1]   = CPU.USER[14];
475       CPU.USER[13] = CPU.UND[0];
476       CPU.USER[14] = CPU.UND[1];
477       break;
478     case ARM_MODE_SVC:
479       CPU.SVC[0]   = CPU.USER[13];
480       CPU.SVC[1]   = CPU.USER[14];
481       CPU.USER[13] = CPU.UND[0];
482       CPU.USER[14] = CPU.UND[1];
483       break;
484     case ARM_MODE_ABT:
485       CPU.ABT[0]   = CPU.USER[13];
486       CPU.ABT[1]   = CPU.USER[14];
487       CPU.USER[13] = CPU.UND[0];
488       CPU.USER[14] = CPU.UND[1];
489       break;
490     case ARM_MODE_UND:
491       break;
492     }
493 }
494 
495 static
496 void
ARM_Change_ModeSafe(uint32_t mode_)497 ARM_Change_ModeSafe(uint32_t mode_)
498 {
499   switch(arm_mode_table[mode_ & 0x1F])
500     {
501     case ARM_MODE_USER:
502       ARM_RestUserRONS();
503       break;
504     case ARM_MODE_FIQ:
505       ARM_RestFiqRONS();
506       break;
507     case ARM_MODE_IRQ:
508       ARM_RestIrqRONS();
509       break;
510     case ARM_MODE_SVC:
511       ARM_RestSvcRONS();
512       break;
513     case ARM_MODE_ABT:
514       ARM_RestAbtRONS();
515       break;
516     case ARM_MODE_UND:
517       ARM_RestUndRONS();
518       break;
519     }
520 }
521 
522 void
opera_arm_rom_select(int n_)523 opera_arm_rom_select(int n_)
524 {
525   CPU.rom = ((n_ == 0) ? CPU.rom1 : CPU.rom2);
526 }
527 
528 static
529 INLINE
530 void
arm_cpsr_set(uint32_t a_)531 arm_cpsr_set(uint32_t a_)
532 {
533   a_ |= 0x10;
534   ARM_Change_ModeSafe(a_);
535   CPU.CPSR = (a_ & 0xf00000df);
536 }
537 
538 
539 static
540 INLINE
541 void
SETM(uint32_t a_)542 SETM(uint32_t a_)
543 {
544   a_ |= 0x10;
545   ARM_Change_ModeSafe(a_);
546   CPU.CPSR = ((CPU.CPSR & 0xffffffe0) | (a_ & 0x1F));
547 }
548 
549 static
550 INLINE
551 void
SETN(int a_)552 SETN(int a_)
553 {
554   CPU.CPSR = (CPU.CPSR & 0x7fffffff) | ((a_ ? 1 << 31 : 0));
555 }
556 
557 static
558 INLINE
559 void
SETZ(int a_)560 SETZ(int a_)
561 {
562   CPU.CPSR = (CPU.CPSR & 0xbfffffff) | ((a_ ? 1 << 30 : 0));
563 }
564 
565 static
566 INLINE
567 void
SETC(int a_)568 SETC(int a_)
569 {
570   CPU.CPSR = (CPU.CPSR & 0xdfffffff) | ((a_ ? 1 << 29 : 0));
571 }
572 
573 static
574 INLINE
575 void
SETV(int a_)576 SETV(int a_)
577 {
578   CPU.CPSR = (CPU.CPSR & 0xefffffff) | ((a_ ? 1 << 28 : 0));
579 }
580 
581 static
582 INLINE
583 void
SETI(int a_)584 SETI(int a_)
585 {
586   CPU.CPSR = (CPU.CPSR & 0xffffff7f) | ((a_ ? 1 << 7 : 0));
587 }
588 
589 static
590 INLINE
591 void
SETF(int a_)592 SETF(int a_)
593 {
594   CPU.CPSR = (CPU.CPSR & 0xffffffbf) | ((a_ ? 1 << 6 : 0));
595 }
596 
597 #define MODE ((CPU.CPSR & 0x1F))
598 #define ISN  ((CPU.CPSR >> 31) & 1)
599 #define ISZ  ((CPU.CPSR >> 30) & 1)
600 #define ISC  ((CPU.CPSR >> 29) & 1)
601 #define ISV  ((CPU.CPSR >> 28) & 1)
602 #define ISI  ((CPU.CPSR >>  7) & 1)
603 #define ISF  ((CPU.CPSR >>  6) & 1)
604 
605 static
606 INLINE
607 uint32_t
ROTR(const uint32_t val_,const uint32_t shift_)608 ROTR(const uint32_t val_,
609      const uint32_t shift_)
610 {
611   return (shift_ ?
612           ((val_ >> shift_) | (val_ << (32 - shift_))) :
613           val_);
614 }
615 
616 void
opera_arm_init(void)617 opera_arm_init(void)
618 {
619   int i;
620 
621   g_SWI_HLE = 0;
622 
623   CYCLES = 0;
624   for(i = 0; i < 16; i++)
625     CPU.USER[i] = 0;
626 
627   for(i = 0; i < 2; i++)
628     {
629       CPU.SVC[i] = 0;
630       CPU.ABT[i] = 0;
631       CPU.IRQ[i] = 0;
632       CPU.UND[i] = 0;
633     }
634 
635   for(i = 0;i < 7; i++)
636     CPU.CASH[i] = CPU.FIQ[i] = 0;
637 
638   CPU.ram   = calloc(RAM_SIZE + 1024*1024*16,1);
639   CPU.rom1  = calloc(ROM1_SIZE,1);
640   CPU.rom2  = calloc(ROM2_SIZE,1);
641   CPU.rom   = CPU.rom1;
642   CPU.nvram = calloc(NVRAM_SIZE,1);
643 
644   CPU.nFIQ = FALSE;
645   CPU.MAS_Access_Exept = FALSE;
646 
647   CPU.USER[15] = ARM_INITIAL_PC;
648   arm_cpsr_set(0x13);
649 }
650 
651 void
opera_arm_destroy(void)652 opera_arm_destroy(void)
653 {
654   if(CPU.nvram)
655     free(CPU.nvram);
656   CPU.nvram = NULL;
657 
658   if(CPU.rom1)
659     free(CPU.rom1);
660   CPU.rom1 = NULL;
661 
662   if(CPU.rom2)
663     free(CPU.rom2);
664   CPU.rom2 = NULL;
665 
666   if(CPU.ram)
667     free(CPU.ram);
668   CPU.ram = NULL;
669 }
670 
671 void
opera_arm_reset(void)672 opera_arm_reset(void)
673 {
674   int i;
675 
676   CYCLES = 0;
677   CPU.rom = CPU.rom1;
678 
679   for(i = 0; i < 16; i++)
680     CPU.USER[i] = 0;
681 
682   for(i = 0; i < 2; i++)
683     {
684       CPU.SVC[i] = 0;
685       CPU.ABT[i] = 0;
686       CPU.IRQ[i] = 0;
687       CPU.UND[i] = 0;
688     }
689 
690   for(i = 0; i < 7; i++)
691     CPU.CASH[i] = CPU.FIQ[i] = 0;
692 
693   CPU.MAS_Access_Exept = FALSE;
694 
695   CPU.nFIQ = FALSE;
696 
697   CPU.USER[15] = ARM_INITIAL_PC;
698   arm_cpsr_set(0x13);
699 
700   opera_clio_reset();
701   opera_madam_reset();
702 }
703 
704 void
opera_arm_swi_hle_set(const int hle_)705 opera_arm_swi_hle_set(const int hle_)
706 {
707   g_SWI_HLE = !!hle_;
708 }
709 
710 int
opera_arm_swi_hle_get(void)711 opera_arm_swi_hle_get(void)
712 {
713   return g_SWI_HLE;
714 }
715 
716 static int32_t addrr = 0;
717 static int32_t vall  = 0;
718 static int32_t inuse = 0;
719 
720 static
721 void
ldm_accur(uint32_t opc_,uint32_t base_,uint32_t rn_ind_)722 ldm_accur(uint32_t opc_,
723           uint32_t base_,
724           uint32_t rn_ind_)
725 {
726   uint16_t x;
727   uint16_t list;
728   uint32_t i;
729   uint32_t tmp;
730   uint32_t base_comp;
731 
732   i = 0;
733   x    = opc_ & 0xFFFF;
734   list = opc_ & 0xFFFF;
735   x = ((x & 0x5555) + ((x >> 1) & 0x5555));
736   x = ((x & 0x3333) + ((x >> 2) & 0x3333));
737   x = ((x & 0x00ff) + (x >> 8));
738   x = ((x & 0x000f) + (x >> 4));
739 
740   switch((opc_>>23)&3)
741     {
742     case 0:
743       base_     -= (x << 2);
744       base_comp  = (base_ + 4);
745       break;
746     case 1:
747       base_comp  = base_;
748       base_     += (x << 2);
749       break;
750     case 2:
751       base_comp = base_ = (base_ - (x << 2));
752       break;
753     case 3:
754       base_comp  = (base_ + 4);
755       base_     += (x<<2);
756       break;
757     }
758 
759   //base_comp&=~3;
760 
761   //if(opc_&(1<<21))CPU.USER[rn_ind_]=base_;
762 
763   if((opc_ & (1 << 22)) && !(opc_ & 0x8000))
764     {
765       if(opc_ & (1 << 21))
766         loadusr(rn_ind_,base_);
767 
768       while(list)
769         {
770           if(list & 1)
771             {
772               tmp = mreadw(base_comp);
773               /*
774                 if(MAS_Access_Exept)
775                 {
776                 if(opc_&(1<<21))
777                 CPU.USER[rn_ind_]=base_;
778                 break;
779                 }
780               */
781               loadusr(i,tmp);
782               base_comp += 4;
783             }
784 
785           i++;
786           list >>= 1;
787         }
788     }
789   else
790     {
791       if(opc_ & (1 << 21))
792         CPU.USER[rn_ind_] = base_;
793 
794       while(list)
795         {
796           if(list & 1)
797             {
798               tmp = mreadw(base_comp);
799               if((tmp == 0xF1000)         &&
800                  (i == 0x1)               &&
801                  (CPU.USER[2] != 0xF0000) &&
802                  (CNBFIX == 0)            &&
803                  (FIXMODE & FIX_BIT_TIMING_1))
804                 {
805                   tmp+=0x1000;
806                 }
807 
808               if((inuse == 1) && (base_comp & 0x1FFFFF))
809                 {
810                   if(base_comp == addrr)
811                     inuse = 0;
812 
813                   if(tmp != vall)
814                     {
815                       if((tmp == 0xEFE54) &&
816                          (i == 0x4)       &&
817                          (CNBFIX == 0)    &&
818                          (FIXMODE & FIX_BIT_TIMING_1))
819                         tmp -= 0xF;
820                     }
821                 }
822 
823               CPU.USER[i]  = tmp;
824               base_comp   += 4;
825             }
826 
827           i++;
828           list >>= 1;
829         }
830 
831       if((opc_ & (1 << 22)) && arm_mode_table[MODE] /*&& !MAS_Access_Exept*/)
832         arm_cpsr_set(CPU.SPSR[arm_mode_table[MODE]]);
833     }
834 
835   CYCLES -= ((x-1) * SCYCLE + NCYCLE + ICYCLE);
836 }
837 
838 static
839 void
stm_accur(uint32_t opc_,uint32_t base_,uint32_t rn_ind_)840 stm_accur(uint32_t opc_,
841           uint32_t base_,
842           uint32_t rn_ind_)
843 {
844   uint16_t x;
845   uint16_t list;
846   uint32_t i;
847   uint32_t base_comp;
848 
849   i = 0;
850   x    = opc_ & 0xFFFF;
851   list = opc_ & 0x7FFF;
852   x = ((x & 0x5555) + ((x >> 1) & 0x5555));
853   x = ((x & 0x3333) + ((x >> 2) & 0x3333));
854   x = ((x & 0x00ff) + (x >> 8));
855   x = ((x & 0x000f) + (x >> 4));
856 
857   switch((opc_ >> 23) & 3)
858     {
859     case 0:
860       base_     -= (x << 2);
861       base_comp  = (base_ + 4);
862       break;
863     case 1:
864       base_comp  = base_;
865       base_     += (x << 2);
866       break;
867     case 2:
868       base_comp = base_ = (base_ - (x << 2));
869       break;
870     case 3:
871       base_comp  = (base_ + 4);
872       base_     += (x << 2);
873       break;
874     }
875 
876   if((opc_ & (1 << 22)))
877     {
878       if((opc_ & (1 << 21)) && (opc_ & ((1 << rn_ind_) - 1)))
879         loadusr(rn_ind_,base_);
880 
881       while(list)
882         {
883           if(list & 1)
884             {
885               mwritew(base_comp,readusr(i));
886               //if(MAS_Access_Exept)break;
887               base_comp += 4;
888             }
889 
890           i++;
891           list >>= 1;
892         }
893 
894       if(opc_ & (1 << 21))
895         loadusr(rn_ind_,base_);
896     }
897   else
898     {
899       if((opc_ & (1 << 21)) && (opc_ & ((1 << rn_ind_) - 1)))
900         CPU.USER[rn_ind_] = base_;
901 
902       while(list)
903         {
904           if(list&1)
905             {
906               mwritew(base_comp,CPU.USER[i]);
907               if(base_comp & 0x1FFFFF)
908                 {
909                   addrr = base_comp;
910                   vall  = CPU.USER[i];
911                   inuse = 1;
912                 }
913               base_comp += 4;
914             }
915 
916           i++;
917           list >>= 1;
918         }
919 
920       if(opc_ & (1 << 21))
921         CPU.USER[rn_ind_] = base_;
922     }
923 
924   if((opc_ & 0x8000) /*&& !MAS_Access_Exept*/)
925     mwritew(base_comp,CPU.USER[15]+8);
926 
927   CYCLES -= ((x - 2) * SCYCLE + NCYCLE + NCYCLE);
928 }
929 
930 static
931 void
bdt_core(uint32_t opc_)932 bdt_core(uint32_t opc_)
933 {
934   uint32_t base;
935   uint32_t rn_ind = ((opc_ >> 16) & 0xF);
936 
937   if(rn_ind == 0xF)
938     base = CPU.USER[rn_ind] + 8;
939   else
940     base = CPU.USER[rn_ind];
941 
942   if(opc_ & (1 << 20)) /* memory or register? */
943     {
944       if(opc_ & 0x8000)
945         CYCLES -= (SCYCLE + NCYCLE);
946       ldm_accur(opc_,base,rn_ind);
947     }
948   else
949     {
950       stm_accur(opc_,base,rn_ind);
951     }
952 }
953 
954 typedef struct TagArg
955 {
956   uint32_t Type;
957   uint32_t Arg;
958 } TagItem;
959 
960 
961 static
962 void
decode_swi_lle(void)963 decode_swi_lle(void)
964 {
965   CPU.SPSR[arm_mode_table[0x13]] = CPU.CPSR;
966 
967   SETI(1);
968   SETM(0x13);
969 
970   CPU.USER[14] = CPU.USER[15];
971   CPU.USER[15] = 0x00000008;
972 }
973 
decode_swi_hle(const uint32_t op_)974 static void decode_swi_hle(const uint32_t op_)
975 {
976   switch(op_ & 0x000FFFFF)
977     {
978     case 0x50000:
979       opera_swi_hle_0x50000(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2]);
980       return;
981     case 0x50001:
982       opera_swi_hle_0x50001(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2]);
983       return;
984     case 0x50002:
985       opera_swi_hle_0x50002(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2],CPU.USER[3]);
986       return;
987     case 0x50003:
988       break;
989     case 0x50004:
990       break;
991     case 0x50005:
992       opera_swi_hle_0x50005(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2],CPU.USER[3]);
993       return;
994     case 0x50006:
995       opera_swi_hle_0x50006(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2],CPU.USER[3]);
996       return;
997     case 0x50007:
998       opera_swi_hle_0x50007(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2]);
999       return;
1000     case 0x50008:
1001       opera_swi_hle_0x50008(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2]);
1002       return;
1003     case 0x50009:
1004       opera_swi_hle_0x50009(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2],CPU.USER[3]);
1005       return;
1006     case 0x5000A:
1007       break;
1008     case 0x5000B:
1009       break;
1010     case 0x5000C:
1011       CPU.USER[0] = opera_swi_hle_0x5000C(CPU.ram,CPU.USER[0],CPU.USER[1]);
1012       return;
1013     case 0x5000E:
1014       opera_swi_hle_0x5000E(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2]);
1015       return;
1016     case 0x5000F:
1017       CPU.USER[0] = opera_swi_hle_0x5000F(CPU.ram,CPU.USER[0]);
1018       return;
1019     case 0x50010:
1020       CPU.USER[0] = opera_swi_hle_0x50010(CPU.ram,CPU.USER[0]);
1021       return;
1022     case 0x50011:
1023       opera_swi_hle_0x50011(CPU.ram,CPU.USER[0],CPU.USER[1],CPU.USER[2],CPU.USER[3]);
1024       return;
1025     case 0x50012:
1026       opera_swi_hle_0x50012(CPU.ram,CPU.USER[0]);
1027       return;
1028     }
1029 
1030   decode_swi_lle();
1031 }
1032 
decode_swi(const uint32_t op_)1033 static void decode_swi(const uint32_t op_)
1034 {
1035   CYCLES -= (SCYCLE + NCYCLE);  // +2S+1N
1036 
1037   if(g_SWI_HLE)
1038   {
1039     decode_swi_hle(op_);
1040     return;
1041   }
1042 
1043   decode_swi_lle();
1044 }
1045 
1046 
1047 static uint32_t carry_out = 0;
1048 
1049 static
1050 INLINE
1051 void
ARM_SET_C(const uint32_t x_)1052 ARM_SET_C(const uint32_t x_)
1053 {
1054   CPU.CPSR = ((CPU.CPSR & 0xdfffffff) | ((x_ & 1) << 29));
1055 }
1056 
1057 static
1058 INLINE
1059 void
ARM_SET_Z(const uint32_t x_)1060 ARM_SET_Z(const uint32_t x_)
1061 {
1062   CPU.CPSR = ((CPU.CPSR & 0xbfffffff) | (x_ == 0 ? 0x40000000 : 0));
1063 }
1064 
1065 static
1066 INLINE
1067 void
ARM_SET_N(const uint32_t x_)1068 ARM_SET_N(const uint32_t x_)
1069 {
1070   CPU.CPSR = ((CPU.CPSR & 0x7fffffff) | (x_ & 0x80000000));
1071 }
1072 
1073 static
1074 INLINE
1075 uint32_t
ARM_GET_C(void)1076 ARM_GET_C(void)
1077 {
1078   return ((CPU.CPSR >> 29) & 1);
1079 }
1080 
1081 static
1082 INLINE
1083 void
ARM_SET_ZN(const uint32_t val_)1084 ARM_SET_ZN(const uint32_t val_)
1085 {
1086   if(val_)
1087     CPU.CPSR = ((CPU.CPSR & 0x3fffffff) | (val_ & 0x80000000));
1088   else
1089     CPU.CPSR = ((CPU.CPSR & 0x3fffffff) | 0x40000000);
1090 }
1091 
1092 static
1093 INLINE
1094 void
ARM_SET_CV(const uint32_t rd_,const uint32_t op1_,const uint32_t op2_)1095 ARM_SET_CV(const uint32_t rd_,
1096            const uint32_t op1_,
1097            const uint32_t op2_)
1098 {
1099   CPU.CPSR = ((CPU.CPSR & 0xcfffffff) |
1100               ((((op1_ & op2_) | ((~rd_) & (op1_ | op2_))) & 0x80000000) >> 2) |
1101               (((((op1_ & (op2_ & (~rd_))) | ((~op1_) & (~op2_) & rd_))) & 0x80000000) >> 3));
1102 }
1103 
1104 static
1105 INLINE
1106 void
ARM_SET_CV_sub(uint32_t rd_,uint32_t op1_,uint32_t op2_)1107 ARM_SET_CV_sub(uint32_t rd_,
1108                uint32_t op1_,
1109                uint32_t op2_)
1110 {
1111   CPU.CPSR = ((CPU.CPSR & 0xcfffffff) |
1112               ((((op1_ & (~op2_)) | ((~rd_) & (op1_ | (~op2_)))) & 0x80000000) >> 2) |
1113               (((((op1_ & ((~op2_) & (~rd_))) | ((~op1_) & op2_ & rd_))) & 0x80000000) >> 3));
1114 }
1115 
1116 static
1117 INLINE
1118 int
ARM_ALU_Exec(uint32_t inst_,uint8_t opc_,uint32_t op1_,uint32_t op2_,uint32_t * rd_)1119 ARM_ALU_Exec(uint32_t  inst_,
1120              uint8_t   opc_,
1121              uint32_t  op1_,
1122              uint32_t  op2_,
1123              uint32_t *rd_)
1124 {
1125   switch(opc_)
1126     {
1127     case 0:
1128       *rd_ = op1_ & op2_;
1129       break;
1130     case 2:
1131       *rd_ = op1_ ^ op2_;
1132       break;
1133     case 4:
1134       *rd_ = op1_ - op2_;
1135       break;
1136     case 6:
1137       *rd_ = op2_ - op1_;
1138       break;
1139     case 8:
1140       *rd_ = op1_ + op2_;
1141       break;
1142     case 10:
1143       *rd_ = op1_ + op2_ + ARM_GET_C();
1144       break;
1145     case 12:
1146       *rd_ = op1_ - op2_ - (ARM_GET_C() ^ 1);
1147       break;
1148     case 14:
1149       *rd_ = op2_ - op1_ - (ARM_GET_C() ^ 1);
1150       break;
1151     case 16:
1152     case 20:
1153       if((inst_ >> 22) & 1)
1154         CPU.USER[(inst_ >> 12) & 0xF] = CPU.SPSR[arm_mode_table[CPU.CPSR & 0x1F]];
1155       else
1156         CPU.USER[(inst_ >> 12) & 0xF] = CPU.CPSR;
1157       return TRUE;
1158     case 18:
1159     case 22:
1160       if(!((inst_ >> 16) & 0x1) || !(arm_mode_table[MODE]))
1161         {
1162           if((inst_ >> 22) & 1)
1163             CPU.SPSR[arm_mode_table[MODE]] = (CPU.SPSR[arm_mode_table[MODE]] & 0x0fffffff) | (op2_ & 0xf0000000);
1164           else
1165             CPU.CPSR = (CPU.CPSR & 0x0fffffff) | (op2_ & 0xf0000000);
1166         }
1167       else
1168         {
1169           if((inst_ >> 22) & 1)
1170             CPU.SPSR[arm_mode_table[MODE]] = op2_ & 0xf00000df;
1171           else
1172             arm_cpsr_set(op2_);
1173         }
1174       return TRUE;
1175     case 24:
1176       *rd_ = op1_ | op2_;
1177       break;
1178     case 26:
1179       *rd_ = op2_;
1180       break;
1181     case 28:
1182       *rd_ = op1_ & ~op2_;
1183       break;
1184     case 30:
1185       *rd_ = ~op2_;
1186       break;
1187     case 1:
1188       *rd_ = op1_ & op2_;
1189       ARM_SET_ZN(*rd_);
1190       break;
1191     case 3:
1192       *rd_ = op1_ ^ op2_;
1193       ARM_SET_ZN(*rd_);
1194       break;
1195     case 5:
1196       *rd_ = op1_ - op2_;
1197       ARM_SET_ZN(*rd_);
1198       ARM_SET_CV_sub(*rd_,op1_,op2_);
1199       break;
1200     case 7:
1201       *rd_ = op2_ - op1_;
1202       ARM_SET_ZN(*rd_);
1203       ARM_SET_CV_sub(*rd_,op2_,op1_);
1204       break;
1205     case 9:
1206       *rd_ = op1_ + op2_;
1207       ARM_SET_ZN(*rd_);
1208       ARM_SET_CV(*rd_,op1_,op2_);
1209       break;
1210 
1211     case 11:
1212       *rd_ = op1_ + op2_ + ARM_GET_C();
1213       ARM_SET_ZN(*rd_);
1214       ARM_SET_CV(*rd_,op1_,op2_);
1215       break;
1216     case 13:
1217       *rd_ = op1_ - op2_ - (ARM_GET_C()^1);
1218       ARM_SET_ZN(*rd_);
1219       ARM_SET_CV_sub(*rd_,op1_,op2_);
1220       break;
1221     case 15:
1222       *rd_ = op2_ - op1_ - (ARM_GET_C()^1);
1223       ARM_SET_ZN(*rd_);
1224       ARM_SET_CV_sub(*rd_,op2_,op1_);
1225       break;//*/
1226     case 17:
1227       op1_ &= op2_;
1228       ARM_SET_ZN(op1_);
1229       return TRUE;
1230     case 19:
1231       op1_ ^= op2_;
1232       ARM_SET_ZN(op1_);
1233       return TRUE;
1234     case 21:
1235       ARM_SET_CV_sub(op1_ - op2_,op1_,op2_);
1236       ARM_SET_ZN(op1_ - op2_);
1237       return TRUE;
1238     case 23:
1239       ARM_SET_CV(op1_ + op2_,op1_,op2_);
1240       ARM_SET_ZN(op1_ + op2_);
1241       return TRUE;
1242     case 25:
1243       *rd_ = op1_ | op2_;
1244       ARM_SET_ZN(*rd_);
1245       break;
1246     case 27:
1247       *rd_ = op2_;
1248       ARM_SET_ZN(*rd_);
1249       break;
1250     case 29:
1251       *rd_ = op1_ & ~op2_;
1252       ARM_SET_ZN(*rd_);
1253       break;
1254     case 31:
1255       *rd_ = ~op2_;
1256       ARM_SET_ZN(*rd_);
1257       break;
1258     };
1259   return FALSE;
1260 }
1261 
1262 static
1263 uint32_t
ARM_SHIFT_NSC(uint32_t value_,uint8_t shift_,uint8_t type_)1264 ARM_SHIFT_NSC(uint32_t value_,
1265               uint8_t  shift_,
1266               uint8_t  type_)
1267 {
1268   switch(type_)
1269     {
1270     case 0:
1271       if(shift_)
1272         {
1273           if(shift_ > 32)
1274             carry_out = 0;
1275           else
1276             carry_out = (((value_ << (shift_ - 1)) & 0x80000000) >> 31);
1277         }
1278       else
1279         {
1280           carry_out = ARM_GET_C();
1281         }
1282 
1283       if(shift_ == 0)
1284         return value_;
1285       if(shift_ > 31)
1286         return 0;
1287       return (value_ << shift_);
1288     case 1:
1289       if(shift_)
1290         {
1291           if(shift_ > 32)
1292             carry_out = 0;
1293           else
1294             carry_out = ((value_ >> (shift_ - 1)) & 1);
1295         }
1296       else
1297         {
1298           carry_out = ARM_GET_C();
1299         }
1300 
1301       if(shift_ == 0)
1302         return value_;
1303       if(shift_ > 31)
1304         return 0;
1305       return (value_ >> shift_);
1306     case 2:
1307       if(shift_)
1308         {
1309           if(shift_ > 32)
1310             carry_out = ((((int32_t)value_) >> 31) & 1);
1311           else
1312             carry_out = ((((int32_t)value_) >> (shift_ - 1)) & 1);
1313         }
1314       else
1315         {
1316           carry_out = ARM_GET_C();
1317         }
1318 
1319       if(shift_ == 0)
1320         return value_;
1321       if(shift_ > 31)
1322         return (((int32_t)value_) >> 31);
1323       return (((int32_t)value_) >> shift_);
1324     case 3:
1325       if(shift_)
1326         {
1327           if(shift_&31)
1328             carry_out = ((value_ >> (shift_ - 1)) & 1);
1329           else
1330             carry_out = ((value_ >> 31) & 1);
1331         }
1332       else
1333         {
1334           carry_out = ARM_GET_C();
1335         }
1336 
1337       shift_ &= 31;
1338       if(shift_ == 0)
1339         return value_;
1340       return ROTR(value_,shift_);
1341     case 4:
1342       carry_out = value_ & 1;
1343       return ((value_ >> 1) | (ARM_GET_C() << 31));
1344     }
1345 
1346   return 0;
1347 }
1348 
1349 static
1350 uint32_t
ARM_SHIFT_SC(uint32_t value_,uint8_t shift_,uint8_t type_)1351 ARM_SHIFT_SC(uint32_t value_,
1352              uint8_t  shift_,
1353              uint8_t  type_)
1354 {
1355   uint32_t tmp;
1356 
1357   switch(type_)
1358     {
1359     case 0:
1360       if(shift_)
1361         {
1362           if(shift_ > 32)
1363             ARM_SET_C(0);
1364           else
1365             ARM_SET_C(((value_ << (shift_ - 1)) & 0x80000000) >> 31);
1366         }
1367       else
1368         {
1369           return value_;
1370         }
1371 
1372       if(shift_ > 31)
1373         return 0;
1374       return (value_ << shift_);
1375     case 1:
1376       if(shift_)
1377         {
1378           if(shift_ > 32)
1379             ARM_SET_C(0);
1380           else
1381             ARM_SET_C((value_ >> (shift_ - 1)) & 1);
1382         }
1383       else
1384         {
1385           return value_;
1386         }
1387 
1388       if(shift_ > 31)
1389         return 0;
1390       return (value_ >> shift_);
1391     case 2:
1392       if(shift_)
1393         {
1394           if(shift_ > 32)
1395             ARM_SET_C((((int32_t)value_) >> 31) & 1);
1396           else
1397             ARM_SET_C((((int32_t)value_) >> (shift_ - 1)) & 1);
1398         }
1399       else
1400         {
1401           return value_;
1402         }
1403 
1404       if(shift_ > 31)
1405         return (((int32_t)value_) >> 31);
1406       return ((int32_t)value_) >> shift_;
1407     case 3:
1408       if(shift_)
1409         {
1410           shift_ = (shift_ & 31);
1411           if(shift_)
1412             ARM_SET_C((value_ >> (shift_ - 1)) & 1);
1413           else
1414             ARM_SET_C((value_ >> 31) & 1);
1415         }
1416       else
1417         {
1418           return value_;
1419         }
1420 
1421       return ROTR(value_,shift_);
1422     case 4:
1423       tmp = ARM_GET_C() << 31;
1424       ARM_SET_C(value_ & 1);
1425       return ((value_ >> 1) | (tmp));
1426     }
1427 
1428   return 0;
1429 }
1430 
1431 static
1432 void
ARM_SWAP(uint32_t cmd_)1433 ARM_SWAP(uint32_t cmd_)
1434 {
1435   uint32_t tmp;
1436   uint32_t addr;
1437 
1438   CPU.USER[15] += 4;
1439   addr          = CPU.USER[(cmd_ >> 16) & 0xF];
1440   CPU.USER[15] += 4;
1441 
1442   if(cmd_ & (1 << 22))
1443     {
1444       tmp = mreadb(addr);
1445       //	if(MAS_Access_Exept)return TRUE;
1446       mwriteb(addr,CPU.USER[cmd_ & 0xF]);
1447       CPU.USER[15] -= 8;
1448       //	if(MAS_Access_Exept)return TRUE;
1449       CPU.USER[(cmd_ >> 12) & 0xF] = tmp;
1450     }
1451   else
1452     {
1453       tmp = mreadw(addr);
1454       //if(MAS_Access_Exept)return TRUE;
1455       mwritew(addr,CPU.USER[cmd_ & 0xF]);
1456       CPU.USER[15] -= 8;
1457       //if(MAS_Access_Exept)return TRUE;
1458       if(addr & 3)
1459         tmp = ((tmp >> ((addr & 3) << 3)) | (tmp << (32 - ((addr & 3) << 3))));
1460       CPU.USER[(cmd_ >> 12) & 0xF] = tmp;
1461     }
1462 }
1463 
1464 static
1465 INLINE
1466 uint32_t
calcbits(uint32_t num_)1467 calcbits(uint32_t num_)
1468 {
1469   uint32_t rv;
1470 
1471   if(!num_)
1472     return 1;
1473 
1474   if(num_ >> 16)
1475     {
1476       num_ >>= 16;
1477       rv     = 16;
1478     }
1479   else
1480     {
1481       rv = 0;
1482     }
1483 
1484   if(num_ >> 8)
1485     {
1486       num_ >>= 8;
1487       rv    += 8;
1488     }
1489 
1490   if(num_ >> 4)
1491     {
1492       num_ >>= 4;
1493       rv    += 4;
1494     }
1495 
1496   if(num_ >> 2)
1497     {
1498       num_ >>= 2;
1499       rv    += 2;
1500     }
1501 
1502   if(num_ >> 1)
1503     {
1504       num_ >>= 1;
1505       rv    += 2;
1506     }
1507   else if(num_)
1508     {
1509       rv++;
1510     }
1511 
1512   return rv;
1513 }
1514 
1515 static const int is_logic[] =
1516   {
1517     TRUE,TRUE,FALSE,FALSE,
1518     FALSE,FALSE,FALSE,FALSE,
1519     TRUE,TRUE,FALSE,FALSE,
1520     TRUE,TRUE,TRUE,TRUE
1521   };
1522 
1523 int32_t
opera_arm_execute(void)1524 opera_arm_execute(void)
1525 {
1526   uint32_t op1;
1527   uint32_t op2;
1528   uint8_t shift;
1529   uint8_t shtype;
1530   uint32_t cmd;
1531   uint32_t pc_tmp;
1532   int isexeption;
1533 
1534   isexeption = FALSE;
1535   if((CPU.USER[15] == 0x94D60) &&
1536      (CPU.USER[0] == 0x113000) &&
1537      (CPU.USER[1] == 0x113000) &&
1538      (CNBFIX == 0)             &&
1539      (FIXMODE & FIX_BIT_TIMING_1))
1540     {
1541       CPU.USER[15] = 0x9E9CC;
1542       CNBFIX = 1;
1543     }
1544 
1545   cmd = mreadw(CPU.USER[15]);
1546   CPU.USER[15] += 4;
1547 
1548   CYCLES = -SCYCLE;
1549   if((cmd == 0xE5101810) && (CPU.CPSR == 0x80000093))
1550     isexeption = TRUE;
1551 
1552   if(((cond_flags_cross[cmd >> 28] >> (CPU.CPSR >> 28)) & 1) &&
1553      (isexeption == FALSE))
1554     {
1555       switch((cmd >> 24) & 0xF)
1556         {
1557         case 0x0:               //Multiply
1558           if((cmd & ARM_MUL_MASK) == ARM_MUL_SIGN)
1559             {
1560               uint32_t res = ((calcbits(CPU.USER[(cmd>>8)&0xf])+5)>>1)-1;
1561               if(res > 16)
1562                 CYCLES -= 16;
1563               else
1564                 CYCLES -= res;
1565 
1566               if(((cmd >> 16) & 0xF) == (cmd & 0xF))
1567                 {
1568                   if(cmd & (1 << 21))
1569                     {
1570                       CPU.USER[15] += 8;
1571                       res=CPU.USER[(cmd >> 12) & 0xF];
1572                       CPU.USER[15] -= 8;
1573                     }
1574                   else
1575                     {
1576                       res = 0;
1577                     }
1578                 }
1579               else
1580                 {
1581                   if(cmd & (1 << 21))
1582                     {
1583                       res = CPU.USER[cmd & 0xF] * CPU.USER[(cmd >> 8) & 0xF];
1584                       CPU.USER[15] += 8;
1585                       res += CPU.USER[(cmd >> 12) & 0xF];
1586                       CPU.USER[15] -= 8;
1587                     }
1588                   else
1589                     {
1590                       res = CPU.USER[cmd & 0xF] * CPU.USER[(cmd >> 8) & 0xF];
1591                     }
1592                 }
1593 
1594               if(cmd & (1 << 20))
1595                 ARM_SET_ZN(res);
1596 
1597               CPU.USER[(cmd >> 16) & 0xF] = res;
1598               break;
1599             }
1600         case 0x1:               //Single Data Swap
1601           if((cmd & ARM_SDS_MASK) == ARM_SDS_SIGN)
1602             {
1603               ARM_SWAP(cmd);
1604               //if(MAS_Access_Exept)
1605               CYCLES -= (2 * NCYCLE + ICYCLE);
1606               break;
1607             }
1608         case 0x2:               //ALU
1609         case 0x3:
1610           {
1611             if((cmd & 0x2000090) != 0x90)
1612               {
1613                 /* SHIFT */
1614                 pc_tmp = CPU.USER[15];
1615                 CPU.USER[15] += 4;
1616                 if(cmd & (1 << 25))
1617                   {
1618                     op2 = cmd & 0xFF;
1619                     if(((cmd >> 7) & 0x1E))
1620                       {
1621                         op2 = ROTR(op2,((cmd >> 7) & 0x1E));
1622                         //if((cmd&(1<<20))) SETC(((cmd&0xff)>>(((cmd>>7)&0x1e)-1))&1);
1623                       }
1624                     op1 = CPU.USER[(cmd >> 16) & 0xF];
1625                   }
1626                 else
1627                   {
1628                     shtype = ((cmd >> 5) & 0x3);
1629                     if(cmd & (1 << 4))
1630                       {
1631                         shift = ((cmd >> 8) & 0xF);
1632                         shift = (CPU.USER[shift] & 0xFF);
1633                         CPU.USER[15] += 4;
1634                         op2 = CPU.USER[cmd & 0xF];
1635                         op1 = CPU.USER[(cmd >> 16) & 0xF];
1636                         CYCLES -= ICYCLE;
1637                       }
1638                     else
1639                       {
1640                         shift = ((cmd >> 7) & 0x1F);
1641 
1642                         if(!shift)
1643                           {
1644                             if(shtype)
1645                               {
1646                                 if(shtype == 3)
1647                                   shtype++;
1648                                 else
1649                                   shift=32;
1650                               }
1651                           }
1652 
1653                         op2 = CPU.USER[cmd & 0xF];
1654                         op1 = CPU.USER[(cmd >> 16) & 0xF];
1655                       }
1656 
1657                     //if((cmd&(1<<20)) && is_logic[((cmd>>21)&0xf)] ) op2=ARM_SHIFT_SC(op2, shift, shtype);
1658                     //else
1659                     op2 = ARM_SHIFT_NSC(op2,shift,shtype);
1660                   }
1661 
1662                 CPU.USER[15] = pc_tmp;
1663 
1664                 if((cmd & (1 << 20)) && is_logic[((cmd >> 21) & 0xF)])
1665                   ARM_SET_C(carry_out);
1666 
1667                 if(ARM_ALU_Exec(cmd,((cmd >> 20) & 0x1F),op1,op2,&CPU.USER[(cmd >> 12) & 0xF]))
1668                   break;
1669 
1670                 if(((cmd >> 12) & 0xF) == 0xF) //destination = pc, take care of cpsr
1671                   {
1672                     if(cmd & (1 << 20))
1673                       arm_cpsr_set(CPU.SPSR[arm_mode_table[MODE]]);
1674 
1675                     CYCLES -= (ICYCLE + NCYCLE);
1676                   }
1677                 break;
1678               }
1679           }
1680         case 0x6:               //Undefined
1681         case 0x7:
1682         Undefine:
1683           if((cmd & ARM_UND_MASK) == ARM_UND_SIGN)
1684             {
1685               CPU.SPSR[arm_mode_table[0x1b]] = CPU.CPSR;
1686               SETI(1);
1687               SETM(0x1b);
1688               CPU.USER[14] = CPU.USER[15];
1689               CPU.USER[15] = 0x00000004;
1690               CYCLES -= (SCYCLE + NCYCLE); // +2S+1N
1691               break;
1692             }
1693         case 0x4:               //Single Data Transfer
1694         case 0x5:
1695           if((cmd & 0x2000090) != 0x2000090)
1696             {
1697               uint32_t base;
1698               uint32_t tbas;
1699               uint32_t oper2;
1700               uint32_t val;
1701               uint32_t rora;
1702 
1703               pc_tmp = CPU.USER[15];
1704               CPU.USER[15] += 4;
1705               if(cmd & (1 << 25))
1706                 {
1707                   shtype = ((cmd >> 5) & 0x3);
1708                   if(cmd & (1 << 4))
1709                     {
1710                       shift = ((cmd >> 8) & 0xF);
1711                       shift = (CPU.USER[shift] & 0xFF);
1712                       CPU.USER[15] += 4;
1713                     }
1714                   else
1715                     {
1716                       shift = ((cmd >> 7) & 0x1F);
1717                       if(!shift)
1718                         {
1719                           if(shtype)
1720                             {
1721                               if(shtype == 3)
1722                                 shtype++;
1723                               else
1724                                 shift = 32;
1725                             }
1726                         }
1727                     }
1728 
1729                   oper2 = ARM_SHIFT_NSC(CPU.USER[cmd & 0xF],shift,shtype);
1730                 }
1731               else
1732                 {
1733                   oper2 = (cmd & 0x0FFF);
1734                 }
1735 
1736               tbas = base = CPU.USER[((cmd >> 16) & 0xF)];
1737 
1738               if(!(cmd & (1 << 23)))
1739                 oper2 = (0 - oper2);
1740 
1741               if(cmd & (1 << 24))
1742                 tbas = base = (base + oper2);
1743               else
1744                 base = (base + oper2);
1745 
1746               if(cmd & (1 << 20)) //load
1747                 {
1748                   if(cmd & (1 << 22)) //bytes
1749                     {
1750                       val = mreadb(tbas);
1751                     }
1752                   else //words/halfwords
1753                     {
1754                       uint32_t rora;
1755 
1756                       rora = tbas & 3;
1757                       val = mreadw(tbas);
1758 
1759                       if(rora)
1760                         val = ROTR(val,rora*8);
1761                     }
1762 
1763                   if(((cmd >> 12) & 0xF) == 0xF)
1764                     CYCLES -= (SCYCLE + NCYCLE);   // +1S+1N ifR15 load
1765 
1766                   CYCLES -= (NCYCLE + ICYCLE);  // +1N+1I
1767                   CPU.USER[15] = pc_tmp;
1768 
1769                   if((cmd & (1 << 21)) || (!(cmd & (1 << 24))))
1770                     CPU.USER[(cmd >> 16) & 0xF] = base;
1771 
1772                   if((cmd & (1 << 21)) && !(cmd & (1 << 24)))
1773                     loadusr((cmd >> 12) & 0xF,val);
1774                   else
1775                     CPU.USER[(cmd >> 12) & 0xF] = val;
1776                 }
1777               else // store
1778                 {
1779                   if((cmd & (1 << 21)) && !(cmd & (1 << 24)))
1780                     val = readusr((cmd >> 12) & 0xF);
1781                   else
1782                     val = CPU.USER[(cmd >> 12) & 0xF];
1783 
1784                   CPU.USER[15] = pc_tmp;
1785                   CYCLES -= (-SCYCLE + 2 * NCYCLE);  // 2N
1786 
1787                   if(cmd & (1 << 22)) //bytes/words
1788                     mwriteb(tbas,val);
1789                   else //words/halfwords
1790                     mwritew(tbas,val);
1791 
1792                   if((cmd & (1 << 21)) || !(cmd & (1 << 24)))
1793                     CPU.USER[(cmd >> 16) & 0xF] = base;
1794                 }
1795 
1796               //if(MAS_Access_Exept)
1797               break;
1798             }
1799           else
1800             {
1801               goto Undefine;
1802             }
1803 
1804         case 0x8:               //Block Data Transfer
1805         case 0x9:
1806           bdt_core(cmd);
1807           /*if(MAS_Access_Exept)
1808             {
1809             //sprintf(str,"*PC: 0x%8.8X DataAbort!!!\n",CPU.USER[15]);
1810             //CDebug::DPrint(str);
1811             //!!Exeption!!
1812 
1813             CPU.SPSR[arm_mode_table[0x17]]=CPU.CPSR;
1814             SETI(1);
1815             SETM(0x17);
1816             CPU.USER[14] = (CPU.USER[15] + 4);
1817             CPU.USER[15] = 0x00000010;
1818             CYCLES-=SCYCLE+NCYCLE;
1819             MAS_Access_Exept=FALSE;
1820             break;
1821             } */
1822           break;
1823 
1824         case 0xa:               //BRANCH
1825         case 0xb:
1826           if(cmd & (1 << 24))
1827             CPU.USER[14] = CPU.USER[15];
1828           CPU.USER[15] += ((((cmd & 0x00FFFFFF) | ((cmd & 0x00800000) ? 0xFF000000 : 0)) << 2) + 4);
1829 
1830           CYCLES -= (SCYCLE + NCYCLE); //2S+1N
1831           break;
1832 
1833         case 0xf:               //SWI
1834           decode_swi(cmd);
1835           break;
1836 
1837         default:                //coprocessor
1838           CPU.SPSR[arm_mode_table[0x1b]] = CPU.CPSR;
1839           SETI(1);
1840           SETM(0x1b);
1841           CPU.USER[14] = CPU.USER[15];
1842           CPU.USER[15] = 0x00000004;
1843           CYCLES -= (SCYCLE + NCYCLE);
1844           break;
1845         }
1846     }
1847 
1848   if(!ISF && opera_clio_fiq_needed()/*CPU.nFIQ*/)
1849     {
1850       //Set_madam_FSM(FSM_SUSPENDED);
1851       CPU.nFIQ = FALSE;
1852       CPU.SPSR[arm_mode_table[0x11]] = CPU.CPSR;
1853       SETF(1);
1854       SETI(1);
1855       SETM(0x11);
1856       CPU.USER[14] = (CPU.USER[15] + 4);
1857       CPU.USER[15] = 0x0000001C;
1858     }
1859 
1860   return -CYCLES;
1861 }
1862 
1863 void
opera_mem_write8(uint32_t addr_,uint8_t val_)1864 opera_mem_write8(uint32_t addr_,
1865                  uint8_t  val_)
1866 {
1867   CPU.ram[addr_] = val_;
1868   if(!HIRESMODE || (addr_ < 0x200000))
1869     return;
1870   CPU.ram[addr_ + 1*1024*1024] = val_;
1871   CPU.ram[addr_ + 2*1024*1024] = val_;
1872   CPU.ram[addr_ + 3*1024*1024] = val_;
1873 }
1874 
1875 void
opera_mem_write16(uint32_t addr_,uint16_t val_)1876 opera_mem_write16(uint32_t addr_,
1877                   uint16_t val_)
1878 {
1879   *((uint16_t*)&CPU.ram[addr_]) = val_;
1880   if(!HIRESMODE || (addr_ < 0x200000))
1881     return;
1882   *((uint16_t*)&CPU.ram[addr_ + 1*1024*1024]) = val_;
1883   *((uint16_t*)&CPU.ram[addr_ + 2*1024*1024]) = val_;
1884   *((uint16_t*)&CPU.ram[addr_ + 3*1024*1024]) = val_;
1885 }
1886 
1887 void
opera_mem_write32(uint32_t addr_,uint32_t val_)1888 opera_mem_write32(uint32_t addr_,
1889                   uint32_t val_)
1890 {
1891   *((uint32_t*)&CPU.ram[addr_]) = val_;
1892   if(!HIRESMODE || (addr_ < 0x200000))
1893     return;
1894   *((uint32_t*)&CPU.ram[addr_ + 1*1024*1024]) = val_;
1895   *((uint32_t*)&CPU.ram[addr_ + 2*1024*1024]) = val_;
1896   *((uint32_t*)&CPU.ram[addr_ + 3*1024*1024]) = val_;
1897 }
1898 
1899 uint16_t
opera_mem_read16(uint32_t addr_)1900 opera_mem_read16(uint32_t addr_)
1901 {
1902   return *((uint16_t*)&CPU.ram[addr_]);
1903 }
1904 
1905 uint32_t
opera_mem_read32(uint32_t addr_)1906 opera_mem_read32(uint32_t addr_)
1907 {
1908   return *((uint32_t*)&CPU.ram[addr_]);
1909 }
1910 
1911 uint8_t
opera_mem_read8(uint32_t addr_)1912 opera_mem_read8(uint32_t addr_)
1913 {
1914   return CPU.ram[addr_];
1915 }
1916 
mwritew(uint32_t addr_,uint32_t val_)1917 static void mwritew(uint32_t addr_, uint32_t val_)
1918 {
1919    uint32_t index;
1920 
1921    addr_ &= ~3;
1922 
1923    if(addr_ < 0x00300000)
1924    {
1925       opera_mem_write32(addr_,val_);
1926       return;
1927    }
1928 
1929    index = (addr_ ^ 0x03300000);
1930    if(!(index & ~0x7FF))
1931    {
1932       opera_madam_poke(index,val_);
1933       return;
1934    }
1935 
1936    index = (addr_ ^ 0x03400000);
1937    if(!(index & ~0xFFFF))
1938    {
1939       if(opera_clio_poke(index,val_))
1940          CPU.USER[15] += 4;  /* ??? */
1941       return;
1942    }
1943 
1944    index = (addr_ ^ 0x03200000);
1945    if(!(index & ~0xFFFFF))
1946    {
1947       opera_sport_write_access(index,val_);
1948       return;
1949    }
1950 
1951    index = (addr_ ^ 0x03100000);
1952    if(!(index & ~0xFFFFF))
1953    {
1954       if(index & 0x80000)
1955          opera_diag_port_send(val_);
1956       else if(index & 0x40000)
1957          CPU.nvram[(index >> 2) & 0x7FFF] = (uint8_t)val_;
1958    }
1959 }
1960 
1961 static
1962 uint32_t
mreadw(uint32_t addr_)1963 mreadw(uint32_t addr_)
1964 {
1965   int32_t index;
1966 
1967   addr_ &= ~3;
1968 
1969   if(addr_ < 0x00300000)
1970     return opera_mem_read32(addr_);
1971 
1972   index = (addr_ ^ 0x03300000);
1973   if(!(index & ~0xFFFFF))
1974     return opera_madam_peek(index);
1975 
1976   index = (addr_ ^ 0x03400000);
1977   if(!(index & ~0xFFFFF))
1978     return opera_clio_peek(index);
1979 
1980   index = (addr_ ^ 0x03200000);
1981   if(!(index & ~0xFFFFF))
1982     {
1983       if(!(index & ~0x1FFF))
1984         return (opera_sport_set_source(index),0);
1985       return 0xBADACCE5;
1986     }
1987 
1988   /* Standard ROM */
1989   index = (addr_ ^ 0x03000000);
1990   if(!(index & ~0xFFFFF))
1991     return *(uint32_t*)&CPU.rom[index];
1992 
1993   /* ANVIL ROM */
1994   index = (addr_ ^ 0x06000000);
1995   if(!(index & ~0xFFFFF))
1996     return *(uint32_t*)&CPU.rom[index];
1997 
1998   index = (addr_ ^ 0x03100000);
1999   if(!(index & ~0xFFFFF))
2000     {
2001       if(index & 0x80000)
2002         return opera_diag_port_get();
2003       else if(index & 0x40000)
2004         return CPU.nvram[(index >> 2) & 0x7FFF];
2005     }
2006 
2007   /* MAS_Access_Exept = TRUE; */
2008 
2009   return 0xBADACCE5;
2010 }
2011 
mwriteb(uint32_t addr_,uint8_t val_)2012 static void mwriteb(uint32_t addr_, uint8_t  val_)
2013 {
2014   int32_t index;
2015 
2016   if(addr_ < 0x00300000)
2017   {
2018     opera_mem_write8(addr_ ^ 3,val_);
2019     return;
2020   }
2021 
2022   index = (addr_ ^ 0x03100003);
2023   if(!(index & ~0xFFFFF))
2024   {
2025      if((index & 0x40000) == 0x40000)
2026      {
2027         CPU.nvram[(index >> 2) & 0x7FFF] = val_;
2028         return;
2029      }
2030   }
2031 }
2032 
2033 static
2034 uint32_t
mreadb(uint32_t addr_)2035 mreadb(uint32_t addr_)
2036 {
2037   int32_t index;
2038 
2039   if(addr_ < 0x00300000)
2040     return opera_mem_read8(addr_ ^ 3);
2041 
2042   /* Standard ROM */
2043   index = (addr_ ^ 0x03000003);
2044   if(!(index & ~0xFFFFF))
2045     return CPU.rom[index];
2046 
2047   /* ANVIL ROM */
2048   index = (addr_ ^ 0x06000003);
2049   if(!(index & ~0xFFFFF))
2050     return CPU.rom[index];
2051 
2052   index = (addr_ ^ 0x03100003);
2053   if(!(index & ~0xFFFFF))
2054     {
2055       if((index & 0x40000) == 0x40000)
2056         return CPU.nvram[(index >> 2) & 0x7FFF];
2057     }
2058 
2059   /* MAS_Access_Exept = TRUE; */
2060 
2061   return 0xBADACCE5;
2062 }
2063 
2064 static
2065 void
loadusr(uint32_t n_,uint32_t val_)2066 loadusr(uint32_t n_,
2067         uint32_t val_)
2068 {
2069   if(n_ == 15)
2070     {
2071       CPU.USER[15] = val_;
2072       return;
2073     }
2074 
2075   switch(arm_mode_table[(CPU.CPSR & 0x1F) | 0x10])
2076     {
2077     case ARM_MODE_USER:
2078       CPU.USER[n_] = val_;
2079       break;
2080     case ARM_MODE_FIQ:
2081       if(n_ > 7)
2082         CPU.CASH[n_ - 8] = val_;
2083       else
2084         CPU.USER[n_] = val_;
2085       break;
2086     case ARM_MODE_IRQ:
2087     case ARM_MODE_ABT:
2088     case ARM_MODE_UND:
2089     case ARM_MODE_SVC:
2090       if(n_ > 12)
2091         CPU.CASH[n_ - 8] = val_;
2092       else
2093         CPU.USER[n_] = val_;
2094       break;
2095     }
2096 }
2097 
2098 static
2099 uint32_t
readusr(uint32_t n_)2100 readusr(uint32_t n_)
2101 {
2102   if(n_ == 15)
2103     return CPU.USER[15];
2104 
2105   switch(arm_mode_table[CPU.CPSR & 0x1F])
2106     {
2107     case ARM_MODE_USER:
2108       return CPU.USER[n_];
2109     case ARM_MODE_FIQ:
2110       if(n_ > 7)
2111         return CPU.CASH[n_ - 8];
2112       return CPU.USER[n_];
2113     case ARM_MODE_IRQ:
2114     case ARM_MODE_ABT:
2115     case ARM_MODE_UND:
2116     case ARM_MODE_SVC:
2117       if(n_ > 12)
2118         return CPU.CASH[n_ - 8];
2119       return CPU.USER[n_];
2120     }
2121 
2122   return 0;
2123 }
2124 
opera_io_read(const uint32_t addr_)2125 uint32_t opera_io_read(const uint32_t addr_)
2126 {
2127    return mreadw(addr_);
2128 }
2129 
opera_io_write(const uint32_t addr_,const uint32_t val_)2130 void opera_io_write(const uint32_t addr_, const uint32_t val_)
2131 {
2132   mwritew(addr_,val_);
2133 }
2134