41397701 |
1 | #include <string.h> |
2 | #include "sh2.h" |
679af8a3 |
3 | #include "compiler.h" |
41397701 |
4 | |
5 | #define I 0xf0 |
6 | |
679af8a3 |
7 | int sh2_init(SH2 *sh2, int is_slave) |
41397701 |
8 | { |
679af8a3 |
9 | int ret = 0; |
10 | |
41397701 |
11 | memset(sh2, 0, sizeof(*sh2)); |
12 | sh2->is_slave = is_slave; |
679af8a3 |
13 | #ifdef DRC_SH2 |
14 | ret = sh2_drc_init(sh2); |
15 | #endif |
16 | return ret; |
41397701 |
17 | } |
18 | |
19 | void sh2_reset(SH2 *sh2) |
20 | { |
21 | sh2->pc = p32x_sh2_read32(0, sh2->is_slave); |
22 | sh2->r[15] = p32x_sh2_read32(4, sh2->is_slave); |
23 | sh2->sr = I; |
24 | sh2->vbr = 0; |
25 | sh2->pending_int_irq = 0; |
26 | } |
27 | |
28 | static void sh2_do_irq(SH2 *sh2, int level, int vector) |
29 | { |
30 | sh2->irq_callback(sh2->is_slave, level); |
31 | |
32 | sh2->r[15] -= 4; |
33 | p32x_sh2_write32(sh2->r[15], sh2->sr, sh2->is_slave); /* push SR onto stack */ |
34 | sh2->r[15] -= 4; |
35 | p32x_sh2_write32(sh2->r[15], sh2->pc, sh2->is_slave); /* push PC onto stack */ |
36 | |
37 | /* set I flags in SR */ |
38 | sh2->sr = (sh2->sr & ~I) | (level << 4); |
39 | |
40 | /* fetch PC */ |
41 | sh2->pc = p32x_sh2_read32(sh2->vbr + vector * 4, sh2->is_slave); |
42 | |
43 | /* 13 cycles at best */ |
44 | sh2->cycles_done += 13; |
45 | // sh2->icount -= 13; |
46 | } |
47 | |
48 | void sh2_irl_irq(SH2 *sh2, int level) |
49 | { |
50 | sh2->pending_irl = level; |
51 | if (level <= ((sh2->sr >> 4) & 0x0f)) |
52 | return; |
53 | |
54 | sh2_do_irq(sh2, level, 64 + level/2); |
55 | } |
56 | |
57 | void sh2_internal_irq(SH2 *sh2, int level, int vector) |
58 | { |
59 | sh2->pending_int_irq = level; |
60 | sh2->pending_int_vector = vector; |
61 | if (level <= ((sh2->sr >> 4) & 0x0f)) |
62 | return; |
63 | |
64 | sh2_do_irq(sh2, level, vector); |
65 | sh2->pending_int_irq = 0; // auto-clear |
66 | } |
67 | |