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)
21 memset(sh2, 0, offsetof(SH2, mult_m68k_to_sh2));
22 sh2->is_slave = is_slave;
23 pdb_register_cpu(sh2, PDBCT_SH2, is_slave ? "ssh2" : "msh2");
25 ret = sh2_drc_init(sh2);
30 void sh2_finish(SH2 *sh2)
37 void sh2_reset(SH2 *sh2)
39 sh2->pc = p32x_sh2_read32(0, sh2);
40 sh2->r[15] = p32x_sh2_read32(4, sh2);
43 sh2->pending_int_irq = 0;
46 void sh2_do_irq(SH2 *sh2, int level, int vector)
51 p32x_sh2_write32(sh2->r[15], sh2->sr, sh2); /* push SR onto stack */
53 p32x_sh2_write32(sh2->r[15], sh2->pc, sh2); /* push PC onto stack */
55 /* set I flags in SR */
56 sh2->sr = (sh2->sr & ~I) | (level << 4);
59 sh2->pc = p32x_sh2_read32(sh2->vbr + vector * 4, sh2);
61 /* 13 cycles at best */
65 int sh2_irl_irq(SH2 *sh2, int level, int nested_call)
69 sh2->pending_irl = level;
70 if (level < sh2->pending_int_irq)
71 level = sh2->pending_int_irq;
72 sh2->pending_level = level;
74 taken = (level > ((sh2->sr >> 4) & 0x0f));
77 // not in memhandler, so handle this now (recompiler friendly)
78 // do this to avoid missing irqs that other SH2 might clear
79 int vector = sh2->irq_callback(sh2, level);
80 sh2_do_irq(sh2, level, vector);
81 sh2->m68krcycles_done += C_SH2_TO_M68K(*sh2, 13);
89 void sh2_internal_irq(SH2 *sh2, int level, int vector)
91 // FIXME: multiple internal irqs not handled..
92 // assuming internal irqs never clear until accepted
93 sh2->pending_int_irq = level;
94 sh2->pending_int_vector = vector;
95 if (level > sh2->pending_level)
96 sh2->pending_level = level;
101 #define SH2_REG_SIZE (offsetof(SH2, macl) + sizeof(sh2->macl))
103 void sh2_pack(const SH2 *sh2, unsigned char *buff)
107 memcpy(buff, sh2, SH2_REG_SIZE);
108 p = (void *)(buff + SH2_REG_SIZE);
110 p[0] = sh2->pending_int_irq;
111 p[1] = sh2->pending_int_vector;
114 void sh2_unpack(SH2 *sh2, const unsigned char *buff)
118 memcpy(sh2, buff, SH2_REG_SIZE);
119 p = (void *)(buff + SH2_REG_SIZE);
121 sh2->pending_int_irq = p[0];
122 sh2->pending_int_vector = p[1];
131 #include <pico/memory.h>
132 #undef _USE_CZ80 // HACK
133 #include <pico/pico_int.h>
134 #include <pico/debug.h>
136 static SH2 sh2ref[2];
137 static unsigned int mem_val;
141 CTL_MASTERSLAVE = 0x80,
148 #define SH2MAP_ADDR2OFFS_R(a) \
149 ((((a) >> 25) & 3) | (((a) >> 27) & 0x1c))
151 static unsigned int local_read32(SH2 *sh2, u32 a)
153 const sh2_memmap *sh2_map = sh2->read16_map;
157 sh2_map += SH2MAP_ADDR2OFFS_R(a);
159 if (!map_flag_set(p)) {
160 pd = (u16 *)((p << 1) + ((a & sh2_map->mask) & ~1));
161 return (pd[0] << 16) | pd[1];
164 if ((a & 0xfffff000) == 0xc0000000) {
166 pd = (u16 *)Pico32xMem->data_array[sh2->is_slave]
168 return (pd[0] << 16) | pd[1];
170 if ((a & 0xdfffffc0) == 0x4000) {
171 pd = &Pico32x.regs[(a & 0x3f) / 2];
172 return (pd[0] << 16) | pd[1];
174 if ((a & 0xdffffe00) == 0x4200) {
175 pd = &Pico32xMem->pal[(a & 0x1ff) / 2];
176 return (pd[0] << 16) | pd[1];
182 static void write_uint(unsigned char ctl, unsigned int v)
184 fwrite(&ctl, 1, 1, f);
185 fwrite(&v, sizeof(v), 1, f);
188 void do_sh2_trace(SH2 *current, int cycles)
190 static int current_slave = -1;
191 static u32 current_m68k_pc;
192 SH2 *sh2o = &sh2ref[current->is_slave];
193 u32 *regs_a = (void *)current;
194 u32 *regs_o = (void *)sh2o;
200 f = fopen("tracelog", "wb");
202 if (SekPc != current_m68k_pc) {
203 current_m68k_pc = SekPc;
204 write_uint(CTL_M68KPC, current_m68k_pc);
207 if (current->is_slave != current_slave) {
208 current_slave = current->is_slave;
209 v = CTL_MASTERSLAVE | current->is_slave;
213 for (i = 0; i < offsetof(SH2, read8_map) / 4; i++) {
216 if (regs_a[i] != regs_o[i]) {
217 write_uint(i, regs_a[i]);
218 regs_o[i] = regs_a[i];
222 if (current->ea != sh2o->ea) {
223 write_uint(CTL_EA, current->ea);
224 sh2o->ea = current->ea;
226 val = local_read32(current, current->ea);
227 if (mem_val != val) {
228 write_uint(CTL_EAVAL, val);
231 write_uint(CTL_CYCLES, cycles);
234 static const char *regnames[] = {
235 "r0", "r1", "r2", "r3",
236 "r4", "r5", "r6", "r7",
237 "r8", "r9", "r10", "r11",
238 "r12", "r13", "r14", "r15",
239 "pc", "ppc", "pr", "sr",
240 "gbr", "vbr", "mach","macl",
243 static void dump_regs(SH2 *sh2)
248 csh2 = sh2->is_slave ? 's' : 'm';
249 for (i = 0; i < 16/2; i++)
250 printf("%csh2 r%d: %08x r%02d: %08x\n", csh2,
251 i, sh2->r[i], i+8, sh2->r[i+8]);
252 printf("%csh2 PC: %08x , %08x\n", csh2, sh2->pc, sh2->ppc);
253 printf("%csh2 SR: %03x PR: %08x\n", csh2, sh2->sr, sh2->pr);
256 void do_sh2_cmp(SH2 *current)
258 static int current_slave;
259 static u32 current_val;
260 SH2 *sh2o = &sh2ref[current->is_slave];
261 u32 *regs_a = (void *)current;
262 u32 *regs_o = (void *)sh2o;
271 f = fopen("tracelog", "rb");
272 sh2ref[1].is_slave = 1;
276 ret = fread(&code, 1, 1, f);
279 if (code == CTL_CYCLES) {
280 fread(&cycles_o, 1, 4, f);
285 case CTL_MASTERSLAVE:
286 case CTL_MASTERSLAVE + 1:
287 current_slave = code & 1;
290 fread(&sh2o->ea, 4, 1, f);
293 fread(¤t_val, 4, 1, f);
296 fread(&val, 4, 1, f);
298 printf("m68k: %08x %08x\n", SekPc, val);
303 if (code < offsetof(SH2, read8_map) / 4)
304 fread(regs_o + code, 4, 1, f);
306 printf("invalid code: %02x\n", code);
318 if (current->is_slave != current_slave) {
319 printf("bad slave: %d %d\n", current->is_slave,
324 for (i = 0; i < offsetof(SH2, read8_map) / 4; i++) {
325 if (i == 17 || i == 19) // ppc, sr
327 if (regs_a[i] != regs_o[i]) {
328 printf("bad %4s: %08x %08x\n",
329 regnames[i], regs_a[i], regs_o[i]);
334 sr = current->sr & 0x3f3;
335 cycles = (signed int)current->sr >> 12;
337 if (sr != sh2o->sr) {
338 printf("bad SR: %03x %03x\n", sr, sh2o->sr);
342 if (cycles != cycles_o) {
343 printf("bad cycles: %d %d\n", cycles, cycles_o);
347 val = local_read32(current, sh2o->ea);
348 if (val != current_val) {
349 printf("bad val @%08x: %08x %08x\n", sh2o->ea, val, current_val);
354 sh2o->ppc = current->pc;
361 if (current->is_slave != current_slave)
362 dump_regs(&sh2ref[current->is_slave ^ 1]);