summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichiel Van Der Kolk <not.valid@email.address>2005-03-05 16:29:20 +0000
committerMichiel Van Der Kolk <not.valid@email.address>2005-03-05 16:29:20 +0000
commitd1f948423e77418206185d39e5f4f17e19602f62 (patch)
treee372f9bcaa4b11456059aba403231733e163afc5
parentfd01ca38f6818ec5302e0543626619cbd555cd3e (diff)
downloadrockbox-d1f948423e77418206185d39e5f4f17e19602f62.tar.gz
rockbox-d1f948423e77418206185d39e5f4f17e19602f62.zip
More opcodes implemented on dynarec, somewhat working, some bugs.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6141 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/rockboy/cpu.c4
-rw-r--r--apps/plugins/rockboy/dynarec.c81
2 files changed, 74 insertions, 11 deletions
diff --git a/apps/plugins/rockboy/cpu.c b/apps/plugins/rockboy/cpu.c
index c396b218f5..1ed62cab92 100644
--- a/apps/plugins/rockboy/cpu.c
+++ b/apps/plugins/rockboy/cpu.c
@@ -242,7 +242,7 @@ un32 reg_backup[16];
242struct dynarec_block *address_map[1<<HASH_SIGNIFICANT_LOWER_BITS]; 242struct dynarec_block *address_map[1<<HASH_SIGNIFICANT_LOWER_BITS];
243extern void *dynapointer; 243extern void *dynapointer;
244int blockcount; 244int blockcount;
245#define MAXBLOCK 3 245#define MAXBLOCK 10
246#endif 246#endif
247 247
248 248
@@ -943,8 +943,6 @@ next:
943 rb->splash(HZ*2,true,meow); 943 rb->splash(HZ*2,true,meow);
944 while(b&&b->address.d!=(ptr+PC)) { 944 while(b&&b->address.d!=(ptr+PC)) {
945 p=b; 945 p=b;
946 snprintf(meow,499,"next: 0x%x",b->next ? b->next->address.d : 0);
947 rb->splash(HZ*2,true,meow);
948 b=b->next; 946 b=b->next;
949 } 947 }
950 if(b) { // call block 948 if(b) { // call block
diff --git a/apps/plugins/rockboy/dynarec.c b/apps/plugins/rockboy/dynarec.c
index a09bc50884..b4f420d6c8 100644
--- a/apps/plugins/rockboy/dynarec.c
+++ b/apps/plugins/rockboy/dynarec.c
@@ -51,7 +51,7 @@ int blockclen;
51#define CALL_NATIVE(n) \ 51#define CALL_NATIVE(n) \
52 DYNA_MOVEA_l_i_to_r(&cpu.a,3); \ 52 DYNA_MOVEA_l_i_to_r(&cpu.a,3); \
53 DYNA_MOVEM(3,0x3FE,0); \ 53 DYNA_MOVEM(3,0x3FE,0); \
54 DYNA_JSR(&writehi); \ 54 DYNA_JSR((n)); \
55 DYNA_MOVEA_l_i_to_r(&cpu.a,3); \ 55 DYNA_MOVEA_l_i_to_r(&cpu.a,3); \
56 DYNA_MOVEM(3,0x3FE,1); 56 DYNA_MOVEM(3,0x3FE,1);
57 57
@@ -362,8 +362,17 @@ void DYNA_SET_b_r(un8 src, un8 cond) {
362 DWRITEW(0x50C0|((cond)&0xF)<<8|(src&0x7)); 362 DWRITEW(0x50C0|((cond)&0xF)<<8|(src&0x7));
363} 363}
364 364
365void DYNA_INC_l_r(un8 dest,int is_areg) {
366 DYNA_ADDQ_l_i_to_r(1,dest,is_areg);
367}
368
369void DYNA_DEC_l_r(un8 dest,int is_areg) {
370 DYNA_SUBQ_l_i_to_r(1,dest,is_areg);
371}
372
373
365void dynamic_recompile (struct dynarec_block *newblock) { 374void dynamic_recompile (struct dynarec_block *newblock) {
366 int done=0; 375 int done=0,writepc=1;
367 byte op; 376 byte op;
368 unsigned int oldpc=PC; 377 unsigned int oldpc=PC;
369 unsigned short temp; 378 unsigned short temp;
@@ -373,7 +382,7 @@ void dynamic_recompile (struct dynarec_block *newblock) {
373 newblock->block=dynapointer; 382 newblock->block=dynapointer;
374 383
375 snprintf(meow,499,"Recompiling 0x%x",oldpc); 384 snprintf(meow,499,"Recompiling 0x%x",oldpc);
376 rb->splash(HZ*3,1,meow); 385 rb->splash(HZ*1,1,meow);
377 while(!done) { 386 while(!done) {
378 op=FETCH; 387 op=FETCH;
379 clen = cycles_table[op]; 388 clen = cycles_table[op];
@@ -388,6 +397,14 @@ void dynamic_recompile (struct dynarec_block *newblock) {
388 case 0x6D: /* LD L,L */ 397 case 0x6D: /* LD L,L */
389 case 0x7F: /* LD A,A */ 398 case 0x7F: /* LD A,A */
390 break; 399 break;
400
401 case 0x0B: /* DEC BC*
402 DYNA_TST_b_r(3); // test C
403 DYNA_DUMMYBRANCH(2,0);
404 DYNA_DEC_l_r(2,0); // dec B
405 DYNA_BCC_c(0x6,2,0); //jump here if not zero
406 DYNA_DEC_l_r(3,0); // dec C
407 break;
391 case 0x41: /* LD B,C */ 408 case 0x41: /* LD B,C */
392 DYNA_MOVE_b_r_to_r(3,2); 409 DYNA_MOVE_b_r_to_r(3,2);
393 break; 410 break;
@@ -548,6 +565,13 @@ void dynamic_recompile (struct dynarec_block *newblock) {
548 PC += 2; 565 PC += 2;
549 } 566 }
550 break; 567 break;
568 case 0x22: /* LDI (HL), A */
569 DYNA_PUSH_l_r(1,0);
570 DYNA_PUSH_l_r(6,0);
571 CALL_NATIVE(&writeb);
572 DYNA_ADDQ_l_i_to_r(0,7,1);
573 DYNA_INC_l_r(6,0);
574 break;
551 case 0x31: /* LD SP,imm */ 575 case 0x31: /* LD SP,imm */
552 DYNA_MOVEA_l_i_to_r(readw(xPC),0); 576 DYNA_MOVEA_l_i_to_r(readw(xPC),0);
553 PC += 2; 577 PC += 2;
@@ -654,16 +678,58 @@ void dynamic_recompile (struct dynarec_block *newblock) {
654 DYNA_MOVEA_l_i_to_r(&blockclen,3); 678 DYNA_MOVEA_l_i_to_r(&blockclen,3);
655 DYNA_MOVE_l_i_to_m(tclen,3); 679 DYNA_MOVE_l_i_to_m(tclen,3);
656 DYNA_RET(); 680 DYNA_RET();
657 DYNA_BCC_c(0x6,2,0); /* jump here if not zero (not zero = C) */ 681 DYNA_BCC_c(0x6,2,0); /* jump here if bit is not zero */
658 tclen-=3; 682 tclen-=3;
659 break; 683 break;
684 case 0xC9: /* RET */
685 POPA(1);
686 writepc=0;
687 done=1;
688 break;
689 case 0x20: /* JR NZ */
690 DYNA_BTST_l_r(8,7); /* btst #8,d7 */
691 DYNA_DUMMYBRANCH(2,0);
692 DYNA_MOVEA_l_i_to_r(&blockclen,3);
693 DYNA_MOVE_l_i_to_m(tclen,3);
694 DYNA_MOVEA_l_i_to_r(PC+1+(signed char)readb(PC),1);
695 DYNA_RET();
696 DYNA_BCC_c(0x6,2,0); /* jump here if bit is not zero */
697 tclen--;
698 PC++;
699 break;
700 case 0xC2: /* JP NZ */
701 DYNA_BTST_l_r(8,7); /* btst #8,d7 */
702 DYNA_DUMMYBRANCH(2,0);
703 DYNA_MOVEA_l_i_to_r(&blockclen,3);
704 DYNA_MOVEA_l_i_to_r(readw(PC),1);
705 DYNA_RET();
706 DYNA_BCC_c(0x6,2,0); /* jump here if bit is not zero */
707 tclen--;
708 PC+=2;
709 break;
710/* case 0xFA: /* LD A, (imm)
711 DYNA_PEA_w_i(readw(xPC));
712 PC+=2; \
713 CALL_NATIVE(&readb); \
714 DYNA_ADDQ_l_i_to_r(4,7,1); \
715 DYNA_MOVE_l_r_to_r(0,1,0);
716 break; */
717
660 case 0xFE: /* CMP #<imm> TODO: can be (much) more efficient.*/ 718 case 0xFE: /* CMP #<imm> TODO: can be (much) more efficient.*/
661 DYNA_MOVEA_l_r_to_r(2,3,0); /* movea.l %d2, %a3 */ 719 DYNA_MOVEA_l_r_to_r(2,3,0); /* movea.l %d2, %a3 */
662 DYNA_MOVEQ_l_i_to_r(FETCH,2); /* moveq.l #<FETCH>,%d2 */ 720 DYNA_MOVEQ_l_i_to_r(FETCH,2); /* moveq.l #<FETCH>,%d2 */
663 CMP(2); 721 CMP(2);
664 DYNA_MOVE_l_r_to_r(3,2,1); /* move.l %a3, %d2 */ 722 DYNA_MOVE_l_r_to_r(3,2,1); /* move.l %a3, %d2 */
665 break; 723 break;
666 724
725 case 0xB1: /* OR C */
726 DYNA_OR_l_r_to_r(3,1); // or %d3,%d1
727 DYNA_MOVEQ_l_i_to_r(0,7);
728 DYNA_TST_b_r(1,0);
729 DYNA_DUMMYBRANCH(2,0);
730 DYNA_MOVEQ_l_i_to_r(0x80,7);
731 DYNA_BCC_c(0x6,2,0);
732 break;
667 default: 733 default:
668 snprintf(meow,499,"unimplemented opcode %d / 0x%x",op,op); 734 snprintf(meow,499,"unimplemented opcode %d / 0x%x",op,op);
669 die(meow); 735 die(meow);
@@ -671,11 +737,10 @@ void dynamic_recompile (struct dynarec_block *newblock) {
671 break; 737 break;
672 } 738 }
673 } 739 }
674 snprintf(meow,499,"end of block, pc:0x%x",PC);
675 rb->splash(HZ*2,true,meow);
676 DYNA_MOVEA_l_i_to_r(&blockclen,3); 740 DYNA_MOVEA_l_i_to_r(&blockclen,3);
677 DYNA_MOVE_l_i_to_m(tclen,3); 741 DYNA_MOVE_l_i_to_m(tclen,3);
678 DYNA_MOVEA_l_i_to_r(PC,1); 742 if(writepc)
743 DYNA_MOVEA_l_i_to_r(PC,1);
679 DYNA_RET(); 744 DYNA_RET();
680 PC=oldpc; 745 PC=oldpc;
681 setmallocpos(dynapointer); 746 setmallocpos(dynapointer);