1 // 187 blocks, 12072 bytes
4 #include "../../PicoInt.h"
6 #define TCACHE_SIZE (256*1024)
7 static unsigned int *block_table[0x5090/2];
8 static unsigned int *block_table_iram[15][0x800/2];
9 static unsigned int *tcache = NULL;
10 static unsigned int *tcache_ptr = NULL;
12 static int had_jump = 0;
13 static int nblocks = 0;
14 static int iram_context = 0;
16 #define EMBED_INTERPRETER
17 #define ssp1601_reset ssp1601_reset_local
18 #define ssp1601_run ssp1601_run_local
21 #define GET_PPC_OFFS() (GET_PC()*2 - 2)
22 #define SET_PC(d) { had_jump = 1; rPC = d; } /* must return to dispatcher after this */
23 //#define GET_PC() (PC - (unsigned short *)svp->iram_rom)
24 //#define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2)
25 //#define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d
30 // -----------------------------------------------------
33 static void op00(unsigned int op, unsigned int imm)
36 PC = ((unsigned short *)&op) + 1; /* FIXME: needed for interpreter */
37 if (op == 0) return; // nop
38 if (op == ((SSP_A<<4)|SSP_P)) { // A <- P
39 // not sure. MAME claims that only hi word is transfered.
45 tmpv = REG_READ(op & 0x0f);
46 REG_WRITE((op & 0xf0) >> 4, tmpv);
51 static void op01(unsigned int op, unsigned int imm)
54 tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv);
58 static void op02(unsigned int op, unsigned int imm)
61 tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv);
65 static void op04(unsigned int op, unsigned int imm)
67 REG_WRITE((op & 0xf0) >> 4, imm);
71 static void op05(unsigned int op, unsigned int imm)
74 tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv);
78 static void op06(unsigned int op, unsigned int imm)
84 static void op07(unsigned int op, unsigned int imm)
86 ssp->RAM[op & 0x1ff] = rA;
90 static void op09(unsigned int op, unsigned int imm)
93 tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv);
97 static void op0a(unsigned int op, unsigned int imm)
99 rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4);
102 // ldi ri, simm (also op0d op0e op0f)
103 static void op0c(unsigned int op, unsigned int imm)
109 static void op24(unsigned int op, unsigned int imm)
114 if (cond) { int new_PC = imm; write_STACK(GET_PC()); write_PC(new_PC); }
120 static void op25(unsigned int op, unsigned int imm)
123 tmpv = ((unsigned short *)svp->iram_rom)[rA]; REG_WRITE((op & 0xf0) >> 4, tmpv);
127 static void op26(unsigned int op, unsigned int imm)
133 if (cond) write_PC(imm);
139 static void op48(unsigned int op, unsigned int imm)
147 case 2: rA32 = (signed int)rA32 >> 1; break; // shr (arithmetic)
148 case 3: rA32 <<= 1; break; // shl
149 case 6: rA32 = -(signed int)rA32; break; // neg
150 case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; // abs
151 default: elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x",
152 op&7, GET_PPC_OFFS());
161 static void op1b(unsigned int op, unsigned int imm)
163 read_P(); // update P
164 rA32 -= rP.v; // maybe only upper word?
165 UPD_ACC_ZN // there checking flags after this
166 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
167 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
170 // mpya (rj), (ri), b
171 static void op4b(unsigned int op, unsigned int imm)
173 read_P(); // update P
174 rA32 += rP.v; // confirmed to be 32bit
176 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
177 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
181 static void op5b(unsigned int op, unsigned int imm)
185 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
186 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
190 static void op10(unsigned int op, unsigned int imm)
195 OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv);
200 static void op30(unsigned int op, unsigned int imm)
205 OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv);
210 static void op40(unsigned int op, unsigned int imm)
215 OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv);
220 static void op50(unsigned int op, unsigned int imm)
225 OP_CHECK32(OP_ANDA32); tmpv = REG_READ(op & 0x0f); OP_ANDA(tmpv);
230 static void op60(unsigned int op, unsigned int imm)
235 OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv);
240 static void op70(unsigned int op, unsigned int imm)
245 OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv);
251 static void op11(unsigned int op, unsigned int imm)
254 tmpv = ptr1_read(op); OP_SUBA(tmpv);
257 static void op31(unsigned int op, unsigned int imm)
260 tmpv = ptr1_read(op); OP_CMPA(tmpv);
263 static void op41(unsigned int op, unsigned int imm)
266 tmpv = ptr1_read(op); OP_ADDA(tmpv);
269 static void op51(unsigned int op, unsigned int imm)
272 tmpv = ptr1_read(op); OP_ANDA(tmpv);
275 static void op61(unsigned int op, unsigned int imm)
278 tmpv = ptr1_read(op); OP_ORA (tmpv);
281 static void op71(unsigned int op, unsigned int imm)
284 tmpv = ptr1_read(op); OP_EORA(tmpv);
288 static void op03(unsigned int op, unsigned int imm)
291 tmpv = ssp->RAM[op & 0x1ff]; OP_LDA (tmpv);
294 static void op13(unsigned int op, unsigned int imm)
297 tmpv = ssp->RAM[op & 0x1ff]; OP_SUBA(tmpv);
300 static void op33(unsigned int op, unsigned int imm)
303 tmpv = ssp->RAM[op & 0x1ff]; OP_CMPA(tmpv);
306 static void op43(unsigned int op, unsigned int imm)
309 tmpv = ssp->RAM[op & 0x1ff]; OP_ADDA(tmpv);
312 static void op53(unsigned int op, unsigned int imm)
315 tmpv = ssp->RAM[op & 0x1ff]; OP_ANDA(tmpv);
318 static void op63(unsigned int op, unsigned int imm)
321 tmpv = ssp->RAM[op & 0x1ff]; OP_ORA (tmpv);
324 static void op73(unsigned int op, unsigned int imm)
327 tmpv = ssp->RAM[op & 0x1ff]; OP_EORA(tmpv);
331 static void op14(unsigned int op, unsigned int imm)
336 static void op34(unsigned int op, unsigned int imm)
341 static void op44(unsigned int op, unsigned int imm)
346 static void op54(unsigned int op, unsigned int imm)
351 static void op64(unsigned int op, unsigned int imm)
356 static void op74(unsigned int op, unsigned int imm)
362 static void op15(unsigned int op, unsigned int imm)
365 tmpv = ptr2_read(op); OP_SUBA(tmpv);
368 static void op35(unsigned int op, unsigned int imm)
371 tmpv = ptr2_read(op); OP_CMPA(tmpv);
374 static void op45(unsigned int op, unsigned int imm)
377 tmpv = ptr2_read(op); OP_ADDA(tmpv);
380 static void op55(unsigned int op, unsigned int imm)
383 tmpv = ptr2_read(op); OP_ANDA(tmpv);
386 static void op65(unsigned int op, unsigned int imm)
389 tmpv = ptr2_read(op); OP_ORA (tmpv);
392 static void op75(unsigned int op, unsigned int imm)
395 tmpv = ptr2_read(op); OP_EORA(tmpv);
399 static void op19(unsigned int op, unsigned int imm)
402 tmpv = rIJ[IJind]; OP_SUBA(tmpv);
405 static void op39(unsigned int op, unsigned int imm)
408 tmpv = rIJ[IJind]; OP_CMPA(tmpv);
411 static void op49(unsigned int op, unsigned int imm)
414 tmpv = rIJ[IJind]; OP_ADDA(tmpv);
417 static void op59(unsigned int op, unsigned int imm)
420 tmpv = rIJ[IJind]; OP_ANDA(tmpv);
423 static void op69(unsigned int op, unsigned int imm)
426 tmpv = rIJ[IJind]; OP_ORA (tmpv);
429 static void op79(unsigned int op, unsigned int imm)
432 tmpv = rIJ[IJind]; OP_EORA(tmpv);
436 static void op1c(unsigned int op, unsigned int imm)
441 static void op3c(unsigned int op, unsigned int imm)
446 static void op4c(unsigned int op, unsigned int imm)
451 static void op5c(unsigned int op, unsigned int imm)
456 static void op6c(unsigned int op, unsigned int imm)
461 static void op7c(unsigned int op, unsigned int imm)
466 typedef void (in_func)(unsigned int op, unsigned int imm);
468 static in_func *in_funcs[0x80] =
470 op00, op01, op02, op03, op04, op05, op06, op07,
471 NULL, op09, op0a, NULL, op0c, op0c, op0c, op0c,
472 op10, op11, NULL, op13, op14, op15, NULL, NULL,
473 NULL, op19, NULL, op1b, op1c, NULL, NULL, NULL,
474 NULL, NULL, NULL, NULL, op24, op25, op26, NULL,
475 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
476 op30, op31, NULL, op33, op34, op35, NULL, NULL,
477 NULL, op39, NULL, NULL, op3c, NULL, NULL, NULL,
478 op40, op41, NULL, op43, op44, op45, NULL, NULL,
479 op48, op49, NULL, op4b, op4c, NULL, NULL, NULL,
480 op50, op51, NULL, op53, op54, op55, NULL, NULL,
481 NULL, op59, NULL, op5b, op5c, NULL, NULL, NULL,
482 op60, op61, NULL, op63, op64, op65, NULL, NULL,
483 NULL, op69, NULL, NULL, op6c, NULL, NULL, NULL,
484 op70, op71, NULL, op73, op74, op75, NULL, NULL,
485 NULL, op79, NULL, NULL, op7c, NULL, NULL, NULL,
488 // -----------------------------------------------------
490 static unsigned char iram_context_map[] =
492 0, 0, 0, 0, 1, 0, 0, 0, // 04
493 0, 0, 0, 0, 0, 0, 2, 0, // 0e
494 0, 0, 0, 0, 0, 3, 0, 4, // 15 17
495 5, 0, 0, 6, 0, 7, 0, 0, // 18 1b 1d
496 8, 9, 0, 0, 0,10, 0, 0, // 20 21 25
497 0, 0, 0, 0, 0, 0, 0, 0,
498 0, 0,11, 0, 0,12, 0, 0, // 32 35
499 13,14, 0, 0, 0, 0, 0, 0 // 38 39
502 static int get_iram_context(void)
504 unsigned char *ir = (unsigned char *)svp->iram_rom;
505 int val1, val = ir[0x083^1] + ir[0x4FA^1] + ir[0x5F7^1] + ir[0x47B^1];
506 val1 = iram_context_map[(val>>1)&0x3f];
509 printf("val: %02x PC=%04x\n", (val>>1)&0x3f, rPC);
510 //debug_dump2file(name, svp->iram_rom, 0x800);
513 // elprintf(EL_ANOMALY, "iram_context: %02i", val1);
518 #define PROGRAM(x) ((unsigned short *)svp->iram_rom)[x]
520 static void *translate_block(int pc)
522 unsigned int op, op1, icount = 0;
523 unsigned int *block_start;
526 *tcache_ptr++ = (u32) &g_cycles; // -3 g_cycles
527 *tcache_ptr++ = (u32) &ssp->gr[SSP_PC].v; // -2 ptr to rPC
528 *tcache_ptr++ = (u32) in_funcs; // -1 func pool
530 block_start = tcache_ptr;
532 emit_block_prologue();
534 //printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<1);
541 emit_mov_const16(0, op);
544 if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6) {
545 emit_mov_const16(1, PROGRAM(pc++)); // immediate
549 emit_pc_inc(block_start, pc);
551 emit_call(block_start, op1);
553 if (in_funcs[op1] == NULL) {
554 printf("NULL func! op=%08x (%02x)\n", op, op1);
557 if (op1 == 0x24 || op1 == 0x26 || // call, bra
558 ((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) &&
559 (op & 0xf0) == 0x60)) { // ld PC
564 emit_block_epilogue(block_start, icount + 1);
565 *tcache_ptr++ = 0xffffffff; // end of block
566 //printf(" %i inst\n", icount);
568 if (tcache_ptr - tcache > TCACHE_SIZE/4) {
569 printf("tcache overflow!\n");
577 printf("%i blocks, %i bytes\n", nblocks, (tcache_ptr - tcache)*4);
581 FILE *f = fopen("tcache.bin", "wb");
582 fwrite(tcache, 1, (tcache_ptr - tcache)*4, f);
592 // -----------------------------------------------------
594 int ssp1601_dyn_init(void)
596 tcache = tcache_ptr = malloc(TCACHE_SIZE);
597 if (tcache == NULL) {
601 memset(tcache, 0, sizeof(TCACHE_SIZE));
602 memset(block_table, 0, sizeof(block_table));
603 memset(block_table_iram, 0, sizeof(block_table_iram));
604 *tcache_ptr++ = 0xffffffff;
610 void ssp1601_dyn_reset(ssp1601_t *ssp)
612 ssp1601_reset_local(ssp);
615 static void handle_caches()
618 extern void flush_inval_dcache(const void *start_addr, const void *end_addr);
619 extern void flush_inval_icache(const void *start_addr, const void *end_addr);
620 flush_inval_dcache(tcache, tcache_ptr);
621 flush_inval_icache(tcache, tcache_ptr);
627 void ssp1601_dyn_run(int cycles)
631 void (*trans_entry)(void);
635 iram_context = get_iram_context();
638 if (block_table_iram[iram_context][rPC] == NULL)
639 block_table_iram[iram_context][rPC] = translate_block(rPC);
640 trans_entry = (void *) block_table_iram[iram_context][rPC];
644 if (block_table[rPC] == NULL)
645 block_table[rPC] = translate_block(rPC);
646 trans_entry = (void *) block_table[rPC];
651 //printf("enter @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1);
659 if (pc_old < 0x800/2)
660 rPC += (PC - block_table_iram[iram_context][pc_old]) - 1;
662 rPC += (PC - block_table[pc_old]) - 1;
665 //printf("end @ %04x, PC=%04x\n", (PC - tcache)<<1, rPC<<1);
667 if (pc_old < 0x400) {
669 tcache_ptr = block_table[pc_old];
670 block_table[pc_old] = NULL;
673 if (pc_old >= 0x400 && rPC < 0x400)
675 int i, crc = chksum_crc32(svp->iram_rom, 0x800);
676 for (i = 0; i < 32; i++)
677 if (iram_crcs[i] == crc) break;
680 for (i = 0; i < 32 && iram_crcs[i]; i++);
682 printf("%i IRAMs\n", i+1);
683 sprintf(name, "ir%08x.bin", crc);
684 debug_dump2file(name, svp->iram_rom, 0x800);
686 printf("CRC %08x %08x\n", crc, iram_id);
690 // debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 1);