fix GP2X build
[picodrive.git] / cpu / sh2mame / sh2pico.c
CommitLineData
eaa10a6e 1#include <string.h>
2
3// MAME types
4typedef signed char INT8;
5typedef signed short INT16;
6typedef signed int INT32;
7typedef unsigned int UINT32;
8typedef unsigned short UINT16;
9typedef unsigned char UINT8;
10
11// pico memhandlers
b78efee2 12unsigned int p32x_sh2_read8(unsigned int a, int id);
13unsigned int p32x_sh2_read16(unsigned int a, int id);
14unsigned int p32x_sh2_read32(unsigned int a, int id);
15void p32x_sh2_write8(unsigned int a, unsigned int d, int id);
16void p32x_sh2_write16(unsigned int a, unsigned int d, int id);
17void p32x_sh2_write32(unsigned int a, unsigned int d, int id);
18
19#define RB(a) p32x_sh2_read8(a,sh2->is_slave)
20#define RW(a) p32x_sh2_read16(a,sh2->is_slave)
21#define RL(a) p32x_sh2_read32(a,sh2->is_slave)
22#define WB(a,d) p32x_sh2_write8(a,d,sh2->is_slave)
23#define WW(a,d) p32x_sh2_write16(a,d,sh2->is_slave)
24#define WL(a,d) p32x_sh2_write32(a,d,sh2->is_slave)
eaa10a6e 25
26// some stuff from sh2comn.h
27#define T 0x00000001
28#define S 0x00000002
29#define I 0x000000f0
30#define Q 0x00000100
31#define M 0x00000200
32
33#define AM 0xc7ffffff
34
35#define FLAGS (M|Q|I|S|T)
36
37#define Rn ((opcode>>8)&15)
38#define Rm ((opcode>>4)&15)
39
40#include "sh2.c"
41
42void sh2_reset(SH2 *sh2)
43{
eaa10a6e 44 sh2->pc = RL(0);
45 sh2->r[15] = RL(4);
46 sh2->sr = I;
83ff19ec 47 sh2->vbr = 0;
48 sh2->pending_int_irq = 0;
eaa10a6e 49}
50
1d7a28a7 51static void sh2_do_irq(SH2 *sh2, int level, int vector)
52{
53 sh2->irq_callback(sh2->is_slave, level);
54
55 sh2->r[15] -= 4;
56 WL(sh2->r[15], sh2->sr); /* push SR onto stack */
57 sh2->r[15] -= 4;
58 WL(sh2->r[15], sh2->pc); /* push PC onto stack */
59
60 /* set I flags in SR */
61 sh2->sr = (sh2->sr & ~I) | (level << 4);
62
63 /* fetch PC */
64 sh2->pc = RL(sh2->vbr + vector * 4);
65
66 /* 13 cycles at best */
67 sh2_icount -= 13;
68}
69
eaa10a6e 70/* Execute cycles - returns number of cycles actually run */
71int sh2_execute(SH2 *sh2_, int cycles)
72{
73 sh2 = sh2_;
74 sh2_icount = cycles;
2ea2cbfe 75 sh2->cycles_aim += cycles;
eaa10a6e 76
77 do
78 {
79 UINT32 opcode;
80
3cf9570b 81 if (sh2->delay)
82 {
a44737c1 83 sh2->ppc = sh2->delay;
3cf9570b 84 opcode = RW(sh2->delay);
85 sh2->pc -= 2;
86 }
87 else
a44737c1 88 {
89 sh2->ppc = sh2->pc;
3cf9570b 90 opcode = RW(sh2->pc);
a44737c1 91 }
eaa10a6e 92
93 sh2->delay = 0;
94 sh2->pc += 2;
eaa10a6e 95
96 switch (opcode & ( 15 << 12))
97 {
98 case 0<<12: op0000(opcode); break;
99 case 1<<12: op0001(opcode); break;
100 case 2<<12: op0010(opcode); break;
101 case 3<<12: op0011(opcode); break;
102 case 4<<12: op0100(opcode); break;
103 case 5<<12: op0101(opcode); break;
104 case 6<<12: op0110(opcode); break;
105 case 7<<12: op0111(opcode); break;
106 case 8<<12: op1000(opcode); break;
107 case 9<<12: op1001(opcode); break;
108 case 10<<12: op1010(opcode); break;
109 case 11<<12: op1011(opcode); break;
110 case 12<<12: op1100(opcode); break;
111 case 13<<12: op1101(opcode); break;
112 case 14<<12: op1110(opcode); break;
113 default: op1111(opcode); break;
114 }
115
116 if (sh2->test_irq && !sh2->delay)
117 {
1d7a28a7 118 if (sh2->pending_irl > sh2->pending_int_irq)
119 sh2_irl_irq(sh2, sh2->pending_irl);
120 else
121 sh2_internal_irq(sh2, sh2->pending_int_irq, sh2->pending_int_vector);
eaa10a6e 122 sh2->test_irq = 0;
123 }
124 sh2_icount--;
125 }
2ea2cbfe 126 while (sh2_icount > 0 || sh2->delay); /* can't interrupt before delay */
eaa10a6e 127
128 return cycles - sh2_icount;
129}
130
b78efee2 131void sh2_init(SH2 *sh2, int is_slave)
eaa10a6e 132{
133 memset(sh2, 0, sizeof(*sh2));
b78efee2 134 sh2->is_slave = is_slave;
eaa10a6e 135}
136
4ea707e1 137void sh2_irl_irq(SH2 *sh2, int level)
138{
1d7a28a7 139 sh2->pending_irl = level;
4ea707e1 140 if (level <= ((sh2->sr >> 4) & 0x0f))
4ea707e1 141 return;
142
1d7a28a7 143 sh2_do_irq(sh2, level, 64 + level/2);
144}
4ea707e1 145
1d7a28a7 146void sh2_internal_irq(SH2 *sh2, int level, int vector)
147{
148 sh2->pending_int_irq = level;
149 sh2->pending_int_vector = vector;
150 if (level <= ((sh2->sr >> 4) & 0x0f))
151 return;
4ea707e1 152
1d7a28a7 153 sh2_do_irq(sh2, level, vector);
154 sh2->pending_int_irq = 0; // auto-clear
4ea707e1 155}
eaa10a6e 156