X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Main.cpp;h=400d3a6a05c48a32283d002a85fb416cc0563f36;hb=66dda842eae01f47f5389b931ec9567fb0bbb6a1;hp=1f532a0d93d52ab597c467a8861d972cdd4cce77;hpb=52ac6b1c8f65fe2477ffc3a7fc63ca8ae9d7e59f;p=cyclone68000.git diff --git a/Main.cpp b/Main.cpp index 1f532a0..400d3a6 100644 --- a/Main.cpp +++ b/Main.cpp @@ -25,8 +25,8 @@ int arm_op_count; // opcodes often used by games static const unsigned short hot_opcodes[] = { - 0x6701, // beq $3 - 0x6601, // bne $3 + 0x6702, // beq $3 + 0x6602, // bne $3 0x51c8, // dbra Dn, $2 0x4a38, // tst.b $0.w 0xd040, // add.w Dn, Dn @@ -34,7 +34,7 @@ static const unsigned short hot_opcodes[] = { 0x0240, // andi.w #$0, D0 0x2038, // move.l $0.w, D0 0xb0b8, // cmp.l $0.w, D0 - 0x6001, // bra $3 + 0x6002, // bra $3 0x30c0, // move.w D0, (A0)+ 0x3028, // move.w ($0,A0), D0 0x0c40, // cmpi.w #$0, D0 @@ -52,7 +52,7 @@ static const unsigned short hot_opcodes[] = { 0xb038, // cmp.b $0.w, D0 0x3039, // move.w $0.l, D0 0x4840, // swap D0 - 0x6101, // bsr $3 + 0x6102, // bsr $3 0x6100, // bsr $2 0x5e40, // addq.w #7, D0 0x1039, // move.b $0.l, D0 @@ -64,10 +64,10 @@ static const unsigned short hot_opcodes[] = { 0xc040, // and.w D0, D0 0x3180, // move.w D0, (A0,D0.w) 0x1198, // move.b (A0)+, (A0,D0.w) - 0x6501, // bcs $3 + 0x6502, // bcs $3 0x6500, // bcs $2 - 0x6401, // bcc $3 - 0x6a01, // bpl $3 + 0x6402, // bcc $3 + 0x6a02, // bpl $3 0x41f0, // lea (A0,D0.w), A0 0x4a28, // tst.b ($0,A0) 0x0828, // btst #$0, ($0,A0) @@ -111,50 +111,29 @@ void ltorg() } #if (CYCLONE_FOR_GENESIS == 2) -// r12=ptr to tas in table, trashes r0,r1 -static void ChangeTAS(int norm) +static const char *tas_ops[] = { + "Op4ad0", "Op4ad8", "Op4adf", + "Op4ae0", "Op4ae7", "Op4ae8", + "Op4af0", "Op4af8", "Op4af9", +}; + +// get handler address in r0, OT (offset table) in r2 +static void ChangeTASGet(unsigned int i) { - ot(" ldr r0,=Op4ad0%s\n",norm?"_":""); - ot(" mov r1,#8\n"); - ot("setrtas_loop%i0%s ;@ 4ad0-4ad7\n",norm,ms?"":":"); - ot(" subs r1,r1,#1\n"); - ot(" str r0,[r12],#4\n"); - ot(" bne setrtas_loop%i0\n",norm); - ot(" ldr r0,=Op4ad8%s\n",norm?"_":""); - ot(" mov r1,#7\n"); - ot("setrtas_loop%i1%s ;@ 4ad8-4ade\n",norm,ms?"":":"); - ot(" subs r1,r1,#1\n"); - ot(" str r0,[r12],#4\n"); - ot(" bne setrtas_loop%i1\n",norm); - ot(" ldr r0,=Op4adf%s\n",norm?"_":""); - ot(" str r0,[r12],#4\n"); - ot(" ldr r0,=Op4ae0%s\n",norm?"_":""); - ot(" mov r1,#7\n"); - ot("setrtas_loop%i2%s ;@ 4ae0-4ae6\n",norm,ms?"":":"); - ot(" subs r1,r1,#1\n"); - ot(" str r0,[r12],#4\n"); - ot(" bne setrtas_loop%i2\n",norm); - ot(" ldr r0,=Op4ae7%s\n",norm?"_":""); - ot(" str r0,[r12],#4\n"); - ot(" ldr r0,=Op4ae8%s\n",norm?"_":""); - ot(" mov r1,#8\n"); - ot("setrtas_loop%i3%s ;@ 4ae8-4aef\n",norm,ms?"":":"); - ot(" subs r1,r1,#1\n"); - ot(" str r0,[r12],#4\n"); - ot(" bne setrtas_loop%i3\n",norm); - ot(" ldr r0,=Op4af0%s\n",norm?"_":""); - ot(" mov r1,#8\n"); - ot("setrtas_loop%i4%s ;@ 4af0-4af7\n",norm,ms?"":":"); - ot(" subs r1,r1,#1\n"); - ot(" str r0,[r12],#4\n"); - ot(" bne setrtas_loop%i4\n",norm); - ot(" ldr r0,=Op4af8%s\n",norm?"_":""); - ot(" str r0,[r12],#4\n"); - ot(" ldr r0,=Op4af9%s\n",norm?"_":""); - ot(" str r0,[r12],#4\n"); + if (i >= sizeof(tas_ops) / sizeof(tas_ops[0])) + abort(); + ot(" ldr r0,[r2,#%d*4] ;@ %s\n",i,tas_ops[i]); + ot(" add r0,r0,r2\n"); } #endif +static void LoadCycloneJumpTab(int reg, int tmp) +{ + ot(" adr r%d,CycloneOT_JT\n", tmp); + ot(" ldr r%d,[r%d] ;@ CycloneJumpTab-CycloneOT_JT\n", reg, tmp); + ot(" add r%d,r%d,r%d ;@ =CycloneJumpTab\n", reg, reg, tmp); +} + #if EMULATE_ADDRESS_ERRORS_JUMP || EMULATE_ADDRESS_ERRORS_IO static void AddressErrorWrapper(char rw, const char *dataprg, int iw) { @@ -169,13 +148,14 @@ static void AddressErrorWrapper(char rw, const char *dataprg, int iw) } #endif -void FlushPC(void) +void FlushPC(int force) { #if MEMHANDLERS_NEED_PC - if (pc_dirty) - ot(" str r4,[r7,#0x40] ;@ Save PC\n"); -#endif + force |= pc_dirty; pc_dirty = 0; +#endif + if (force) + ot(" str r4,[r7,#0x40] ;@ Save PC\n"); } static void PrintFramework() @@ -197,14 +177,13 @@ static void PrintFramework() ot(" mov r7,r0 ;@ r7 = Pointer to Cpu Context\n"); ot(" ;@ r0-3 = Temporary registers\n"); ot(" ldrb r10,[r7,#0x46] ;@ r10 = Flags (NZCV)\n"); - ot(" ldr r6,=CycloneJumpTab ;@ r6 = Opcode Jump table\n"); + ot(" ldr r6,[r7,#0x54] ;@ r6 = Opcode Jump table (from reset)\n"); ot(" ldr r5,[r7,#0x5c] ;@ r5 = Cycles\n"); ot(" ldr r4,[r7,#0x40] ;@ r4 = Current PC + Memory Base\n"); ot(" ;@ r8 = Current Opcode\n"); ot(" ldr r1,[r7,#0x44] ;@ Get SR high T_S__III and irq level\n"); ot(" mov r10,r10,lsl #28;@ r10 = Flags 0xf0000000, cpsr format\n"); ot(" ;@ r11 = Source value / Memory Base\n"); - ot(" str r6,[r7,#0x54] ;@ make a copy to avoid literal pools\n"); ot("\n"); #if (CYCLONE_FOR_GENESIS == 2) || EMULATE_TRACE ot(" mov r2,#0\n"); @@ -261,7 +240,7 @@ static void PrintFramework() ot("CycloneInit%s\n", ms?"":":"); #if COMPRESS_JUMPTABLE ot(";@ decompress jump table\n"); - ot(" ldr r12,=CycloneJumpTab\n"); + LoadCycloneJumpTab(12, 1); ot(" add r0,r12,#0xe000*4 ;@ ctrl code pointer\n"); ot(" ldr r1,[r0,#-4]\n"); ot(" tst r1,r1\n"); @@ -287,7 +266,7 @@ static void PrintFramework() ot(" bgt unc_loop_in\n"); ot(" b unc_loop\n"); ot("unc_finish%s\n", ms?"":":"); - ot(" ldr r12,=CycloneJumpTab\n"); + LoadCycloneJumpTab(12, 1); ot(" ;@ set a-line and f-line handlers\n"); ot(" add r0,r12,#0xa000*4\n"); ot(" ldr r1,[r0,#4] ;@ a-line handler\n"); @@ -306,7 +285,12 @@ static void PrintFramework() ot(" bx lr\n"); ltorg(); #else - ot(";@ do nothing\n"); + ot(";@ fix final jumptable entries\n"); + LoadCycloneJumpTab(12, 0); + ot(" add r12,r12,#0x10000*4\n"); + ot(" ldr r0,[r12,#-3*4]\n"); + ot(" str r0,[r12,#-2*4]\n"); + ot(" str r0,[r12,#-1*4]\n"); ot(" bx lr\n"); #endif ot("\n"); @@ -314,7 +298,9 @@ static void PrintFramework() // -------------- ot("CycloneReset%s\n", ms?"":":"); ot(" stmfd sp!,{r7,lr}\n"); + LoadCycloneJumpTab(12, 1); ot(" mov r7,r0\n"); + ot(" str r12,[r7,#0x54] ;@ save CycloneJumpTab avoid literal pools\n"); ot(" mov r0,#0\n"); ot(" str r0,[r7,#0x58] ;@ state_flags\n"); ot(" str r0,[r7,#0x48] ;@ OSP\n"); @@ -337,6 +323,77 @@ static void PrintFramework() ot(" ldmfd sp!,{r7,pc}\n"); ot("\n"); + // -------------- + ot("CycloneSetRealTAS%s\n", ms?"":":"); +#if (CYCLONE_FOR_GENESIS == 2) + LoadCycloneJumpTab(12, 1); + ot(" tst r0,r0\n"); + ot(" add r12,r12,#0x4a00*4\n"); + ot(" add r12,r12,#0x00d0*4\n"); + ot(" adr r2,CycloneOT_TAS_\n"); + ot(" addeq r2,r2,#%lu*4\n", sizeof(tas_ops) / sizeof(tas_ops[0])); + + ChangeTASGet(0); + ot(" mov r1,#8\n"); + ot("setrtas_loop0%s ;@ 4ad0-4ad7\n",ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop0\n"); + + ChangeTASGet(1); + ot(" mov r1,#7\n"); + ot("setrtas_loop1%s ;@ 4ad8-4ade\n",ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop1\n"); + + ChangeTASGet(2); + ot(" str r0,[r12],#4\n"); + ChangeTASGet(3); + ot(" mov r1,#7\n"); + ot("setrtas_loop2%s ;@ 4ae0-4ae6\n",ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop2\n"); + + ChangeTASGet(4); + ot(" str r0,[r12],#4\n"); + ChangeTASGet(5); + ot(" mov r1,#8\n"); + ot("setrtas_loop3%s ;@ 4ae8-4aef\n",ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop3\n"); + + ChangeTASGet(6); + ot(" mov r1,#8\n"); + ot("setrtas_loop4%s ;@ 4af0-4af7\n",ms?"":":"); + ot(" subs r1,r1,#1\n"); + ot(" str r0,[r12],#4\n"); + ot(" bne setrtas_loop4\n"); + + ChangeTASGet(7); + ot(" str r0,[r12],#4\n"); + ChangeTASGet(8); + ot(" str r0,[r12],#4\n"); +#endif + ot(" bx lr\n"); + ot("\n"); + + // -------------- + // offset table to avoid .text relocations (forbidden by Android and iOS) + ot("CycloneOT_JT%s\n", ms?"":":"); + ot(" %s %s-CycloneOT_JT\n", ms?"dcd":".long", "CycloneJumpTab"); +#if (CYCLONE_FOR_GENESIS == 2) + ot("CycloneOT_TAS_%s\n", ms?"":":"); // working TAS (no MD bug) + for (size_t i = 0; i < sizeof(tas_ops) / sizeof(tas_ops[0]); i++) + ot(" %s %s_-CycloneOT_TAS_\n", ms?"dcd":".long", tas_ops[i]); + ot("CycloneOT_TAS%s\n", ms?"":":"); // broken TAS + for (size_t i = 0; i < sizeof(tas_ops) / sizeof(tas_ops[0]); i++) + ot(" %s %s-CycloneOT_TAS\n", ms?"dcd":".long", tas_ops[i]); + ot("\n"); +#endif + // -------------- // 68k: XNZVC, ARM: NZCV ot("CycloneSetSr%s\n", ms?"":":"); @@ -488,25 +545,6 @@ static void PrintFramework() ot("\n"); ot("\n"); - // -------------- - ot("CycloneSetRealTAS%s\n", ms?"":":"); -#if (CYCLONE_FOR_GENESIS == 2) - ot(" ldr r12,=CycloneJumpTab\n"); - ot(" tst r0,r0\n"); - ot(" add r12,r12,#0x4a00*4\n"); - ot(" add r12,r12,#0x00d0*4\n"); - ot(" beq setrtas_off\n"); - ChangeTAS(1); - ot(" bx lr\n"); - ot("setrtas_off%s\n",ms?"":":"); - ChangeTAS(0); - ot(" bx lr\n"); - ltorg(); -#else - ot(" bx lr\n"); -#endif - ot("\n"); - // -------------- ot(";@ DoInterrupt - r0=IRQ level\n"); ot("CycloneDoInterruptGoBack%s\n", ms?"":":"); @@ -630,7 +668,7 @@ static void PrintFramework() ot(" ldr r6,[r7,#0x54]\n"); ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n"); ot(" subs r5,r5,#44 ;@ Subtract cycles\n"); - ot(" ldrge pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); + ot(" ldrgt pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); ot(" b CycloneEnd\n"); ot("\n"); @@ -842,7 +880,7 @@ static void PrintFramework() ot(" ldr r6,[r7,#0x54]\n"); ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n"); ot(" subs r5,r5,#50 ;@ Subtract cycles\n"); - ot(" ldrge pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); + ot(" ldrgt pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); ot(" b CycloneEnd\n"); ot("\n"); #endif @@ -855,7 +893,7 @@ static void PrintFramework() ot(" cmp r5,#0\n"); ot(" orr r0,r0,#2 ;@ go to trace mode\n"); ot(" str r0,[r7,#0x58]\n"); - ot(" blt CycloneEnd\n"); // should take care of situation where we come here when already tracing + ot(" ble CycloneEnd\n"); // should take care of situation where we come here when already tracing ot(";@ CheckInterrupt:\n"); ot(" movs r0,r1,lsr #24 ;@ Get IRQ level\n"); ot(" beq CycloneDoTrace\n"); @@ -898,13 +936,13 @@ static void PrintFramework() ot(" bl Exception\n"); ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n"); ot(" subs r5,r5,#34 ;@ Subtract cycles\n"); - ot(" ldrge pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); + ot(" ldrgt pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); ot(" b CycloneEnd\n"); ot("\n"); ot("TraceDisabled%s\n", ms?"":":"); ot(" ldrh r8,[r4],#2 ;@ Fetch next opcode\n"); ot(" cmp r5,#0\n"); - ot(" ldrge pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); + ot(" ldrgt pc,[r6,r8,asl #2] ;@ Jump to opcode handler\n"); ot(" b CycloneEnd\n"); ot("\n"); #endif @@ -1267,9 +1305,9 @@ static int CycloneMake() ot(" %s CycloneDoTrace\n",globl); ot(" %s CycloneJumpTab\n",globl); ot(" %s Op____\n",globl); - ot(" %s Op6001\n",globl); - ot(" %s Op6601\n",globl); - ot(" %s Op6701\n",globl); + ot(" %s Op6002\n",globl); + ot(" %s Op6602\n",globl); + ot(" %s Op6702\n",globl); #endif ot("\n"); ot(ms?"CycloneVer dcd 0x":"CycloneVer: .long 0x");