implement op42 in C core
authorJavier S. Pedro <maemo@javispedro.com>
Wed, 9 Sep 2009 19:14:46 +0000 (21:14 +0200)
committerJavier S. Pedro <maemo@javispedro.com>
Wed, 9 Sep 2009 19:14:46 +0000 (21:14 +0200)
65c816ops.inc

index d28cb1f..e76d13c 100644 (file)
@@ -3894,7 +3894,142 @@ static void OpDB ()
 // Reserved S9xOpcode
 static void Op42 ()
 {
-       // TODO: Implement (speedhacks in i386)
+#if defined(CPU_SHUTDOWN) && !defined(SA1_OPCODES)\r
+\r
+       CPU.WaitAddress = NULL;\r
+       if (Settings.SA1) S9xSA1ExecuteDuringSleep ();\r
+\r
+       ApuSync();\r\r#ifdef VAR_CYCLES\r
+       CPU.Cycles += CPU.MemSpeed;\r
+#endif
+
+       //relative
+       int8 b = *CPU.PC;
+       CPU.PC++;
+
+       int8 BranchOffset = ((b & 0xF) | 0xF0);\r
+       uint16 OpAddress = (int)(CPU.PC - CPU.PCBase) + BranchOffset;\r
+
+       // Assume we're going to branch
+#ifdef VAR_CYCLES\r
+       CPU.Cycles += ONE_CYCLE;\r
+#else
+       CPU.Cycles++;\r
+#endif
+\r
+       switch (b >> 4) {\r
+       case 0x1: //BPL\r
+               BranchCheck1 ();\r
+               if (!CheckNegative ()) {\r
+                       CPU.PC = CPU.PCBase + OpAddress;
+#                      ifdef VAR_CYCLES\r
+                               CPU.Cycles += ONE_CYCLE;\r
+#                      else
+                               CPU.Cycles++;\r
+#                      endif\r
+                       CPUShutdown ();\r
+               }\r
+               return;\r
+       case 0x3: //BMI\r
+               BranchCheck1 ();\r
+               if (CheckNegative ()) {\r
+                       CPU.PC = CPU.PCBase + OpAddress;\r
+#                      ifdef VAR_CYCLES\r
+                               CPU.Cycles += ONE_CYCLE;\r
+#                      else
+                               CPU.Cycles++;\r
+#                      endif\r
+                       CPUShutdown ();\r
+               }\r
+               return;\r
+       case 0x5: //BVC\r
+               BranchCheck0 ();\r
+               if (!CheckOverflow ()) {\r
+                       CPU.PC = CPU.PCBase + OpAddress;\r
+#                      ifdef VAR_CYCLES\r
+                               CPU.Cycles += ONE_CYCLE;\r
+#                      else
+                               CPU.Cycles++;\r
+#                      endif\r
+                       CPUShutdown ();\r
+               }\r
+               return;\r
+       case 0x7: //BVS\r
+               BranchCheck0 ();\r
+               if (CheckOverflow ()) {\r
+                               CPU.PC = CPU.PCBase + OpAddress;\r
+#                      ifdef VAR_CYCLES\r
+                               CPU.Cycles += ONE_CYCLE;\r
+#                      else
+                               CPU.Cycles++;\r
+#                      endif\r
+                       CPUShutdown ();\r
+                       }\r
+               return;\r
+       case 0x8: //BRA\r
+               CPU.PC = CPU.PCBase + OpAddress;\r
+#              ifdef VAR_CYCLES\r
+                       CPU.Cycles += ONE_CYCLE;\r
+#              else
+                       CPU.Cycles++;\r
+#              endif\r
+               CPUShutdown ();\r
+               return;\r
+       case 0x9: //BCC\r
+               BranchCheck0 ();\r
+           if (!CheckCarry ()) {\r
+                       CPU.PC = CPU.PCBase + OpAddress;\r
+#                      ifdef VAR_CYCLES\r
+                               CPU.Cycles += ONE_CYCLE;\r
+#                      else
+                               CPU.Cycles++;\r
+#                      endif\r
+                       CPUShutdown ();\r
+               }\r
+               return;\r
+       case 0xB: //BCS\r
+               BranchCheck0 ();\r
+               if (CheckCarry ()) {\r
+                       CPU.PC = CPU.PCBase + OpAddress;\r
+#                      ifdef VAR_CYCLES\r
+                               CPU.Cycles += ONE_CYCLE;\r
+#                      else
+                               CPU.Cycles++;\r
+#                      endif\r
+                       CPUShutdown ();\r
+               }\r
+               return;\r
+       case 0xD: //BNE\r
+               BranchCheck1 ();\r
+               if (!CheckZero ()) {\r
+                       CPU.PC = CPU.PCBase + OpAddress;\r
+#                      ifdef VAR_CYCLES\r
+                       CPU.Cycles += ONE_CYCLE;\r
+#                      else
+                               CPU.Cycles++;\r
+#                      endif\r
+                       CPUShutdown ();\r
+               }\r
+               return;\r
+       case 0xF: //BEQ\r
+               BranchCheck2 ();\r
+               if (CheckZero ()) {\r
+                       CPU.PC = CPU.PCBase + OpAddress;\r
+#                      ifdef VAR_CYCLES\r
+                               CPU.Cycles += ONE_CYCLE;\r
+#                      else
+                               CPU.Cycles++;\r
+#                      endif\r
+                       CPUShutdown ();\r
+                       }\r
+               return;
+#ifdef DEBUG
+       default:
+               printf("Invalid Op42 branch type %hx\n", b >> 4);
+               return;\r
+       }
+#endif\r
+#endif
 }
 
 /**********************************************************************************************/