X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cpu%2FCyclone%2FMain.cpp;h=8f00bb1b7d9626a52b4406d8495cda485745825e;hb=9bb5d91c48b50da466aa553db65c9f9b2a0b1e8d;hp=2c87ea0103861c3f4d42a25fce7bc4230a1a4e91;hpb=d95259bdaaf911218656d8a74b096ff7306034f6;p=picodrive.git diff --git a/cpu/Cyclone/Main.cpp b/cpu/Cyclone/Main.cpp index 2c87ea0..8f00bb1 100644 --- a/cpu/Cyclone/Main.cpp +++ b/cpu/Cyclone/Main.cpp @@ -12,10 +12,72 @@ int Cycles; // Current cycles for opcode int pc_dirty; // something changed PC during processing int arm_op_count; +// opcodes often used by games +static const unsigned short hot_opcodes[] = { + 0x6701, // beq $3 + 0x6601, // bne $3 + 0x51c8, // dbra Dn, $2 + 0x4a38, // tst.b $0.w + 0xd040, // add.w Dn, Dn + 0x4a79, // tst.w $0.l + 0x0240, // andi.w #$0, D0 + 0x2038, // move.l $0.w, D0 + 0xb0b8, // cmp.l $0.w, D0 + 0x6001, // bra $3 + 0x30c0, // move.w D0, (A0)+ + 0x3028, // move.w ($0,A0), D0 + 0x0c40, // cmpi.w #$0, D0 + 0x0c79, // cmpi.w #$0, $0.l + 0x4e75, // rts + 0x4e71, // nop + 0x3000, // move.w D0, D0 + 0x0839, // btst #$0, $0.l + 0x7000, // moveq #$0, D0 + 0x3040, // movea.w D0, A0 + 0x0838, // btst #$0, $0.w + 0x4a39, // tst.b $0.l + 0x33d8, // move.w (A0)+, $0.l + 0x6700, // beq $2 + 0xb038, // cmp.b $0.w, D0 + 0x3039, // move.w $0.l, D0 + 0x4840, // swap D0 + 0x6101, // bsr $3 + 0x6100, // bsr $2 + 0x5e40, // addq.w #7, D0 + 0x1039, // move.b $0.l, D0 + 0x20c0, // move.l D0, (A0)+ + 0x1018, // move.b (A0)+, D0 + 0x30d0, // move.w (A0), (A0)+ + 0x3080, // move.w D0, (A0) + 0x3018, // move.w (A0)+, D0 + 0xc040, // and.w D0, D0 + 0x3180, // move.w D0, (A0,D0.w) + 0x1198, // move.b (A0)+, (A0,D0.w) + 0x6501, // bcs $3 + 0x6500, // bcs $2 + 0x6401, // bcc $3 + 0x6a01, // bpl $3 + 0x41f0, // lea (A0,D0.w), A0 + 0x4a28, // tst.b ($0,A0) + 0x0828, // btst #$0, ($0,A0) + 0x0640, // addi.w #$0, D0 + 0x10c0, // move.b D0, (A0)+ + 0x10d8, // move.b (A0)+, (A0)+ +}; +#define hot_opcode_count (int)(sizeof(hot_opcodes) / sizeof(hot_opcodes[0])) + +static int is_op_hot(int op) +{ + int i; + for (i = 0; i < hot_opcode_count; i++) + if (op == hot_opcodes[i]) + return 1; + return 0; +} void ot(const char *format, ...) { - va_list valist=NULL; + va_list valist; int i, len; // notaz: stop me from leaving newlines in the middle of format string @@ -238,6 +300,32 @@ static void PrintFramework() #endif ot("\n"); + // -------------- + ot("CycloneReset%s\n", ms?"":":"); + ot(" stmfd sp!,{r7,lr}\n"); + ot(" mov r7,r0\n"); + ot(" mov r0,#0\n"); + ot(" str r0,[r7,#0x58] ;@ state_flags\n"); + ot(" str r0,[r7,#0x48] ;@ OSP\n"); + ot(" mov r1,#0x27 ;@ Supervisor mode\n"); + ot(" strb r1,[r7,#0x44] ;@ set SR high\n"); + ot(" strb r0,[r7,#0x47] ;@ IRQ\n"); + MemHandler(0,2); + ot(" str r0,[r7,#0x3c] ;@ Stack pointer\n"); + ot(" mov r0,#0\n"); + ot(" str r0,[r7,#0x60] ;@ Membase\n"); + ot(" mov r0,#4\n"); + MemHandler(0,2); +#ifdef MEMHANDLERS_DIRECT_PREFIX + ot(" bl %scheckpc ;@ Call checkpc()\n", MEMHANDLERS_DIRECT_PREFIX); +#else + ot(" mov lr,pc\n"); + ot(" ldr pc,[r7,#0x64] ;@ Call checkpc()\n"); +#endif + ot(" str r0,[r7,#0x40] ;@ PC + base\n"); + ot(" ldmfd sp!,{r7,pc}\n"); + ot("\n"); + // -------------- // 68k: XNZVC, ARM: NZCV ot("CycloneSetSr%s\n", ms?"":":"); @@ -313,9 +401,10 @@ static void PrintFramework() // -------------- ot("CycloneUnpack%s\n", ms?"":":"); - ot(" stmfd sp!,{r4,r5,lr}\n"); - ot(" mov r4,r0\n"); - ot(" mov r5,r1\n"); + ot(" stmfd sp!,{r5,r7,lr}\n"); + ot(" mov r7,r0\n"); + ot(" movs r5,r1\n"); + ot(" beq c_unpack_do_pc\n"); ot(" mov r3,#16\n"); ot(";@ 0x00-0x3f: DA registers\n"); ot("c_unpack_loop%s\n",ms?"":":"); @@ -325,30 +414,37 @@ static void PrintFramework() ot(" bne c_unpack_loop\n"); ot(";@ 0x40: PC\n"); ot(" ldr r0,[r5],#4 ;@ PC\n"); -#if USE_CHECKPC_CALLBACK - ot(" mov r1,#0\n"); - ot(" str r1,[r4,#0x60] ;@ Memory base\n"); - ot(" mov lr,pc\n"); - ot(" ldr pc,[r4,#0x64] ;@ Call checkpc()\n"); -#else - ot(" ldr r1,[r4,#0x60] ;@ Memory base\n"); - ot(" add r0,r0,r1 ;@ r0 = Memory Base + New PC\n"); -#endif - ot(" str r0,[r4,#0x40] ;@ PC + Memory Base\n"); + ot(" str r0,[r7,#0x40] ;@ handle later\n"); ot(";@ 0x44: SR\n"); ot(" ldrh r1,[r5],#2\n"); - ot(" mov r0,r4\n"); + ot(" mov r0,r7\n"); ot(" bl CycloneSetSr\n"); ot(";@ 0x46: IRQ level\n"); ot(" ldrb r0,[r5],#2\n"); - ot(" strb r0,[r4,#0x47]\n"); + ot(" strb r0,[r7,#0x47]\n"); ot(";@ 0x48: other SP\n"); ot(" ldr r0,[r5],#4\n"); - ot(" str r0,[r4,#0x48]\n"); + ot(" str r0,[r7,#0x48]\n"); ot(";@ 0x4c: CPU state flags\n"); ot(" ldr r0,[r5],#4\n"); - ot(" str r0,[r4,#0x58]\n"); - ot(" ldmfd sp!,{r4,r5,pc}\n"); + ot(" str r0,[r7,#0x58]\n"); + ot("c_unpack_do_pc%s\n",ms?"":":"); + ot(" ldr r0,[r7,#0x40] ;@ unbased PC\n"); +#if USE_CHECKPC_CALLBACK + ot(" mov r1,#0\n"); + ot(" str r1,[r7,#0x60] ;@ Memory base\n"); + #ifdef MEMHANDLERS_DIRECT_PREFIX + ot(" bl %scheckpc ;@ Call checkpc()\n", MEMHANDLERS_DIRECT_PREFIX); + #else + ot(" mov lr,pc\n"); + ot(" ldr pc,[r7,#0x64] ;@ Call checkpc()\n"); + #endif +#else + ot(" ldr r1,[r7,#0x60] ;@ Memory base\n"); + ot(" add r0,r0,r1 ;@ r0 = Memory Base + New PC\n"); +#endif + ot(" str r0,[r7,#0x40] ;@ PC + Memory Base\n"); + ot(" ldmfd sp!,{r5,r7,pc}\n"); ot("\n"); // -------------- @@ -487,12 +583,20 @@ static void PrintFramework() MemHandler(0,2,0,0); ot(" tst r0,r0 ;@ uninitialized int vector?\n"); ot(" moveq r0,#0x3c\n"); + #ifdef MEMHANDLERS_DIRECT_PREFIX + ot(" bleq %sread32 ;@ Call read32(r0) handler\n", MEMHANDLERS_DIRECT_PREFIX); + #else ot(" moveq lr,pc\n"); ot(" ldreq pc,[r7,#0x70] ;@ Call read32(r0) handler\n"); + #endif #if USE_CHECKPC_CALLBACK ot(" add lr,pc,#4\n"); ot(" add r0,r0,r11 ;@ r0 = Memory Base + New PC\n"); + #ifdef MEMHANDLERS_DIRECT_PREFIX + ot(" bl %scheckpc ;@ Call checkpc()\n", MEMHANDLERS_DIRECT_PREFIX); + #else ot(" ldr pc,[r7,#0x64] ;@ Call checkpc()\n"); + #endif #if EMULATE_ADDRESS_ERRORS_JUMP ot(" mov r4,r0\n"); #else @@ -574,7 +678,11 @@ static void PrintFramework() #if USE_CHECKPC_CALLBACK ot(" add lr,pc,#4\n"); ot(" add r0,r0,r3 ;@ r0 = Memory Base + New PC\n"); + #ifdef MEMHANDLERS_DIRECT_PREFIX + ot(" bl %scheckpc ;@ Call checkpc()\n", MEMHANDLERS_DIRECT_PREFIX); + #else ot(" ldr pc,[r7,#0x64] ;@ Call checkpc()\n"); + #endif #if EMULATE_ADDRESS_ERRORS_JUMP ot(" mov r4,r0\n"); #else @@ -701,7 +809,11 @@ static void PrintFramework() #if USE_CHECKPC_CALLBACK ot(" add lr,pc,#4\n"); ot(" add r0,r0,r3 ;@ r0 = Memory Base + New PC\n"); + #ifdef MEMHANDLERS_DIRECT_PREFIX + ot(" bl %scheckpc ;@ Call checkpc()\n", MEMHANDLERS_DIRECT_PREFIX); + #else ot(" ldr pc,[r7,#0x64] ;@ Call checkpc()\n"); + #endif ot(" mov r4,r0\n"); #else ot(" add r4,r0,r3 ;@ r4 = Memory Base + New PC\n"); @@ -792,8 +904,8 @@ static void PrintFramework() // Trashes r0-r3,r12,lr int MemHandler(int type,int size,int addrreg,int need_addrerr_check) { - int func=0; - func=0x68+type*0xc+(size<<2); // Find correct offset + int func=0x68+type*0xc+(size<<2); // Find correct offset + char what[32]; #if MEMHANDLERS_NEED_FLAGS ot(" mov r3,r10,lsr #28\n"); @@ -832,6 +944,14 @@ int MemHandler(int type,int size,int addrreg,int need_addrerr_check) } else #endif + + sprintf(what, "%s%d", type==0 ? "read" : (type==1 ? "write" : "fetch"), 8<>12); fflush(stdout); } // Update progress - OpAny(op); + if (!is_op_hot(op)) + OpAny(op); } ot("\n"); @@ -1119,6 +1240,7 @@ static int CycloneMake() ot(ms?" area |.text|, code\n":" .text\n .align 4\n\n"); ot(" %s CycloneInit\n",globl); + ot(" %s CycloneReset\n",globl); ot(" %s CycloneRun\n",globl); ot(" %s CycloneSetSr\n",globl); ot(" %s CycloneGetSr\n",globl);