diff options
author | Michiel Van Der Kolk <not.valid@email.address> | 2005-03-05 16:29:20 +0000 |
---|---|---|
committer | Michiel Van Der Kolk <not.valid@email.address> | 2005-03-05 16:29:20 +0000 |
commit | d1f948423e77418206185d39e5f4f17e19602f62 (patch) | |
tree | e372f9bcaa4b11456059aba403231733e163afc5 | |
parent | fd01ca38f6818ec5302e0543626619cbd555cd3e (diff) | |
download | rockbox-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.c | 4 | ||||
-rw-r--r-- | apps/plugins/rockboy/dynarec.c | 81 |
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]; | |||
242 | struct dynarec_block *address_map[1<<HASH_SIGNIFICANT_LOWER_BITS]; | 242 | struct dynarec_block *address_map[1<<HASH_SIGNIFICANT_LOWER_BITS]; |
243 | extern void *dynapointer; | 243 | extern void *dynapointer; |
244 | int blockcount; | 244 | int 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 | ||
365 | void DYNA_INC_l_r(un8 dest,int is_areg) { | ||
366 | DYNA_ADDQ_l_i_to_r(1,dest,is_areg); | ||
367 | } | ||
368 | |||
369 | void DYNA_DEC_l_r(un8 dest,int is_areg) { | ||
370 | DYNA_SUBQ_l_i_to_r(1,dest,is_areg); | ||
371 | } | ||
372 | |||
373 | |||
365 | void dynamic_recompile (struct dynarec_block *newblock) { | 374 | void 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); |