optimizations, bugfixes, uae works (but with timing glitches?)
[picodrive.git] / cpu / Cyclone / OpMove.cpp
index b0916ea..64c0f59 100644 (file)
@@ -39,16 +39,6 @@ void OpRegToFlags(int high)
   ot("\n");\r
 }\r
 \r
-// checks for supervisor bit, if not set, jumps to SuperEnd()\r
-// also sets r11 to SR high value, SuperChange() uses this\r
-void SuperCheck(int op)\r
-{\r
-  ot("  ldr r11,[r7,#0x44] ;@ Get SR high\n");\r
-  ot("  tst r11,#0x20 ;@ Check we are in supervisor mode\n");\r
-  ot("  beq WrongPrivilegeMode ;@ No\n");\r
-  ot("\n");\r
-}\r
-\r
 void SuperEnd(void)\r
 {\r
   ot(";@ ----------\n");\r
@@ -58,7 +48,7 @@ void SuperEnd(void)
   ot("  mov r0,#0x20 ;@ privilege violation\n");\r
   ot("  bl Exception\n");\r
   Cycles=34;\r
-  OpEnd(0x10);\r
+  OpEnd(0);\r
 }\r
 \r
 // does OSP and A7 swapping if needed\r
@@ -217,12 +207,11 @@ int OpMoveSr(int op)
   use=OpBase(op,size);\r
   if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
 \r
-  OpStart(op,ea);\r
+  // 68000 model allows reading whole SR in user mode (but newer models don't)\r
+  OpStart(op,ea,0,0,type==3);\r
   Cycles=12;\r
   if (type==0) Cycles=(ea>=8)?8:6;\r
 \r
-  if (type==3) SuperCheck(op); // 68000 model allows reading whole SR in user mode (but newer models don't)\r
-\r
   if (type==0 || type==1)\r
   {\r
     OpFlagsToReg(type==0);\r
@@ -236,11 +225,10 @@ int OpMoveSr(int op)
     OpRegToFlags(type==3);\r
     if (type==3) {\r
       SuperChange(op,0);\r
-      CheckInterrupt(op);\r
     }\r
   }\r
 \r
-  OpEnd(ea);\r
+  OpEnd(ea,0,0,type==3);\r
 \r
   return 0;\r
 }\r
@@ -259,9 +247,7 @@ int OpArithSr(int op)
   use=OpBase(op,size);\r
   if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
 \r
-  OpStart(op,ea); Cycles=16;\r
-\r
-  if (size) SuperCheck(op);\r
+  OpStart(op,ea,0,0,size!=0); Cycles=16;\r
 \r
   EaCalc(10,0x003f,ea,size);\r
   EaRead(10,    10,ea,size,0x003f);\r
@@ -271,12 +257,11 @@ int OpArithSr(int op)
   if (type==1) ot("  and r0,r1,r10\n");\r
   if (type==5) ot("  eor r0,r1,r10\n");\r
   OpRegToFlags(size);\r
-  if (size) {\r
+  if (size && type!=0) { // we can't enter supervisor mode, nor unmask irqs just by using OR\r
     SuperChange(op,0);\r
-    CheckInterrupt(op);\r
   }\r
 \r
-  OpEnd(ea);\r
+  OpEnd(ea,0,0,size!=0 && type!=0);\r
 \r
   return 0;\r
 }\r
@@ -337,7 +322,7 @@ int OpMovem(int op)
   use=OpBase(op,size);\r
   if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
 \r
-  OpStart(op,ea);\r
+  OpStart(op,ea,0,1);\r
 \r
   ot("  ldrh r11,[r4],#2 ;@ r11=register mask\n");\r
 \r
@@ -370,6 +355,9 @@ int OpMovem(int op)
   }\r
   else\r
   {\r
+    // if (size == 2 && decr && SPLIT_MOVEL_PD) we should do 2xWrite16 here\r
+    // (same as in movel.l ?, -(An)), but as this is not likely to be needed and\r
+    // we do not want the performance hit, we do single Write32 instead.\r
     ot("  ;@ Copy register to memory:\n",1<<size);\r
     ot("  ldr r1,[r7,r10] ;@ Load value from Dn/An\n");\r
     EaWrite(6,1,ea,size,0x003f);\r
@@ -403,7 +391,7 @@ int OpMovem(int op)
 \r
   Cycles+=Ea_add_ns(g_movem_cycle_table,ea);\r
 \r
-  OpEnd(ea);\r
+  OpEnd(ea,0,1);\r
   ltorg();\r
   ot("\n");\r
 \r
@@ -421,9 +409,7 @@ int OpMoveUsp(int op)
 \r
   if (op!=use) { OpUse(op,use); return 0; } // Use existing handler\r
 \r
-  OpStart(op); Cycles=4;\r
-\r
-  SuperCheck(op);\r
+  OpStart(op,0,0,0,1); Cycles=4;\r
 \r
   if (dir)\r
   {\r
@@ -572,9 +558,7 @@ int OpStopReset(int op)
 {\r
   int type=(op>>1)&1; // stop/reset\r
 \r
-  OpStart(op);\r
-\r
-  SuperCheck(op);\r
+  OpStart(op,0,0,0,1);\r
 \r
   if(type) {\r
     // copy immediate to SR, stop the CPU and eat all remaining cycles.\r