5 * This work is licensed under the terms of MAME license.
6 * See COPYING file in the top-level directory.
17 int sh2_init(SH2 *sh2, int is_slave, SH2 *other_sh2)
21 memset(sh2, 0, offsetof(SH2, mult_m68k_to_sh2));
22 sh2->is_slave = is_slave;
23 sh2->other_sh2 = other_sh2;
24 pdb_register_cpu(sh2, PDBCT_SH2, is_slave ? "ssh2" : "msh2");
26 ret = sh2_drc_init(sh2);
31 void sh2_finish(SH2 *sh2)
38 void sh2_reset(SH2 *sh2)
40 sh2->pc = p32x_sh2_read32(0, sh2);
41 sh2->r[15] = p32x_sh2_read32(4, sh2);
44 sh2->pending_int_irq = 0;
47 void sh2_do_irq(SH2 *sh2, int level, int vector)
52 p32x_sh2_write32(sh2->r[15], sh2->sr, sh2); /* push SR onto stack */
54 p32x_sh2_write32(sh2->r[15], sh2->pc, sh2); /* push PC onto stack */
56 /* set I flags in SR */
57 sh2->sr = (sh2->sr & ~I) | (level << 4);
60 sh2->pc = p32x_sh2_read32(sh2->vbr + vector * 4, sh2);
62 /* 13 cycles at best */
66 int sh2_irl_irq(SH2 *sh2, int level, int nested_call)
70 sh2->pending_irl = level;
71 if (level < sh2->pending_int_irq)
72 level = sh2->pending_int_irq;
73 sh2->pending_level = level;
75 taken = (level > ((sh2->sr >> 4) & 0x0f));
78 // not in memhandler, so handle this now (recompiler friendly)
79 // do this to avoid missing irqs that other SH2 might clear
80 int vector = sh2->irq_callback(sh2, level);
81 sh2_do_irq(sh2, level, vector);
82 sh2->m68krcycles_done += C_SH2_TO_M68K(*sh2, 13);
90 void sh2_internal_irq(SH2 *sh2, int level, int vector)
92 // FIXME: multiple internal irqs not handled..
93 // assuming internal irqs never clear until accepted
94 sh2->pending_int_irq = level;
95 sh2->pending_int_vector = vector;
96 if (level > sh2->pending_level)
97 sh2->pending_level = level;
102 #define SH2_REG_SIZE (offsetof(SH2, macl) + sizeof(sh2->macl))
104 void sh2_pack(const SH2 *sh2, unsigned char *buff)
108 memcpy(buff, sh2, SH2_REG_SIZE);
109 p = (void *)(buff + SH2_REG_SIZE);
111 p[0] = sh2->pending_int_irq;
112 p[1] = sh2->pending_int_vector;
115 void sh2_unpack(SH2 *sh2, const unsigned char *buff)
119 memcpy(sh2, buff, SH2_REG_SIZE);
120 p = (void *)(buff + SH2_REG_SIZE);
122 sh2->pending_int_irq = p[0];
123 sh2->pending_int_vector = p[1];
132 #include <pico/memory.h>
133 #undef _USE_CZ80 // HACK
134 #include <pico/pico_int.h>
135 #include <pico/debug.h>
137 static SH2 sh2ref[2];
138 static unsigned int mem_val;
142 CTL_MASTERSLAVE = 0x80,
149 static unsigned int local_read32(SH2 *sh2, u32 a)
151 const sh2_memmap *sh2_map = sh2->read16_map;
155 sh2_map += (a >> 25);
157 if (!map_flag_set(p)) {
158 pd = (u16 *)((p << 1) + ((a & sh2_map->mask) & ~1));
159 return (pd[0] << 16) | pd[1];
162 if ((a & 0xfffff000) == 0xc0000000) {
164 pd = (u16 *)sh2->data_array + (a & 0xfff) / 2;
165 return (pd[0] << 16) | pd[1];
167 if ((a & 0xdfffffc0) == 0x4000) {
168 pd = &Pico32x.regs[(a & 0x3f) / 2];
169 return (pd[0] << 16) | pd[1];
171 if ((a & 0xdffffe00) == 0x4200) {
172 pd = &Pico32xMem->pal[(a & 0x1ff) / 2];
173 return (pd[0] << 16) | pd[1];
179 static void write_uint(unsigned char ctl, unsigned int v)
181 fwrite(&ctl, 1, 1, f);
182 fwrite(&v, sizeof(v), 1, f);
185 void do_sh2_trace(SH2 *current, int cycles)
187 static int current_slave = -1;
188 static u32 current_m68k_pc;
189 SH2 *sh2o = &sh2ref[current->is_slave];
190 u32 *regs_a = (void *)current;
191 u32 *regs_o = (void *)sh2o;
197 f = fopen("tracelog", "wb");
199 if (SekPc != current_m68k_pc) {
200 current_m68k_pc = SekPc;
201 write_uint(CTL_M68KPC, current_m68k_pc);
204 if (current->is_slave != current_slave) {
205 current_slave = current->is_slave;
206 v = CTL_MASTERSLAVE | current->is_slave;
210 for (i = 0; i < offsetof(SH2, read8_map) / 4; i++) {
213 if (regs_a[i] != regs_o[i]) {
214 write_uint(i, regs_a[i]);
215 regs_o[i] = regs_a[i];
219 if (current->ea != sh2o->ea) {
220 write_uint(CTL_EA, current->ea);
221 sh2o->ea = current->ea;
223 val = local_read32(current, current->ea);
224 if (mem_val != val) {
225 write_uint(CTL_EAVAL, val);
228 write_uint(CTL_CYCLES, cycles);
231 static const char *regnames[] = {
232 "r0", "r1", "r2", "r3",
233 "r4", "r5", "r6", "r7",
234 "r8", "r9", "r10", "r11",
235 "r12", "r13", "r14", "r15",
236 "pc", "ppc", "pr", "sr",
237 "gbr", "vbr", "mach","macl",
240 static void dump_regs(SH2 *sh2)
245 csh2 = sh2->is_slave ? 's' : 'm';
246 for (i = 0; i < 16/2; i++)
247 printf("%csh2 r%d: %08x r%02d: %08x\n", csh2,
248 i, sh2->r[i], i+8, sh2->r[i+8]);
249 printf("%csh2 PC: %08x , %08x\n", csh2, sh2->pc, sh2->ppc);
250 printf("%csh2 SR: %03x PR: %08x\n", csh2, sh2->sr, sh2->pr);
253 void do_sh2_cmp(SH2 *current)
255 static int current_slave;
256 static u32 current_val;
257 SH2 *sh2o = &sh2ref[current->is_slave];
258 u32 *regs_a = (void *)current;
259 u32 *regs_o = (void *)sh2o;
268 f = fopen("tracelog", "rb");
269 sh2ref[1].is_slave = 1;
273 ret = fread(&code, 1, 1, f);
276 if (code == CTL_CYCLES) {
277 fread(&cycles_o, 1, 4, f);
282 case CTL_MASTERSLAVE:
283 case CTL_MASTERSLAVE + 1:
284 current_slave = code & 1;
287 fread(&sh2o->ea, 4, 1, f);
290 fread(¤t_val, 4, 1, f);
293 fread(&val, 4, 1, f);
295 printf("m68k: %08x %08x\n", SekPc, val);
300 if (code < offsetof(SH2, read8_map) / 4)
301 fread(regs_o + code, 4, 1, f);
303 printf("invalid code: %02x\n", code);
315 if (current->is_slave != current_slave) {
316 printf("bad slave: %d %d\n", current->is_slave,
321 for (i = 0; i < offsetof(SH2, read8_map) / 4; i++) {
322 if (i == 17 || i == 19) // ppc, sr
324 if (regs_a[i] != regs_o[i]) {
325 printf("bad %4s: %08x %08x\n",
326 regnames[i], regs_a[i], regs_o[i]);
331 sr = current->sr & 0x3f3;
332 cycles = (signed int)current->sr >> 12;
334 if (sr != sh2o->sr) {
335 printf("bad SR: %03x %03x\n", sr, sh2o->sr);
339 if (cycles != cycles_o) {
340 printf("bad cycles: %d %d\n", cycles, cycles_o);
344 val = local_read32(current, sh2o->ea);
345 if (val != current_val) {
346 printf("bad val @%08x: %08x %08x\n", sh2o->ea, val, current_val);
351 sh2o->ppc = current->pc;
358 if (current->is_slave != current_slave)
359 dump_regs(&sh2ref[current->is_slave ^ 1]);