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;
16 #define DUMP_BLOCK 0x84a
17 unsigned int tcache[512*1024];
18 void regfile_load(void){}
19 void regfile_store(void){}
22 #define EMBED_INTERPRETER
23 #define ssp1601_reset ssp1601_reset_local
24 #define ssp1601_run ssp1601_run_local
27 #define GET_PPC_OFFS() (GET_PC()*2 - 2)
28 #define SET_PC(d) { had_jump = 1; rPC = d; } /* must return to dispatcher after this */
29 //#define GET_PC() (PC - (unsigned short *)svp->iram_rom)
30 //#define GET_PPC_OFFS() ((unsigned int)PC - (unsigned int)svp->iram_rom - 2)
31 //#define SET_PC(d) PC = (unsigned short *)svp->iram_rom + d
36 // -----------------------------------------------------
39 static void op00(unsigned int op, unsigned int imm)
42 PC = ((unsigned short *)(void *)&op) + 1; /* FIXME: needed for interpreter */
43 if (op == 0) return; // nop
44 if (op == ((SSP_A<<4)|SSP_P)) { // A <- P
45 // not sure. MAME claims that only hi word is transfered.
51 tmpv = REG_READ(op & 0x0f);
52 REG_WRITE((op & 0xf0) >> 4, tmpv);
57 static void op01(unsigned int op, unsigned int imm)
60 tmpv = ptr1_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv);
64 static void op02(unsigned int op, unsigned int imm)
67 tmpv = REG_READ((op & 0xf0) >> 4); ptr1_write(op, tmpv);
71 static void op04(unsigned int op, unsigned int imm)
73 REG_WRITE((op & 0xf0) >> 4, imm);
77 static void op05(unsigned int op, unsigned int imm)
80 tmpv = ptr2_read(op); REG_WRITE((op & 0xf0) >> 4, tmpv);
84 static void op06(unsigned int op, unsigned int imm)
90 static void op07(unsigned int op, unsigned int imm)
92 ssp->RAM[op & 0x1ff] = rA;
96 static void op09(unsigned int op, unsigned int imm)
99 tmpv = rIJ[(op&3)|((op>>6)&4)]; REG_WRITE((op & 0xf0) >> 4, tmpv);
103 static void op0a(unsigned int op, unsigned int imm)
105 rIJ[(op&3)|((op>>6)&4)] = REG_READ((op & 0xf0) >> 4);
108 // ldi ri, simm (also op0d op0e op0f)
109 static void op0c(unsigned int op, unsigned int imm)
115 static void op24(unsigned int op, unsigned int imm)
120 if (cond) { int new_PC = imm; write_STACK(GET_PC()); SET_PC(new_PC); }
126 static void op25(unsigned int op, unsigned int imm)
129 tmpv = ((unsigned short *)svp->iram_rom)[rA]; REG_WRITE((op & 0xf0) >> 4, tmpv);
133 static void op26(unsigned int op, unsigned int imm)
139 if (cond) SET_PC(imm);
145 static void op48(unsigned int op, unsigned int imm)
153 case 2: rA32 = (signed int)rA32 >> 1; break; // shr (arithmetic)
154 case 3: rA32 <<= 1; break; // shl
155 case 6: rA32 = -(signed int)rA32; break; // neg
156 case 7: if ((int)rA32 < 0) rA32 = -(signed int)rA32; break; // abs
157 default: elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: unhandled mod %i @ %04x",
158 op&7, GET_PPC_OFFS());
167 static void op1b(unsigned int op, unsigned int imm)
169 read_P(); // update P
170 rA32 -= rP.v; // maybe only upper word?
171 UPD_ACC_ZN // there checking flags after this
172 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
173 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
176 // mpya (rj), (ri), b
177 static void op4b(unsigned int op, unsigned int imm)
179 read_P(); // update P
180 rA32 += rP.v; // confirmed to be 32bit
182 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
183 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
187 static void op5b(unsigned int op, unsigned int imm)
191 rX = ptr1_read_(op&3, 0, (op<<1)&0x18); // ri (maybe rj?)
192 rY = ptr1_read_((op>>4)&3, 4, (op>>3)&0x18); // rj
196 static void op10(unsigned int op, unsigned int imm)
201 OP_CHECK32(OP_SUBA32); tmpv = REG_READ(op & 0x0f); OP_SUBA(tmpv);
206 static void op30(unsigned int op, unsigned int imm)
211 OP_CHECK32(OP_CMPA32); tmpv = REG_READ(op & 0x0f); OP_CMPA(tmpv);
216 static void op40(unsigned int op, unsigned int imm)
221 OP_CHECK32(OP_ADDA32); tmpv = REG_READ(op & 0x0f); OP_ADDA(tmpv);
226 static void op50(unsigned int op, unsigned int imm)
231 OP_CHECK32(OP_ANDA32); tmpv = REG_READ(op & 0x0f); OP_ANDA(tmpv);
236 static void op60(unsigned int op, unsigned int imm)
241 OP_CHECK32(OP_ORA32 ); tmpv = REG_READ(op & 0x0f); OP_ORA (tmpv);
246 static void op70(unsigned int op, unsigned int imm)
251 OP_CHECK32(OP_EORA32); tmpv = REG_READ(op & 0x0f); OP_EORA(tmpv);
257 static void op11(unsigned int op, unsigned int imm)
260 tmpv = ptr1_read(op); OP_SUBA(tmpv);
263 static void op31(unsigned int op, unsigned int imm)
266 tmpv = ptr1_read(op); OP_CMPA(tmpv);
269 static void op41(unsigned int op, unsigned int imm)
272 tmpv = ptr1_read(op); OP_ADDA(tmpv);
275 static void op51(unsigned int op, unsigned int imm)
278 tmpv = ptr1_read(op); OP_ANDA(tmpv);
281 static void op61(unsigned int op, unsigned int imm)
284 tmpv = ptr1_read(op); OP_ORA (tmpv);
287 static void op71(unsigned int op, unsigned int imm)
290 tmpv = ptr1_read(op); OP_EORA(tmpv);
294 static void op03(unsigned int op, unsigned int imm)
297 tmpv = ssp->RAM[op & 0x1ff]; OP_LDA (tmpv);
300 static void op13(unsigned int op, unsigned int imm)
303 tmpv = ssp->RAM[op & 0x1ff]; OP_SUBA(tmpv);
306 static void op33(unsigned int op, unsigned int imm)
309 tmpv = ssp->RAM[op & 0x1ff]; OP_CMPA(tmpv);
312 static void op43(unsigned int op, unsigned int imm)
315 tmpv = ssp->RAM[op & 0x1ff]; OP_ADDA(tmpv);
318 static void op53(unsigned int op, unsigned int imm)
321 tmpv = ssp->RAM[op & 0x1ff]; OP_ANDA(tmpv);
324 static void op63(unsigned int op, unsigned int imm)
327 tmpv = ssp->RAM[op & 0x1ff]; OP_ORA (tmpv);
330 static void op73(unsigned int op, unsigned int imm)
333 tmpv = ssp->RAM[op & 0x1ff]; OP_EORA(tmpv);
337 static void op14(unsigned int op, unsigned int imm)
342 static void op34(unsigned int op, unsigned int imm)
347 static void op44(unsigned int op, unsigned int imm)
352 static void op54(unsigned int op, unsigned int imm)
357 static void op64(unsigned int op, unsigned int imm)
362 static void op74(unsigned int op, unsigned int imm)
368 static void op15(unsigned int op, unsigned int imm)
371 tmpv = ptr2_read(op); OP_SUBA(tmpv);
374 static void op35(unsigned int op, unsigned int imm)
377 tmpv = ptr2_read(op); OP_CMPA(tmpv);
380 static void op45(unsigned int op, unsigned int imm)
383 tmpv = ptr2_read(op); OP_ADDA(tmpv);
386 static void op55(unsigned int op, unsigned int imm)
389 tmpv = ptr2_read(op); OP_ANDA(tmpv);
392 static void op65(unsigned int op, unsigned int imm)
395 tmpv = ptr2_read(op); OP_ORA (tmpv);
398 static void op75(unsigned int op, unsigned int imm)
401 tmpv = ptr2_read(op); OP_EORA(tmpv);
405 static void op19(unsigned int op, unsigned int imm)
408 tmpv = rIJ[IJind]; OP_SUBA(tmpv);
411 static void op39(unsigned int op, unsigned int imm)
414 tmpv = rIJ[IJind]; OP_CMPA(tmpv);
417 static void op49(unsigned int op, unsigned int imm)
420 tmpv = rIJ[IJind]; OP_ADDA(tmpv);
423 static void op59(unsigned int op, unsigned int imm)
426 tmpv = rIJ[IJind]; OP_ANDA(tmpv);
429 static void op69(unsigned int op, unsigned int imm)
432 tmpv = rIJ[IJind]; OP_ORA (tmpv);
435 static void op79(unsigned int op, unsigned int imm)
438 tmpv = rIJ[IJind]; OP_EORA(tmpv);
442 static void op1c(unsigned int op, unsigned int imm)
447 static void op3c(unsigned int op, unsigned int imm)
452 static void op4c(unsigned int op, unsigned int imm)
457 static void op5c(unsigned int op, unsigned int imm)
462 static void op6c(unsigned int op, unsigned int imm)
467 static void op7c(unsigned int op, unsigned int imm)
472 typedef void (in_func)(unsigned int op, unsigned int imm);
474 static in_func *in_funcs[0x80] =
476 op00, op01, op02, op03, op04, op05, op06, op07,
477 NULL, op09, op0a, NULL, op0c, op0c, op0c, op0c,
478 op10, op11, NULL, op13, op14, op15, NULL, NULL,
479 NULL, op19, NULL, op1b, op1c, NULL, NULL, NULL,
480 NULL, NULL, NULL, NULL, op24, op25, op26, NULL,
481 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
482 op30, op31, NULL, op33, op34, op35, NULL, NULL,
483 NULL, op39, NULL, NULL, op3c, NULL, NULL, NULL,
484 op40, op41, NULL, op43, op44, op45, NULL, NULL,
485 op48, op49, NULL, op4b, op4c, NULL, NULL, NULL,
486 op50, op51, NULL, op53, op54, op55, NULL, NULL,
487 NULL, op59, NULL, op5b, op5c, NULL, NULL, NULL,
488 op60, op61, NULL, op63, op64, op65, NULL, NULL,
489 NULL, op69, NULL, NULL, op6c, NULL, NULL, NULL,
490 op70, op71, NULL, op73, op74, op75, NULL, NULL,
491 NULL, op79, NULL, NULL, op7c, NULL, NULL, NULL,
494 // -----------------------------------------------------
496 static unsigned char iram_context_map[] =
498 0, 0, 0, 0, 1, 0, 0, 0, // 04
499 0, 0, 0, 0, 0, 0, 2, 0, // 0e
500 0, 0, 0, 0, 0, 3, 0, 4, // 15 17
501 5, 0, 0, 6, 0, 7, 0, 0, // 18 1b 1d
502 8, 9, 0, 0, 0,10, 0, 0, // 20 21 25
503 0, 0, 0, 0, 0, 0, 0, 0,
504 0, 0,11, 0, 0,12, 0, 0, // 32 35
505 13,14, 0, 0, 0, 0, 0, 0 // 38 39
508 static int get_iram_context(void)
510 unsigned char *ir = (unsigned char *)svp->iram_rom;
511 int val1, val = ir[0x083^1] + ir[0x4FA^1] + ir[0x5F7^1] + ir[0x47B^1];
512 val1 = iram_context_map[(val>>1)&0x3f];
515 printf("val: %02x PC=%04x\n", (val>>1)&0x3f, rPC);
516 //debug_dump2file(name, svp->iram_rom, 0x800);
519 // elprintf(EL_ANOMALY, "iram_context: %02i", val1);
523 // -----------------------------------------------------
526 SSP_GR0, SSP_X, SSP_Y, SSP_A,
527 SSP_ST, SSP_STACK, SSP_PC, SSP_P,
528 SSP_PM0, SSP_PM1, SSP_PM2, SSP_XST,
529 SSP_PM4, SSP_gr13, SSP_PMC, SSP_AL
532 /* regs with known values */
539 #define CRREG_X (1 << SSP_X)
540 #define CRREG_Y (1 << SSP_Y)
541 #define CRREG_A (1 << SSP_A) /* AH only */
542 #define CRREG_ST (1 << SSP_ST)
543 #define CRREG_STACK (1 << SSP_STACK)
544 #define CRREG_PC (1 << SSP_PC)
545 #define CRREG_P (1 << SSP_P)
546 #define CRREG_PR0 (1 << 8)
547 #define CRREG_PR4 (1 << 12)
548 #define CRREG_AL (1 << 16)
550 static u32 const_regb = 0; /* bitfield of known register values */
551 static u32 dirty_regb = 0; /* known vals, which need to be flushed (only r0-r7) */
553 /* known values of host regs.
555 * 00000-0ffff - 16bit value
556 * 10000-1ffff - base reg (r7) + 16bit val
557 * 20000 - means reg (low) eq AH
559 static int hostreg_r[4];
561 static void hostreg_clear(void)
564 for (i = 0; i < 4; i++)
568 /*static*/ void hostreg_ah_changed(void)
571 for (i = 0; i < 4; i++)
572 if (hostreg_r[i] == 0x20000) hostreg_r[i] = -1;
576 #define PROGRAM(x) ((unsigned short *)svp->iram_rom)[x]
578 /* load 16bit val into host reg r0-r3. Nothing is trashed */
579 static void tr_mov16(int r, int val)
581 if (hostreg_r[r] != val) {
582 emit_mov_const(r, val);
587 /* write dirty r0-r7 to host regs. Nothing is trashed */
588 static void tr_flush_dirty(void)
593 for (i = 0; dirty_regb && i < 8; i++, dirty_regb >>= 1)
595 if (!(dirty_regb&1)) continue;
597 case 0: ror = 0; break;
598 case 1: ror = 24/2; break;
599 case 2: ror = 16/2; break;
601 reg = (i < 4) ? 8 : 9;
602 EOP_BIC_IMM(reg,reg,ror,0xff);
603 if (const_regs.r[i] != 0)
604 EOP_ORR_IMM(reg,reg,ror,const_regs.r[i]);
608 /* read bank word to r0 (MSW may contain trash). Thrashes r1. */
609 static void tr_bank_read(int addr) /* word addr 0-0x1ff */
614 if (hostreg_r[1] != (0x10000|((addr&0x180)<<1))) {
615 EOP_ADD_IMM(1,7,30/2,(addr&0x180)>>1); // add r1, r7, ((op&0x180)<<1)
616 hostreg_r[1] = 0x10000|((addr&0x180)<<1);
620 EOP_LDRH_IMM(0,breg,(addr&0x7f)<<1); // ldrh r0, [r1, (op&0x7f)<<1]
622 EOP_LDR_IMM(0,7,(addr&0x1ff)<<1); // ldr r0, [r1, (op&0x1ff)<<1]
627 /* write r0 to bank. Trashes r1. */
628 static void tr_bank_write(int addr)
632 if (hostreg_r[1] != (0x10000|((addr&0x180)<<1))) {
633 EOP_ADD_IMM(1,7,30/2,(addr&0x180)>>1); // add r1, r7, ((op&0x180)<<1)
634 hostreg_r[1] = 0x10000|((addr&0x180)<<1);
638 EOP_STRH_IMM(0,breg,(addr&0x7f)<<1); // strh r0, [r1, (op&0x7f)<<1]
641 /* handle RAM bank pointer modifiers. Nothing is trashed. */
642 static void tr_ptrr_mod(int r, int mod, int need_modulo)
644 int modulo = -1, modulo_shift = -1; /* unknown */
646 if (mod == 0) return;
648 if (!need_modulo || mod == 1) // +!
650 else if (need_modulo && (const_regb & CRREG_ST)) {
651 modulo_shift = const_regs.gr[SSP_ST].h & 7;
652 if (modulo_shift == 0) modulo_shift = 8;
655 if (mod > 1 && modulo_shift == -1) { printf("need var modulo\n"); exit(1); }
656 modulo = (1 << modulo_shift) - 1;
658 if (const_regb & (1 << (r + 8))) {
660 const_regs.r[r] = (const_regs.r[r] & ~modulo) | ((const_regs.r[r] - 1) & modulo);
661 else const_regs.r[r] = (const_regs.r[r] & ~modulo) | ((const_regs.r[r] + 1) & modulo);
663 int reg = (r < 4) ? 8 : 9;
664 int ror = ((r&3) + 1)*8 - (8 - modulo_shift);
665 EOP_MOV_REG_ROR(reg,reg,ror);
666 // {add|sub} reg, reg, #1<<shift
667 EOP_C_DOP_IMM(A_COND_AL,(mod==2)?A_OP_SUB:A_OP_ADD,0,reg,reg, 8/2, 1<<(8 - modulo_shift));
668 EOP_MOV_REG_ROR(reg,reg,32-ror);
672 // SSP_GR0, SSP_X, SSP_Y, SSP_A,
673 // SSP_ST, SSP_STACK, SSP_PC, SSP_P,
676 //@ r6: STACK and emu flags
680 // write r0 to general reg handlers. Trashes r1
681 static void tr_r0_unhandled(void)
683 printf("unhandled\n");
687 static void tr_r0_to_GR0(void)
692 static void tr_r0_to_X(void)
694 EOP_MOV_REG_LSL(4, 4, 16); // mov r4, r4, lsl #16
695 EOP_MOV_REG_LSR(4, 4, 16); // mov r4, r4, lsr #16
696 EOP_ORR_REG_LSL(4, 4, 0, 16); // orr r4, r4, r0, lsl #16
699 static void tr_r0_to_Y(void)
701 EOP_MOV_REG_LSR(4, 4, 16); // mov r4, r4, lsr #16
702 EOP_ORR_REG_LSL(4, 4, 0, 16); // orr r4, r4, r0, lsl #16
703 EOP_MOV_REG_ROR(4, 4, 16); // mov r4, r4, ror #16
706 static void tr_r0_to_A(void)
708 EOP_MOV_REG_LSL(5, 5, 16); // mov r5, r5, lsl #16
709 EOP_MOV_REG_LSR(5, 5, 16); // mov r5, r5, lsl #16 @ AL
710 EOP_ORR_REG_LSL(5, 5, 0, 16); // orr r5, r5, r0, lsl #16
711 hostreg_r[0] = 0x20000;
714 static void tr_r0_to_ST(void)
716 // VR doesn't need much accuracy here..
717 EOP_AND_IMM(1, 0, 0, 0x67); // and r1, r0, #0x67
718 EOP_AND_IMM(6, 6, 8/2, 0xe0); // and r6, r6, #7<<29 @ preserve STACK
719 EOP_ORR_REG_LSL(6, 6, 1, 4); // orr r6, r6, r1, lsl #4
723 static void tr_r0_to_STACK(void)
726 EOP_ADD_IMM(1, 7, 24/2, 0x04); // add r1, r7, 0x400
727 EOP_ADD_IMM(1, 1, 0, 0x48); // add r1, r1, 0x048
728 EOP_ADD_REG_LSR(1, 1, 6, 28); // add r1, r1, r6, lsr #26
729 EOP_STRH_SIMPLE(0, 1); // strh r0, [r1]
730 EOP_ADD_IMM(6, 6, 24/2, 0x20); // add r6, r6, #1<<29
734 static void tr_r0_to_PC(void)
736 EOP_MOV_REG_LSL(1, 0, 16); // mov r1, r0, lsl #16
737 EOP_STR_IMM(0,7,0x400+6*4); // str r0, [r7, #(0x400+6*8)]
741 typedef void (tr_write_func)(void);
743 static tr_write_func *tr_write_funcs[8] =
756 static int translate_op(unsigned int op, int *pc, int imm)
765 if (op == 0) { ret++; break; } // nop
770 tr_bank_read(op&0x1ff);
772 const_regb &= ~CRREG_A;
773 hostreg_r[0] = 0x20000;
778 tmpv = (op & 0xf0) >> 4;
782 tr_write_funcs[tmpv]();
783 const_regs.gr[tmpv].h = imm;
784 const_regb |= 1 << tmpv;
787 else if (tmpv == 0xe && (PROGRAM(*pc) >> 9) == 4)
791 tmpv = imm | (PROGRAM((*pc)++) << 16);
792 emit_mov_const(0, tmpv);
793 EOP_LDR_IMM(1,7,0x484); // ldr r0, [r7, #0x484] // emu_status
794 EOP_STR_IMM(0,7,0x400+14*4); // PMC
795 // TODO: do this only on reads
796 if (tmpv == 0x187f04) { // fe08
797 EOP_LDR_IMM(0,7,0x490); // dram_ptr
798 EOP_ADD_IMM(0,0,24/2,0xfe); // add r0, r0, #0xfe00
799 EOP_LDRH_IMM(0,0,8); // ldrh r0, [r0, #8]
800 EOP_TST_REG_SIMPLE(0,0);
801 EOP_C_DOP_IMM(A_COND_EQ,A_OP_ADD,0,11,11,22/2,1); // add r11, r11, #1024
802 EOP_C_DOP_IMM(A_COND_EQ,A_OP_ORR,0, 1, 1,24/2,SSP_WAIT_30FE08>>8); // orr r1, r1, #SSP_WAIT_30FE08
804 EOP_ORR_IMM(1,1,0,SSP_PMC_SET); // orr r1, r1, #SSP_PMC_SET
805 EOP_STR_IMM(1,7,0x484); // str r1, [r7, #0x484] // emu_status
806 hostreg_r[0] = hostreg_r[1] = -1;
810 return -1; /* TODO.. */
815 // int t = (op&3) | ((op>>6)&4) | ((op<<1)&0x18);
819 tmpv = (op>>2) & 3; // direct addressing
821 if (hostreg_r[1] != 0x10200) {
822 EOP_ADD_IMM(1,7,30/2,0x200>>2); // add r1, r7, 0x200
823 hostreg_r[1] = 0x10200;
825 EOP_STRH_IMM(0,1,tmpv<<1); // str r0, [r1, {0,2,4,6}]
827 EOP_STRH_IMM(0,7,tmpv<<1); // str r0, [r7, {0,2,4,6}]
832 int r = (op&3) | ((op>>6)&4);
833 if (const_regb & (1 << (r + 8))) {
834 tr_bank_write(const_regs.r[r] | ((r < 4) ? 0 : 0x100));
836 int reg = (r < 4) ? 8 : 9;
837 int ror = ((4 - (r&3))*8) & 0x1f;
838 EOP_AND_IMM(1,reg,ror/2,0xff); // and r1, r{7,8}, <mask>
840 EOP_ORR_IMM(1,1,((ror-8)&0x1f)/2,1); // orr r1, r1, 1<<shift
841 if (r&3) EOP_ADD_REG_LSR(1,7,1, (r&3)*8-1); // add r1, r7, r1, lsr #lsr
842 else EOP_ADD_REG_LSL(1,7,1,1);
843 EOP_STRH_SIMPLE(0,1); // strh r0, [r1]
846 tr_ptrr_mod(r, (op>>2) & 3, 0);
852 if (hostreg_r[0] != 0x20000) {
853 EOP_MOV_REG_LSR(0, 5, 16); // mov r0, r5, lsr #16 @ A
854 hostreg_r[0] = 0x20000;
856 tr_bank_write(op&0x1ff);
862 const_regs.r[tmpv] = op;
863 const_regb |= 1 << (tmpv + 8);
864 dirty_regb |= 1 << (tmpv + 8);
871 static void *translate_block(int pc)
873 unsigned int op, op1, imm, ccount = 0;
874 unsigned int *block_start;
878 //*tcache_ptr++ = (u32) in_funcs; // -1 func pool
880 printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
881 block_start = tcache_ptr;
882 const_regb = dirty_regb = 0;
885 emit_block_prologue();
887 for (; ccount < 100;)
889 //printf(" insn #%i\n", icount);
894 if ((op1 & 0xf) == 4 || (op1 & 0xf) == 6)
895 imm = PROGRAM(pc++); // immediate
897 ret = translate_op(op, &pc, imm);
902 emit_mov_const(0, op);
906 emit_mov_const(1, imm);
911 emit_interpreter_call(in_funcs[op1]);
913 if (in_funcs[op1] == NULL) {
914 printf("NULL func! op=%08x (%02x)\n", op, op1);
923 if (op1 == 0x24 || op1 == 0x26 || // call, bra
924 ((op1 == 0 || op1 == 1 || op1 == 4 || op1 == 5 || op1 == 9 || op1 == 0x25) &&
925 (op & 0xf0) == 0x60)) { // ld PC
931 emit_block_epilogue(ccount + 1);
932 *tcache_ptr++ = 0xffffffff; // end of block
933 //printf(" %i inst\n", icount);
935 if (tcache_ptr - tcache > TCACHE_SIZE/4) {
936 printf("tcache overflow!\n");
944 printf("%i blocks, %i bytes\n", nblocks, (tcache_ptr - tcache)*4);
945 //printf("%p %p\n", tcache_ptr, emit_block_epilogue);
949 FILE *f = fopen("tcache.bin", "wb");
950 fwrite(tcache, 1, (tcache_ptr - tcache)*4, f);
963 // -----------------------------------------------------
965 int ssp1601_dyn_startup(void)
967 memset(tcache, 0, TCACHE_SIZE);
968 memset(block_table, 0, sizeof(block_table));
969 memset(block_table_iram, 0, sizeof(block_table_iram));
971 *tcache_ptr++ = 0xffffffff;
977 void ssp1601_dyn_reset(ssp1601_t *ssp)
979 ssp1601_reset_local(ssp);
980 ssp->rom_ptr = (unsigned int) Pico.rom;
981 ssp->iram_ptr = (unsigned int) svp->iram_rom;
982 ssp->dram_ptr = (unsigned int) svp->dram;
985 void ssp1601_dyn_run(int cycles)
987 if (ssp->emu_status & SSP_WAIT_MASK) return;
988 //{ printf("%i wait\n", Pico.m.frame_count); return; }
989 //printf("%i %04x\n", Pico.m.frame_count, rPC<<1);
992 rPC = DUMP_BLOCK >> 1;
996 int (*trans_entry)(void);
1000 iram_context = get_iram_context();
1003 if (block_table_iram[iram_context][rPC] == NULL)
1004 block_table_iram[iram_context][rPC] = translate_block(rPC);
1005 trans_entry = (void *) block_table_iram[iram_context][rPC];
1009 if (block_table[rPC] == NULL)
1010 block_table[rPC] = translate_block(rPC);
1011 trans_entry = (void *) block_table[rPC];
1016 //printf("enter %04x\n", rPC<<1);
1017 cycles -= trans_entry();
1018 //printf("leave %04x\n", rPC<<1);
1020 // debug_dump2file("tcache.bin", tcache, (tcache_ptr - tcache) << 1);