1 // 187 blocks, 12072 bytes
4 #include "../../PicoInt.h"
7 static unsigned int *block_table[0x5090/2];
8 static unsigned int *block_table_iram[15][0x800/2];
9 static unsigned int *tcache_ptr = NULL;
11 static int had_jump = 0;
12 static int nblocks = 0;
13 static int iram_context = 0;
15 #define EMBED_INTERPRETER
16 #define ssp1601_reset ssp1601_reset_local
17 #define ssp1601_run ssp1601_run_local
20 #define GET_PPC_OFFS() (GET_PC()*2 - 2)
21 #define SET_PC(d) { had_jump = 1; rPC = d; } /* must return to dispatcher after this */
22 //#define GET_PC() (PC - (unsigned short *)svp->iram_rom)
23 //#define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2)
24 //#define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d
29 // -----------------------------------------------------
32 static void op00(unsigned int op, unsigned int imm)
35 PC = ((unsigned short *)(void *)&op) + 1; /* FIXME: needed for interpreter */
36 if (op == 0) return; // nop
37 if (op == ((SSP_A<<4)|SSP_P)) { // A <- P
38 // not sure. MAME claims that only hi word is transfered.
44 tmpv = REG_READ(op & 0x0f);
45 REG_WRITE((op & 0xf0) >> 4, tmpv);
50 static void op01(unsigned int op, unsigned int imm)
53 tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv);
57 static void op02(unsigned int op, unsigned int imm)
60 tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv);
64 static void op04(unsigned int op, unsigned int imm)
66 REG_WRITE((op & 0xf0) >> 4, imm);
70 static void op05(unsigned int op, unsigned int imm)
73 tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv);
77 static void op06(unsigned int op, unsigned int imm)
83 static void op07(unsigned int op, unsigned int imm)
85 ssp->RAM[op & 0x1ff] = rA;
89 static void op09(unsigned int op, unsigned int imm)
92 tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv);
96 static void op0a(unsigned int op, unsigned int imm)
98 rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4);
101 // ldi ri, simm (also op0d op0e op0f)
102 static void op0c(unsigned int op, unsigned int imm)
108 static void op24(unsigned int op, unsigned int imm)
113 if (cond) { int new_PC = imm; write_STACK(GET_PC()); SET_PC(new_PC); }
119 static void op25(unsigned int op, unsigned int imm)
122 tmpv = ((unsigned short *)svp->iram_rom)[rA]; REG_WRITE((op & 0xf0) >> 4, tmpv);
126 static void op26(unsigned int op, unsigned int imm)
132 if (cond) SET_PC(imm);
138 static void op48(unsigned int op, unsigned int imm)
146 case 2: rA32 = (signed int)rA32 >> 1; break; // shr (arithmetic)
147 case 3: rA32 <<= 1; break; // shl
148 case 6: rA32 = -(signed int)rA32; break; // neg
149 case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; // abs
150 default: elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x",
151 op&7, GET_PPC_OFFS());
160 static void op1b(unsigned int op, unsigned int imm)
162 read_P(); // update P
163 rA32 -= rP.v; // maybe only upper word?
164 UPD_ACC_ZN // there checking flags after this
165 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
166 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
169 // mpya (rj), (ri), b
170 static void op4b(unsigned int op, unsigned int imm)
172 read_P(); // update P
173 rA32 += rP.v; // confirmed to be 32bit
175 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
176 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
180 static void op5b(unsigned int op, unsigned int imm)
184 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
185 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
189 static void op10(unsigned int op, unsigned int imm)
194 OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv);
199 static void op30(unsigned int op, unsigned int imm)
204 OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv);
209 static void op40(unsigned int op, unsigned int imm)
214 OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv);
219 static void op50(unsigned int op, unsigned int imm)
224 OP_CHECK32(OP_ANDA32); tmpv = REG_READ(op & 0x0f); OP_ANDA(tmpv);
229 static void op60(unsigned int op, unsigned int imm)
234 OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv);
239 static void op70(unsigned int op, unsigned int imm)
244 OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv);
250 static void op11(unsigned int op, unsigned int imm)
253 tmpv = ptr1_read(op); OP_SUBA(tmpv);
256 static void op31(unsigned int op, unsigned int imm)
259 tmpv = ptr1_read(op); OP_CMPA(tmpv);
262 static void op41(unsigned int op, unsigned int imm)
265 tmpv = ptr1_read(op); OP_ADDA(tmpv);
268 static void op51(unsigned int op, unsigned int imm)
271 tmpv = ptr1_read(op); OP_ANDA(tmpv);
274 static void op61(unsigned int op, unsigned int imm)
277 tmpv = ptr1_read(op); OP_ORA (tmpv);
280 static void op71(unsigned int op, unsigned int imm)
283 tmpv = ptr1_read(op); OP_EORA(tmpv);
287 static void op03(unsigned int op, unsigned int imm)
290 tmpv = ssp->RAM[op & 0x1ff]; OP_LDA (tmpv);
293 static void op13(unsigned int op, unsigned int imm)
296 tmpv = ssp->RAM[op & 0x1ff]; OP_SUBA(tmpv);
299 static void op33(unsigned int op, unsigned int imm)
302 tmpv = ssp->RAM[op & 0x1ff]; OP_CMPA(tmpv);
305 static void op43(unsigned int op, unsigned int imm)
308 tmpv = ssp->RAM[op & 0x1ff]; OP_ADDA(tmpv);
311 static void op53(unsigned int op, unsigned int imm)
314 tmpv = ssp->RAM[op & 0x1ff]; OP_ANDA(tmpv);
317 static void op63(unsigned int op, unsigned int imm)
320 tmpv = ssp->RAM[op & 0x1ff]; OP_ORA (tmpv);
323 static void op73(unsigned int op, unsigned int imm)
326 tmpv = ssp->RAM[op & 0x1ff]; OP_EORA(tmpv);
330 static void op14(unsigned int op, unsigned int imm)
335 static void op34(unsigned int op, unsigned int imm)
340 static void op44(unsigned int op, unsigned int imm)
345 static void op54(unsigned int op, unsigned int imm)
350 static void op64(unsigned int op, unsigned int imm)
355 static void op74(unsigned int op, unsigned int imm)
361 static void op15(unsigned int op, unsigned int imm)
364 tmpv = ptr2_read(op); OP_SUBA(tmpv);
367 static void op35(unsigned int op, unsigned int imm)
370 tmpv = ptr2_read(op); OP_CMPA(tmpv);
373 static void op45(unsigned int op, unsigned int imm)
376 tmpv = ptr2_read(op); OP_ADDA(tmpv);
379 static void op55(unsigned int op, unsigned int imm)
382 tmpv = ptr2_read(op); OP_ANDA(tmpv);
385 static void op65(unsigned int op, unsigned int imm)
388 tmpv = ptr2_read(op); OP_ORA (tmpv);
391 static void op75(unsigned int op, unsigned int imm)
394 tmpv = ptr2_read(op); OP_EORA(tmpv);
398 static void op19(unsigned int op, unsigned int imm)
401 tmpv = rIJ[IJind]; OP_SUBA(tmpv);
404 static void op39(unsigned int op, unsigned int imm)
407 tmpv = rIJ[IJind]; OP_CMPA(tmpv);
410 static void op49(unsigned int op, unsigned int imm)
413 tmpv = rIJ[IJind]; OP_ADDA(tmpv);
416 static void op59(unsigned int op, unsigned int imm)
419 tmpv = rIJ[IJind]; OP_ANDA(tmpv);
422 static void op69(unsigned int op, unsigned int imm)
425 tmpv = rIJ[IJind]; OP_ORA (tmpv);
428 static void op79(unsigned int op, unsigned int imm)
431 tmpv = rIJ[IJind]; OP_EORA(tmpv);
435 static void op1c(unsigned int op, unsigned int imm)
440 static void op3c(unsigned int op, unsigned int imm)
445 static void op4c(unsigned int op, unsigned int imm)
450 static void op5c(unsigned int op, unsigned int imm)
455 static void op6c(unsigned int op, unsigned int imm)
460 static void op7c(unsigned int op, unsigned int imm)
465 typedef void (in_func)(unsigned int op, unsigned int imm);
467 static in_func *in_funcs[0x80] =
469 op00, op01, op02, op03, op04, op05, op06, op07,
470 NULL, op09, op0a, NULL, op0c, op0c, op0c, op0c,
471 op10, op11, NULL, op13, op14, op15, NULL, NULL,
472 NULL, op19, NULL, op1b, op1c, NULL, NULL, NULL,
473 NULL, NULL, NULL, NULL, op24, op25, op26, NULL,
474 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
475 op30, op31, NULL, op33, op34, op35, NULL, NULL,
476 NULL, op39, NULL, NULL, op3c, NULL, NULL, NULL,
477 op40, op41, NULL, op43, op44, op45, NULL, NULL,
478 op48, op49, NULL, op4b, op4c, NULL, NULL, NULL,
479 op50, op51, NULL, op53, op54, op55, NULL, NULL,
480 NULL, op59, NULL, op5b, op5c, NULL, NULL, NULL,
481 op60, op61, NULL, op63, op64, op65, NULL, NULL,
482 NULL, op69, NULL, NULL, op6c, NULL, NULL, NULL,
483 op70, op71, NULL, op73, op74, op75, NULL, NULL,
484 NULL, op79, NULL, NULL, op7c, NULL, NULL, NULL,
487 // -----------------------------------------------------
489 static unsigned char iram_context_map[] =
491 0, 0, 0, 0, 1, 0, 0, 0, // 04
492 0, 0, 0, 0, 0, 0, 2, 0, // 0e
493 0, 0, 0, 0, 0, 3, 0, 4, // 15 17
494 5, 0, 0, 6, 0, 7, 0, 0, // 18 1b 1d
495 8, 9, 0, 0, 0,10, 0, 0, // 20 21 25
496 0, 0, 0, 0, 0, 0, 0, 0,
497 0, 0,11, 0, 0,12, 0, 0, // 32 35
498 13,14, 0, 0, 0, 0, 0, 0 // 38 39
501 static int get_iram_context(void)
503 unsigned char *ir = (unsigned char *)svp->iram_rom;
504 int val1, val = ir[0x083^1] + ir[0x4FA^1] + ir[0x5F7^1] + ir[0x47B^1];
505 val1 = iram_context_map[(val>>1)&0x3f];
508 printf("val: %02x PC=%04x\n", (val>>1)&0x3f, rPC);
509 //debug_dump2file(name, svp->iram_rom, 0x800);
512 // elprintf(EL_ANOMALY, "iram_context: %02i", val1);
517 #define PROGRAM(x) ((unsigned short *)svp->iram_rom)[x]
519 static int translate_op(unsigned int op, int *pc)
530 static void *translate_block(int pc)
532 unsigned int op, op1, imm, ccount = 0;
533 unsigned int *block_start;
537 //*tcache_ptr++ = (u32) in_funcs; // -1 func pool
539 printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
540 block_start = tcache_ptr;
542 emit_block_prologue();
544 for (; ccount < 100;)
546 //printf(" insn #%i\n", icount);
551 if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6)
552 imm = PROGRAM(pc++); // immediate
554 ret = translate_op(op, &pc);
557 emit_mov_const(0, op);
561 emit_mov_const(1, imm);
566 emit_interpreter_call(in_funcs[op1]);
568 if (in_funcs[op1] == NULL) {
569 printf("NULL func! op=%08x (%02x)\n", op, op1);
577 if (op1 == 0x24 || op1 == 0x26 || // call, bra
578 ((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) &&
579 (op & 0xf0) == 0x60)) { // ld PC
584 emit_block_epilogue(ccount + 1);
585 *tcache_ptr++ = 0xffffffff; // end of block
586 //printf(" %i inst\n", icount);
588 if (tcache_ptr - tcache > TCACHE_SIZE/4) {
589 printf("tcache overflow!\n");
597 printf("%i blocks, %i bytes\n", nblocks, (tcache_ptr - tcache)*4);
598 //printf("%p %p\n", tcache_ptr, emit_block_epilogue);
602 FILE *f = fopen("tcache.bin", "wb");
603 fwrite(tcache, 1, (tcache_ptr - tcache)*4, f);
616 // -----------------------------------------------------
618 int ssp1601_dyn_startup(void)
620 memset(tcache, 0, TCACHE_SIZE);
621 memset(block_table, 0, sizeof(block_table));
622 memset(block_table_iram, 0, sizeof(block_table_iram));
624 *tcache_ptr++ = 0xffffffff;
630 void ssp1601_dyn_reset(ssp1601_t *ssp)
632 ssp1601_reset_local(ssp);
635 void ssp1601_dyn_run(int cycles)
639 int (*trans_entry)(void);
643 iram_context = get_iram_context();
646 if (block_table_iram[iram_context][rPC] == NULL)
647 block_table_iram[iram_context][rPC] = translate_block(rPC);
648 trans_entry = (void *) block_table_iram[iram_context][rPC];
652 if (block_table[rPC] == NULL)
653 block_table[rPC] = translate_block(rPC);
654 trans_entry = (void *) block_table[rPC];
659 //printf("enter %04x\n", rPC<<1);
660 cycles -= trans_entry();
661 //printf("leave %04x\n", rPC<<1);
663 // debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 1);