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)
525 if (op == 0) return 1; // nop
530 EOP_ADD_IMM(0,7,1,30/2,(op&0x180)>>1); // add r1, r7, ((op&0x180)<<1)
531 EOP_LDRH_IMM(0,1,(op&0x7f)<<1); // ldr r0, [r1, (op&0x7f)<<1]
532 EOP_MOV_REG_LSL(5, 5, 16); // mov r5, r5, lsl #16 @ A
533 EOP_ORR_REG_SIMPLE(5, 0); // orr r5, r5, r0
534 EOP_MOV_REG_ROR(5,5,16); // mov r5, r5, ror #16
539 EOP_ADD_IMM(0,7,1,30/2,(op&0x180)>>1); // add r1, r7, ((op&0x180)<<1)
540 EOP_MOV_REG_LSR(0, 5, 16); // mov r0, r5, lsr #16 @ A
541 EOP_STRH_IMM(0,1,(op&0x7f)<<1); // str r0, [r1, (op&0x7f)<<1]
548 static void *translate_block(int pc)
550 unsigned int op, op1, imm, ccount = 0;
551 unsigned int *block_start;
555 //*tcache_ptr++ = (u32) in_funcs; // -1 func pool
557 printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
558 block_start = tcache_ptr;
560 emit_block_prologue();
562 for (; ccount < 100;)
564 //printf(" insn #%i\n", icount);
569 if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6)
570 imm = PROGRAM(pc++); // immediate
572 ret = translate_op(op, &pc);
575 emit_mov_const(0, op);
579 emit_mov_const(1, imm);
584 emit_interpreter_call(in_funcs[op1]);
586 if (in_funcs[op1] == NULL) {
587 printf("NULL func! op=%08x (%02x)\n", op, op1);
595 if (op1 == 0x24 || op1 == 0x26 || // call, bra
596 ((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) &&
597 (op & 0xf0) == 0x60)) { // ld PC
602 emit_block_epilogue(ccount + 1);
603 *tcache_ptr++ = 0xffffffff; // end of block
604 //printf(" %i inst\n", icount);
606 if (tcache_ptr - tcache > TCACHE_SIZE/4) {
607 printf("tcache overflow!\n");
615 printf("%i blocks, %i bytes\n", nblocks, (tcache_ptr - tcache)*4);
616 //printf("%p %p\n", tcache_ptr, emit_block_epilogue);
620 FILE *f = fopen("tcache.bin", "wb");
621 fwrite(tcache, 1, (tcache_ptr - tcache)*4, f);
634 // -----------------------------------------------------
636 int ssp1601_dyn_startup(void)
638 memset(tcache, 0, TCACHE_SIZE);
639 memset(block_table, 0, sizeof(block_table));
640 memset(block_table_iram, 0, sizeof(block_table_iram));
642 *tcache_ptr++ = 0xffffffff;
648 void ssp1601_dyn_reset(ssp1601_t *ssp)
650 ssp1601_reset_local(ssp);
653 void ssp1601_dyn_run(int cycles)
658 int (*trans_entry)(void);
662 iram_context = get_iram_context();
665 if (block_table_iram[iram_context][rPC] == NULL)
666 block_table_iram[iram_context][rPC] = translate_block(rPC);
667 trans_entry = (void *) block_table_iram[iram_context][rPC];
671 if (block_table[rPC] == NULL)
672 block_table[rPC] = translate_block(rPC);
673 trans_entry = (void *) block_table[rPC];
678 //printf("enter %04x\n", rPC<<1);
679 cycles -= trans_entry();
680 //printf("leave %04x\n", rPC<<1);
682 // debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 1);