ym2612 stray sounds on save load fixed
[picodrive.git] / cpu / Cyclone / Main.cpp
index 2f92c5c..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,14 +131,13 @@ 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 DoInterrupt\n");\r
+  ot("  blgt CycloneDoInterrupt\n");\r
   ot("NoInts%x%s\n", op,ms?"":":");\r
   ot("\n");\r
 }\r
@@ -109,22 +153,21 @@ static void PrintFramework()
   ot("  mov r7,r0          ;@ r7 = Pointer to Cpu Context\n");\r
   ot("                     ;@ r0-3 = Temporary registers\n");\r
   ot("  ldrb r9,[r7,#0x46] ;@ r9 = Flags (NZCV)\n");\r
-  ot("  ldr r6,=JumpTab    ;@ r6 = Opcode Jump table\n");\r
+  ot("  ldr r6,=CycloneJumpTab ;@ r6 = Opcode Jump table\n");\r
   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 DoInterrupt\n");\r
+  ot("  blgt CycloneDoInterrupt\n");\r
   ot(";@ Check if interrupt used up all the cycles:\n");\r
   ot("  subs r5,r5,#0\n");\r
   ot("  blt CycloneEndNoBack\n");\r
@@ -143,7 +186,14 @@ static void PrintFramework()
   ot("CycloneEnd%s\n", ms?"":":");\r
   ot("  sub r4,r4,#2\n");\r
   ot("CycloneEndNoBack%s\n", ms?"":":");\r
+#ifdef CYCLONE_FOR_PICODRIVE\r
+  ot("  ldr r1,[r7,#0x54]\n");\r
+  ot("  mov r9,r9,lsr #28\n");\r
+  ot("  tst r1,r1\n");\r
+  ot("  bxne r1            ;@ jump to alternative CycloneEnd\n");\r
+#else\r
   ot("  mov r9,r9,lsr #28\n");\r
+#endif\r
   ot("  str r4,[r7,#0x40]  ;@ Save Current PC + Memory Base\n");\r
   ot("  str r5,[r7,#0x5c]  ;@ Save Cycles\n");\r
   ot("  strb r9,[r7,#0x46] ;@ Save Flags (NZCV)\n");\r
@@ -161,7 +211,7 @@ static void PrintFramework()
     ot(";@ uncompress jump table\n");\r
     if (ms) ot("CycloneInit\n");\r
     else    ot("CycloneInit:\n");\r
-    ot("  ldr r12,=JumpTab\n");\r
+    ot("  ldr r12,=CycloneJumpTab\n");\r
     ot("  add r0,r12,#0xe000*4 ;@ ctrl code pointer\n");\r
     ot("  ldr r1,[r0,#-4]\n");\r
     ot("  tst r1,r1\n");\r
@@ -187,7 +237,7 @@ static void PrintFramework()
     ot("  bgt unc_loop_in\n");\r
     ot("  b unc_loop\n");\r
     ot("unc_finish%s\n", ms?"":":");\r
-    ot("  ldr r12,=JumpTab\n");\r
+    ot("  ldr r12,=CycloneJumpTab\n");\r
     ot("  ;@ set a-line and f-line handlers\n");\r
     ot("  add r0,r12,#0xa000*4\n");\r
     ot("  ldr r1,[r0,#4] ;@ a-line handler\n");\r
@@ -254,8 +304,28 @@ 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("DoInterrupt%s\n", ms?"":":");\r
+  ot("CycloneDoInterrupt%s\n", ms?"":":");\r
   ot("  stmdb sp!,{lr} ;@ Push ARM return address\n");\r
 \r
   ot(";@ Get IRQ Vector address:\n");\r
@@ -465,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
@@ -472,10 +545,7 @@ 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("JumpTab%s\n", ms?"":":");\r
+       ot("CycloneJumpTab%s\n", ms?"":":");\r
        if(ms) {\r
          for(i = 0; i < 0xa000/8; i++)\r
            ot("  dcd 0,0,0,0,0,0,0,0\n");\r
@@ -548,7 +618,7 @@ static void PrintJumpTable()
        ot("\n");\r
        free(indexes);\r
 #else\r
-       ot("JumpTab%s\n", ms?"":":");\r
+       ot("CycloneJumpTab%s\n", ms?"":":");\r
     len=0xfffe; // Hmmm, armasm 2.50.8684 messes up with a 0x10000 long jump table\r
                 // notaz: same thing with GNU as 2.9-psion-98r2 (reloc overflow)\r
                 // this is due to COFF objects using only 2 bytes for reloc count\r
@@ -602,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
@@ -612,7 +683,12 @@ 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
+    ot("  .global CycloneJumpTab\n");\r
+#endif\r
     ot("CycloneVer: .long 0x%.4x\n",CycloneVer);\r
   }\r
   ot("\n");\r
@@ -623,6 +699,8 @@ static int CycloneMake()
 \r
   if (ms) ot("  END\n");\r
 \r
+  ot("\n\n;@ vim:filetype=armasm\n");\r
+\r
   fclose(AsmFile); AsmFile=NULL;\r
 \r
 #if 0\r