core, revisit ym2612 busy flag implementation
authorkub <derkub@gmail.com>
Sat, 22 Jun 2024 21:12:31 +0000 (23:12 +0200)
committerkub <derkub@gmail.com>
Thu, 27 Jun 2024 21:39:44 +0000 (23:39 +0200)
pico/memory.c
pico/pico_int.h
pico/sound/ym2612.c
pico/sound/ym2612.h
platform/gp2x/code940/940.c

index de5e3e5..b1c917a 100644 (file)
@@ -1174,7 +1174,7 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
 \r
       // the busy flag in the YM2612 status is actually a 32 cycle timer\r
       // (89.6 Z80 cycles), triggered by any write to the data port.\r
-      Pico.t.ym2612_busy = (cycles + 90) << 8; // Q8 for convenience\r
+      Pico.t.ym2612_busy = (cycles << 8) + YMBUSY_ZCYCLES; // Q8 for convenience\r
 \r
       switch (addr)\r
       {\r
@@ -1284,9 +1284,11 @@ static u32 ym2612_read_local_68k(void)
 void ym2612_pack_state(void)\r
 {\r
   // timers are saved as tick counts, in 16.16 int format\r
-  int tac, tat = 0, tbc, tbt = 0;\r
+  int tac, tat = 0, tbc, tbt = 0, busy = 0;\r
   tac = 1024 - ym2612.OPN.ST.TA;\r
   tbc = 256  - ym2612.OPN.ST.TB;\r
+  if (Pico.t.ym2612_busy > 0)\r
+    busy = cycles_z80_to_68k(Pico.t.ym2612_busy);\r
   if (Pico.t.timer_a_next_oflow != TIMER_NO_OFLOW)\r
     tat = (int)((double)(Pico.t.timer_a_step - Pico.t.timer_a_next_oflow)\r
           / (double)Pico.t.timer_a_step * tac * 65536);\r
@@ -1301,12 +1303,12 @@ void ym2612_pack_state(void)
     YM2612PicoStateSave2_940(tat, tbt);\r
   else\r
 #endif\r
-    YM2612PicoStateSave2(tat, tbt);\r
+    YM2612PicoStateSave2(tat, tbt, busy);\r
 }\r
 \r
 void ym2612_unpack_state(void)\r
 {\r
-  int i, ret, tac, tat, tbc, tbt;\r
+  int i, ret, tac, tat, tbc, tbt, busy = 0;\r
   YM2612PicoStateLoad();\r
 \r
   // feed all the registers and update internal state\r
@@ -1336,12 +1338,13 @@ void ym2612_unpack_state(void)
     ret = YM2612PicoStateLoad2_940(&tat, &tbt);\r
   else\r
 #endif\r
-    ret = YM2612PicoStateLoad2(&tat, &tbt);\r
+    ret = YM2612PicoStateLoad2(&tat, &tbt, &busy);\r
   if (ret != 0) {\r
     elprintf(EL_STATUS, "old ym2612 state");\r
     return; // no saved timers\r
   }\r
 \r
+  Pico.t.ym2612_busy = cycles_68k_to_z80(busy);\r
   tac = (1024 - ym2612.OPN.ST.TA) << 16;\r
   tbc = (256  - ym2612.OPN.ST.TB) << 16;\r
   if (ym2612.OPN.ST.mode & 1)\r
index 06f00c2..79997d9 100644 (file)
@@ -209,6 +209,7 @@ extern struct DrZ80 drZ80;
 \r
 // 68k clock = OSC/7, z80 clock = OSC/15, 68k:z80 ratio = 7/15 = 3822.9/8192\r
 #define cycles_68k_to_z80(x) ((x) * 3823 >> 13)\r
+#define cycles_z80_to_68k(x) ((x) * 8777 >> 12)\r
 \r
 // ----------------------- SH2 CPU -----------------------\r
 \r
@@ -898,10 +899,12 @@ void ym2612_unpack_state(void);
 \r
 #define TIMER_NO_OFLOW 0x70000000\r
 \r
-// tA =    72 * (1024 - TA) / M, with M = mclock/2\r
-#define TIMER_A_TICK_ZCYCLES cycles_68k_to_z80(256LL*   72*2) // Q8\r
-// tB = 16*72 * ( 256 - TB) / M\r
-#define TIMER_B_TICK_ZCYCLES cycles_68k_to_z80(256LL*16*72*2) // Q8\r
+// tA =    24*3 * (1024 - TA) / M, with M = mclock/2\r
+#define TIMER_A_TICK_ZCYCLES cycles_68k_to_z80(256LL*   24*3*2) // Q8\r
+// tB = 16*24*3 * ( 256 - TB) / M\r
+#define TIMER_B_TICK_ZCYCLES cycles_68k_to_z80(256LL*16*24*3*2) // Q8\r
+// busy =  32*3 / M\r
+#define YMBUSY_ZCYCLES       cycles_68k_to_z80(256LL*   32*3*2) // Q8\r
 \r
 #define timers_cycle(ticks) \\r
   if (Pico.t.ym2612_busy > 0) \\r
index f0e60b4..ee84da2 100644 (file)
@@ -2049,7 +2049,7 @@ typedef struct
        UINT32  eg_timer;\r
        UINT32  lfo_cnt;\r
        UINT16  lfo_ampm;\r
-       UINT16  unused2;\r
+       INT16   busy_timer;\r
        UINT32  keyon_field;    // 20\r
        UINT32  kcode_fc_sl3_3;\r
        UINT32  reserved[2];\r
@@ -2063,7 +2063,7 @@ typedef struct
 } ym_save_addon2;\r
 \r
 \r
-void YM2612PicoStateSave2(int tat, int tbt)\r
+void YM2612PicoStateSave2(int tat, int tbt, int busy)\r
 {\r
        ym_save_addon_slot ss;\r
        ym_save_addon2 sa2;\r
@@ -2121,10 +2121,11 @@ void YM2612PicoStateSave2(int tat, int tbt)
        sa.eg_timer = ym2612.OPN.eg_timer;\r
        sa.lfo_cnt  = ym2612.OPN.lfo_cnt;\r
        sa.lfo_ampm = g_lfo_ampm;\r
+       sa.busy_timer = busy;\r
        memcpy(ptr, &sa, sizeof(sa)); // 0x30 max\r
 }\r
 \r
-int YM2612PicoStateLoad2(int *tat, int *tbt)\r
+int YM2612PicoStateLoad2(int *tat, int *tbt, int *busy)\r
 {\r
        ym_save_addon_slot ss;\r
        ym_save_addon2 sa2;\r
@@ -2150,6 +2151,7 @@ int YM2612PicoStateLoad2(int *tat, int *tbt)
        g_lfo_ampm = sa.lfo_ampm;\r
        if (tat != NULL) *tat = sa.TAT;\r
        if (tbt != NULL) *tbt = sa.TBT;\r
+       if (busy != NULL) *busy = sa.busy_timer;\r
 \r
        // chans 1,2,3\r
        ptr = &ym2612.REGS[0x0b8];\r
index b981a42..56ec5ef 100644 (file)
@@ -177,8 +177,8 @@ int  YM2612PicoTick_(int n);
 void YM2612PicoStateLoad_(void);\r
 \r
 void *YM2612GetRegs(void);\r
-void YM2612PicoStateSave2(int tat, int tbt);\r
-int  YM2612PicoStateLoad2(int *tat, int *tbt);\r
+void YM2612PicoStateSave2(int tat, int tbt, int busy);\r
+int  YM2612PicoStateLoad2(int *tat, int *tbt, int *busy);\r
 \r
 /* NB must be macros for compiling GP2X 940 code */\r
 #ifndef __GP2X__\r
index 4ab8bad..60be15c 100644 (file)
@@ -187,7 +187,7 @@ void Main940(void)
                                break;\r
 \r
                        case JOB940_PICOSTATESAVE2:\r
-                               YM2612PicoStateSave2(0, 0);\r
+                               YM2612PicoStateSave2(0, 0, 0);\r
                                memcpy(shared_ctl->writebuff0, ym2612_940->REGS, 0x200);\r
                                break;\r
 \r
@@ -197,7 +197,7 @@ void Main940(void)
 \r
                        case JOB940_PICOSTATELOAD2:\r
                                memcpy(ym2612_940->REGS, shared_ctl->writebuff0, 0x200);\r
-                               YM2612PicoStateLoad2(0, 0);\r
+                               YM2612PicoStateLoad2(0, 0, 0);\r
                                break;\r
 \r
                        case JOB940_YM2612UPDATEONE:\r