bugfixes, new scaling, double ym upd at 940
[picodrive.git] / cpu / Cyclone / Main.cpp
index aca7f4f..a85aebc 100644 (file)
@@ -32,6 +32,51 @@ void ltorg()
   else    ot("  .ltorg\n");\r
 }\r
 \r
+#if CYCLONE_FOR_GENESIS\r
+// r12=ptr to tas in table, trashes r0,r1\r
+static void ChangeTAS(int norm)\r
+{\r
+  ot("  ldr r0,=Op4ad0%s\n",norm?"_":"");\r
+  ot("  mov r1,#8\n");\r
+  ot("setrtas_loop%i0%s ;@ 4ad0-4ad7\n",norm,ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop%i0\n",norm);\r
+  ot("  ldr r0,=Op4ad8%s\n",norm?"_":"");\r
+  ot("  mov r1,#7\n");\r
+  ot("setrtas_loop%i1%s ;@ 4ad8-4ade\n",norm,ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop%i1\n",norm);\r
+  ot("  ldr r0,=Op4adf%s\n",norm?"_":"");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  ldr r0,=Op4ae0%s\n",norm?"_":"");\r
+  ot("  mov r1,#7\n");\r
+  ot("setrtas_loop%i2%s ;@ 4ae0-4ae6\n",norm,ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop%i2\n",norm);\r
+  ot("  ldr r0,=Op4ae7%s\n",norm?"_":"");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  ldr r0,=Op4ae8%s\n",norm?"_":"");\r
+  ot("  mov r1,#8\n");\r
+  ot("setrtas_loop%i3%s ;@ 4ae8-4aef\n",norm,ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop%i3\n",norm);\r
+  ot("  ldr r0,=Op4af0%s\n",norm?"_":"");\r
+  ot("  mov r1,#8\n");\r
+  ot("setrtas_loop%i4%s ;@ 4af0-4af7\n",norm,ms?"":":");\r
+  ot("  subs r1,r1,#1\n");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  bne setrtas_loop%i4\n",norm);\r
+  ot("  ldr r0,=Op4af8%s\n",norm?"_":"");\r
+  ot("  str r0,[r12],#4\n");\r
+  ot("  ldr r0,=Op4af9%s\n",norm?"_":"");\r
+  ot("  str r0,[r12],#4\n");\r
+}\r
+#endif\r
+\r
 // trashes all temp regs\r
 static void PrintException(int ints)\r
 {\r
@@ -86,11 +131,10 @@ static void PrintException(int ints)
 void CheckInterrupt(int op)\r
 {\r
   ot(";@ CheckInterrupt:\n");\r
-  ot("  ldr r0,[r7,#0x44]\n"); // same as  ldrb r0,[r7,#0x47]\r
-  ot("  movs r0,r0,lsr #24 ;@ Get IRQ level (loading word is faster)\n");\r
+  ot("  ldr r1,[r7,#0x44] ;@ Get SR high T_S__III and irq level\n");\r
+  ot("  movs r0,r1,lsr #24 ;@ Get IRQ level\n"); // same as  ldrb r0,[r7,#0x47]\r
   ot("  beq NoInts%x\n",op);\r
   ot("  cmp r0,#6 ;@ irq>6 ?\n");\r
-  ot("  ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n");\r
   ot("  andle r1,r1,#7 ;@ Get interrupt mask\n");\r
   ot("  cmple r0,r1 ;@ irq<=6: Is irq<=mask ?\n");\r
   ot("  blgt CycloneDoInterrupt\n");\r
@@ -113,15 +157,14 @@ static void PrintFramework()
   ot("  ldr r5,[r7,#0x5c]  ;@ r5 = Cycles\n");\r
   ot("  ldr r4,[r7,#0x40]  ;@ r4 = Current PC + Memory Base\n");\r
   ot("                     ;@ r8 = Current Opcode\n");\r
-  ot("  ldr r0,[r7,#0x44]\n");\r
+  ot("  ldr r1,[r7,#0x44]  ;@ Get SR high T_S__III and irq level\n");\r
   ot("  mov r9,r9,lsl #28  ;@ r9 = Flags 0xf0000000, cpsr format\n");\r
   ot("                     ;@ r10 = Source value / Memory Base\n");\r
   ot("\n");\r
   ot(";@ CheckInterrupt:\n");\r
-  ot("  movs r0,r0,lsr #24 ;@ Get IRQ level\n"); // same as  ldrb r0,[r7,#0x47]\r
+  ot("  movs r0,r1,lsr #24 ;@ Get IRQ level\n"); // same as  ldrb r0,[r7,#0x47]\r
   ot("  beq NoInts0\n");\r
   ot("  cmp r0,#6 ;@ irq>6 ?\n");\r
-  ot("  ldrleb r1,[r7,#0x44] ;@ Get SR high: T_S__III\n");\r
   ot("  andle r1,r1,#7 ;@ Get interrupt mask\n");\r
   ot("  cmple r0,r1 ;@ irq<=6: Is irq<=mask ?\n");\r
   ot("  blgt CycloneDoInterrupt\n");\r
@@ -261,6 +304,26 @@ static void PrintFramework()
   ot("  bx lr\n");\r
   ot("\n");\r
 \r
+  if (ms) ot("CycloneSetRealTAS\n");\r
+  else    ot("CycloneSetRealTAS:\n");\r
+#if CYCLONE_FOR_GENESIS\r
+  ot("  ldr r12,=CycloneJumpTab\n");\r
+  ot("  tst r0,r0\n");\r
+  ot("  add r12,r12,#0x4a00*4\n");\r
+  ot("  add r12,r12,#0x00d0*4\n");\r
+  ot("  beq setrtas_off\n");\r
+  ChangeTAS(1);\r
+  ot("  bx lr\n");\r
+  ot("setrtas_off%s\n",ms?"":":");\r
+  ChangeTAS(0);\r
+  ot("  bx lr\n");\r
+  ltorg();\r
+  ot("\n");\r
+#else\r
+  ot("  bx lr\n");\r
+  ot("\n");\r
+#endif\r
+\r
   ot(";@ DoInterrupt - r0=IRQ number\n");\r
   ot("CycloneDoInterrupt%s\n", ms?"":":");\r
   ot("  stmdb sp!,{lr} ;@ Push ARM return address\n");\r
@@ -472,6 +535,9 @@ static void PrintJumpTable()
 \r
   ot(";@ -------------------------- Jump Table --------------------------\n");\r
 \r
+  // space for decompressed table\r
+  ot(ms?"  area |.data|, data\n":"  .data\n  .align 4\n\n");\r
+\r
 #if COMPRESS_JUMPTABLE\r
     int handlers=0,reps=0,*indexes,ip,u,out;\r
     // use some weird compression on the jump table\r
@@ -479,9 +545,6 @@ static void PrintJumpTable()
        if(!indexes) { printf("ERROR: out of memory\n"); exit(1); }\r
        len=0x10000;\r
 \r
-       // space for decompressed table\r
-       ot(ms?"  area |.data|, data\n":"  .data\n  .align 4\n\n");\r
-\r
        ot("CycloneJumpTab%s\n", ms?"":":");\r
        if(ms) {\r
          for(i = 0; i < 0xa000/8; i++)\r
@@ -609,6 +672,7 @@ static int CycloneMake()
     ot("  export CycloneRun\n");\r
     ot("  export CycloneSetSr\n");\r
     ot("  export CycloneGetSr\n");\r
+    ot("  export CycloneSetRealTAS\n");\r
     ot("  export CycloneVer\n");\r
     ot("\n");\r
     ot("CycloneVer dcd 0x%.4x\n",CycloneVer);\r
@@ -619,6 +683,7 @@ static int CycloneMake()
     ot("  .global CycloneRun\n");\r
     ot("  .global CycloneSetSr\n");\r
     ot("  .global CycloneGetSr\n");\r
+    ot("  .global CycloneSetRealTAS\n");\r
     ot("  .global CycloneVer\n");\r
 #ifdef CYCLONE_FOR_PICODRIVE\r
     ot("  .global CycloneDoInterrupt\n");\r