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