From: notaz <notasas@gmail.com>
Date: Tue, 19 Sep 2017 21:47:59 +0000 (+0300)
Subject: pass jumptable ptr from C
X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b889883d36b2d247488c82d79d1eaab4dd41d236;p=cyclone68000.git

pass jumptable ptr from C

Doing it from asm is painful because different platforms want it done
differently, last try had R_ARM_REL32 relocs that ld.gold didn't like.
This will also allow multiple jumptables which may be useful.
---

diff --git a/Cyclone.h b/Cyclone.h
index fdcff59..f3c1835 100644
--- a/Cyclone.h
+++ b/Cyclone.h
@@ -19,6 +19,8 @@ extern "C" {
 
 extern int CycloneVer; // Version number of library
 
+extern long CycloneJumpTab[65536]; // default jump table
+
 struct Cyclone
 {
   unsigned int d[8];    // [r7,#0x00]
@@ -55,10 +57,14 @@ struct Cyclone
 };
 
 // Initialize. Used only if Cyclone was compiled with compressed jumptable, see config.h
-void CycloneInit(void);
+#define CycloneInit() \
+	CycloneInitJT(CycloneJumpTab)
+void CycloneInitJT(void *jt);
 
 // Reset
-void CycloneReset(struct Cyclone *pcy);
+#define CycloneReset(pcy) \
+	CycloneResetJT(pcy, CycloneJumpTab)
+void CycloneResetJT(struct Cyclone *pcy, void *jt);
 
 // Run cyclone. Cycles should be specified in context (pcy->cycles)
 void CycloneRun(struct Cyclone *pcy);
@@ -78,7 +84,9 @@ void CyclonePack(const struct Cyclone *pcy, void *save_buffer);
 void CycloneUnpack(struct Cyclone *pcy, const void *save_buffer);
 
 // genesis: if 1, switch to normal TAS handlers
-void CycloneSetRealTAS(int use_real);
+#define CycloneSetRealTAS(use_real) \
+	CycloneSetRealTAS_JT(use_real, CycloneJumpTab)
+void CycloneSetRealTAS_JT(int use_real, void *jt);
 
 
 // These values are special return values for IrqCallback.
diff --git a/Main.cpp b/Main.cpp
index 400d3a6..7c6b8e3 100644
--- a/Main.cpp
+++ b/Main.cpp
@@ -127,13 +127,6 @@ static void ChangeTASGet(unsigned int i)
 }
 #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)
 {
@@ -237,14 +230,16 @@ static void PrintFramework()
   ot("\n");
   ot("\n");
 
-  ot("CycloneInit%s\n", ms?"":":");
+  ot("CycloneInitJT%s\n", ms?"":":");
 #if COMPRESS_JUMPTABLE
   ot(";@ decompress jump table\n");
-  LoadCycloneJumpTab(12, 1);
+  ot("  mov r12,r0 ;@ jump table\n");
   ot("  add r0,r12,#0xe000*4 ;@ ctrl code pointer\n");
   ot("  ldr r1,[r0,#-4]\n");
   ot("  tst r1,r1\n");
   ot("  movne pc,lr ;@ already uncompressed\n");
+  ot("  stmfd sp!,{r7,lr}\n");
+  ot("  mov r7,r12 ;@ jump table\n");
   ot("  add r3,r12,#0xa000*4 ;@ handler table pointer, r12=dest\n");
   ot("unc_loop%s\n", ms?"":":");
   ot("  ldrh r1,[r0],#2\n");
@@ -266,9 +261,8 @@ static void PrintFramework()
   ot("  bgt unc_loop_in\n");
   ot("  b unc_loop\n");
   ot("unc_finish%s\n", ms?"":":");
-  LoadCycloneJumpTab(12, 1);
   ot("  ;@ set a-line and f-line handlers\n");
-  ot("  add r0,r12,#0xa000*4\n");
+  ot("  add r0,r7,#0xa000*4\n");
   ot("  ldr r1,[r0,#4] ;@ a-line handler\n");
   ot("  ldr r3,[r0,#8] ;@ f-line handler\n");
   ot("  mov r2,#0x1000\n");
@@ -276,31 +270,29 @@ static void PrintFramework()
   ot("  subs r2,r2,#1\n");
   ot("  str r1,[r0],#4\n");
   ot("  bgt unc_fill3\n");
-  ot("  add r0,r12,#0xf000*4\n");
+  ot("  add r0,r7,#0xf000*4\n");
   ot("  mov r2,#0x1000\n");
   ot("unc_fill4%s\n", ms?"":":");
   ot("  subs r2,r2,#1\n");
   ot("  str r3,[r0],#4\n");
   ot("  bgt unc_fill4\n");
-  ot("  bx lr\n");
+  ot("  ldmfd sp!,{r7,pc}\n");
   ltorg();
 #else
   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("  add r0,r0,#0x10000*4\n");
+  ot("  ldr r1,[r0,#-3*4]\n");
+  ot("  str r1,[r0,#-2*4]\n");
+  ot("  str r1,[r0,#-1*4]\n");
   ot("  bx lr\n");
 #endif
   ot("\n");
 
   // --------------
-  ot("CycloneReset%s\n", ms?"":":");
+  ot("CycloneResetJT%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("  str r1,[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");
@@ -324,11 +316,10 @@ static void PrintFramework()
   ot("\n");
 
   // --------------
-  ot("CycloneSetRealTAS%s\n", ms?"":":");
+  ot("CycloneSetRealTAS_JT%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,r1,#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]));
@@ -382,8 +373,6 @@ static void PrintFramework()
 
   // --------------
   // 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++)
@@ -1290,8 +1279,8 @@ static int CycloneMake()
   for(i=0xf000; i<0x10000; i++) CyJump[i] = -3; // f-line emulation
 
   ot(ms?"  area |.text|, code\n":"  .text\n  .align 4\n\n");
-  ot("  %s CycloneInit\n",globl);
-  ot("  %s CycloneReset\n",globl);
+  ot("  %s CycloneInitJT\n",globl);
+  ot("  %s CycloneResetJT\n",globl);
   ot("  %s CycloneRun\n",globl);
   ot("  %s CycloneSetSr\n",globl);
   ot("  %s CycloneGetSr\n",globl);
@@ -1300,7 +1289,7 @@ static int CycloneMake()
   ot("  %s CycloneUnpack\n",globl);
   ot("  %s CycloneVer\n",globl);
 #if (CYCLONE_FOR_GENESIS == 2)
-  ot("  %s CycloneSetRealTAS\n",globl);
+  ot("  %s CycloneSetRealTAS_JT\n",globl);
   ot("  %s CycloneDoInterrupt\n",globl);
   ot("  %s CycloneDoTrace\n",globl);
   ot("  %s CycloneJumpTab\n",globl);
diff --git a/tools/idle.h b/tools/idle.h
index 254cc57..d8c4133 100644
--- a/tools/idle.h
+++ b/tools/idle.h
@@ -1,3 +1,8 @@
 
-void CycloneInitIdle(void);
-void CycloneFinishIdle(void);
+void CycloneInitIdleJT(void *jt);
+void CycloneFinishIdleJT(void *jt);
+
+#define CycloneInitIdle() \
+	CycloneInitIdleJT(CycloneJumpTab)
+#define CycloneFinishIdle() \
+	CycloneFinishIdleJT(CycloneJumpTab)
diff --git a/tools/idle.s b/tools/idle.s
index f36588f..7ac8520 100644
--- a/tools/idle.s
+++ b/tools/idle.s
@@ -8,11 +8,17 @@
 .data
 .align 2
 
+idle_data:
 have_patches:
   .word 0
+  .word Op____
+  .word Op6002
+  .word Op6602
+  .word Op6702
 
 .equ patch_desc_table_size, 10
 
+@       to             from
 patch_desc_table:
   .word (0x71fa<<16) | 0x66fa, idle_detector_bcc8, idle_bne, Op6602  @ bne.s
   .word (0x71f8<<16) | 0x66f8, idle_detector_bcc8, idle_bne, Op6602  @ bne.s
@@ -30,13 +36,12 @@ patch_desc_table:
 .align 2
 
 
-.global CycloneInitIdle
+.global CycloneInitIdleJT @ jt
 
-CycloneInitIdle:
+CycloneInitIdleJT:
     adr     r12,offset_table
-    ldr     r3, [r12, #2*4] @ =CycloneJumpTab-ot
     ldr     r2, [r12, #1*4] @ =patch_desc_table-ot
-    add     r3, r3, r12
+    mov     r3, r0          @ =CycloneJumpTab
     add     r2, r2, r12
     mov     r12,#patch_desc_table_size
 
@@ -55,29 +60,27 @@ cii_loop:
     bgt     cii_loop
 
     adr     r12,offset_table
-    ldr     r0, [r12, #0*4] @ =have_patches-ot
+    ldr     r0, [r12, #0*4] @ =idle_data-ot
     mov     r1, #1
-    str     r1, [r0, r12]
+    str     r1, [r0, r12]   @ have_patches
     bx      lr
 
 
-.global CycloneFinishIdle
+.global CycloneFinishIdleJT @ jt
 
-CycloneFinishIdle:
+CycloneFinishIdleJT:
     adr     r12,offset_table
-    ldr     r3, [r12, #0*4] @ =have_patches-ot
-    ldr     r0, [r3, r12]!
-    tst     r0, r0
+    ldr     r3, [r12, #0*4] @ =idle_data-ot
+    ldr     r1, [r3, r12]!  @ have_patches
+    tst     r1, r1
     bxeq    lr
 
     stmfd   sp!, {r4,r5}
     mov     r5, r3
     ldr     r2, [r12, #1*4] @ =patch_desc_table-ot
-    ldr     r3, [r12, #2*4] @ =CycloneJumpTab-ot
-    ldr     r4, [r12, #3*4] @ =Op____-ot
-    add     r2, r2, r12
-    add     r3, r3, r12
-    add     r4, r4, r12
+    mov     r3, r0          @ =CycloneJumpTab
+    ldr     r4, [r5, #1*4]  @ =Op____
+    add     r2, r2, r12     @ =patch_desc_table
     mov     r12,#patch_desc_table_size
 
 cfi_loop:
@@ -165,12 +168,13 @@ idle_detector_bcc8:
 
     @ remove detector from Cyclone
     adr     r12,offset_table
+    ldr     r1, [r12]       @ =idle_data-ot
     mov     r0, r8, lsr #8
     cmp     r0, #0x66
-    ldrlt   r1, [r12, #4*4] @ =Op6002-ot
-    ldreq   r1, [r12, #4*5] @ =Op6602-ot
-    ldrgt   r1, [r12, #4*6] @ =Op6702-ot
-    add     r1, r1, r12
+    add     r1, r1, r12     @ =idle_data
+    ldrlt   r1, [r1, #4*2]  @ =Op6002-ot
+    ldreq   r1, [r1, #4*3]  @ =Op6602-ot
+    ldrgt   r1, [r1, #4*4]  @ =Op6702-ot
 
     str     r1, [r6, r8, lsl #2]
     bx      r1
@@ -183,10 +187,5 @@ exit_detector:
     b       Op6702
 
 offset_table:
-    .word have_patches - offset_table
+    .word idle_data - offset_table
     .word patch_desc_table - offset_table
-    .word CycloneJumpTab - offset_table
-    .word Op____ - offset_table
-    .word Op6002 - offset_table
-    .word Op6602 - offset_table     @ 5
-    .word Op6702 - offset_table