41397701 |
1 | #include <string.h> |
2 | #include "sh2.h" |
5686d931 |
3 | #include "../debug.h" |
679af8a3 |
4 | #include "compiler.h" |
41397701 |
5 | |
6 | #define I 0xf0 |
7 | |
f0d7b1fa |
8 | SH2 *sh2; // active sh2 |
9 | |
679af8a3 |
10 | int sh2_init(SH2 *sh2, int is_slave) |
41397701 |
11 | { |
679af8a3 |
12 | int ret = 0; |
13 | |
41397701 |
14 | memset(sh2, 0, sizeof(*sh2)); |
15 | sh2->is_slave = is_slave; |
5686d931 |
16 | pdb_register_cpu(sh2, PDBCT_SH2, is_slave ? "ssh2" : "msh2"); |
679af8a3 |
17 | #ifdef DRC_SH2 |
18 | ret = sh2_drc_init(sh2); |
19 | #endif |
20 | return ret; |
41397701 |
21 | } |
22 | |
e898de13 |
23 | void sh2_finish(SH2 *sh2) |
24 | { |
25 | #ifdef DRC_SH2 |
26 | sh2_drc_finish(sh2); |
27 | #endif |
28 | } |
29 | |
41397701 |
30 | void sh2_reset(SH2 *sh2) |
31 | { |
bcf65fd6 |
32 | sh2->pc = p32x_sh2_read32(0, sh2); |
33 | sh2->r[15] = p32x_sh2_read32(4, sh2); |
41397701 |
34 | sh2->sr = I; |
35 | sh2->vbr = 0; |
36 | sh2->pending_int_irq = 0; |
37 | } |
38 | |
6add7875 |
39 | void sh2_do_irq(SH2 *sh2, int level, int vector) |
41397701 |
40 | { |
41397701 |
41 | sh2->r[15] -= 4; |
bcf65fd6 |
42 | p32x_sh2_write32(sh2->r[15], sh2->sr, sh2); /* push SR onto stack */ |
41397701 |
43 | sh2->r[15] -= 4; |
bcf65fd6 |
44 | p32x_sh2_write32(sh2->r[15], sh2->pc, sh2); /* push PC onto stack */ |
41397701 |
45 | |
46 | /* set I flags in SR */ |
47 | sh2->sr = (sh2->sr & ~I) | (level << 4); |
48 | |
49 | /* fetch PC */ |
bcf65fd6 |
50 | sh2->pc = p32x_sh2_read32(sh2->vbr + vector * 4, sh2); |
41397701 |
51 | |
52 | /* 13 cycles at best */ |
53 | sh2->cycles_done += 13; |
54 | // sh2->icount -= 13; |
55 | } |
56 | |
57 | void sh2_irl_irq(SH2 *sh2, int level) |
58 | { |
59 | sh2->pending_irl = level; |
6add7875 |
60 | if (level > sh2->pending_int_irq) |
61 | sh2->pending_level = level; |
62 | else |
63 | sh2->pending_level = sh2->pending_int_irq; |
41397701 |
64 | |
6add7875 |
65 | sh2->test_irq = 1; |
41397701 |
66 | } |
67 | |
68 | void sh2_internal_irq(SH2 *sh2, int level, int vector) |
69 | { |
6add7875 |
70 | // FIXME: multiple internal irqs not handled.. |
71 | // assuming internal irqs never clear until accepted |
41397701 |
72 | sh2->pending_int_irq = level; |
73 | sh2->pending_int_vector = vector; |
6add7875 |
74 | if (level > sh2->pending_level) |
75 | sh2->pending_level = level; |
41397701 |
76 | |
6add7875 |
77 | sh2->test_irq = 1; |
41397701 |
78 | } |
79 | |