sound, improve ym2612 timers implementation
authorkub <derkub@gmail.com>
Thu, 22 Jun 2023 22:16:47 +0000 (22:18 +0002)
committerkub <derkub@gmail.com>
Fri, 23 Jun 2023 19:23:52 +0000 (19:25 +0002)
pico/debug.c
pico/memory.c
pico/pico_cmn.c
pico/pico_int.h

index e881089..e928d73 100644 (file)
@@ -406,7 +406,7 @@ void PDebugZ80Frame(void)
   if (PicoIn.sndOut)
     PsndGetSamples(lines);
 
-  timers_cycle();
+  timers_cycle(Pico.t.z80c_aim);
   Pico.t.m68c_aim = Pico.t.m68c_cnt;
 }
 
index 3267a16..a9398b8 100644 (file)
@@ -1136,31 +1136,26 @@ static int ym2612_write_local(u32 a, u32 d, int is_from_z80)
                                      : ((ym2612.OPN.ST.TA & 0x3fc)|(d&3));\r
           if (ym2612.OPN.ST.TA != TAnew)\r
           {\r
+            int cycles = is_from_z80 ? z80_cyclesDone() : z80_cycles_from_68k();\r
+            ym2612_sync_timers(cycles, ym2612.OPN.ST.mode, ym2612.OPN.ST.mode);\r
             //elprintf(EL_STATUS, "timer a set %i", TAnew);\r
             ym2612.OPN.ST.TA = TAnew;\r
             //ym2612.OPN.ST.TAC = (1024-TAnew)*18;\r
             //ym2612.OPN.ST.TAT = 0;\r
             Pico.t.timer_a_step = TIMER_A_TICK_ZCYCLES * (1024 - TAnew);\r
-            if (ym2612.OPN.ST.mode & 1) {\r
-              // this is not right, should really be done on overflow only\r
-              int cycles = is_from_z80 ? z80_cyclesDone() : z80_cycles_from_68k();\r
-              Pico.t.timer_a_next_oflow = (cycles << 8) + Pico.t.timer_a_step;\r
-            }\r
             elprintf(EL_YMTIMER, "timer a set to %i, %i", 1024 - TAnew, Pico.t.timer_a_next_oflow>>8);\r
           }\r
           return 0;\r
         }\r
         case 0x26: // timer B\r
           if (ym2612.OPN.ST.TB != d) {\r
+            int cycles = is_from_z80 ? z80_cyclesDone() : z80_cycles_from_68k();\r
+            ym2612_sync_timers(cycles, ym2612.OPN.ST.mode, ym2612.OPN.ST.mode);\r
             //elprintf(EL_STATUS, "timer b set %i", d);\r
             ym2612.OPN.ST.TB = d;\r
             //ym2612.OPN.ST.TBC = (256-d) * 288;\r
             //ym2612.OPN.ST.TBT  = 0;\r
             Pico.t.timer_b_step = TIMER_B_TICK_ZCYCLES * (256 - d); // 262800\r
-            if (ym2612.OPN.ST.mode & 2) {\r
-              int cycles = is_from_z80 ? z80_cyclesDone() : z80_cycles_from_68k();\r
-              Pico.t.timer_b_next_oflow = (cycles << 8) + Pico.t.timer_b_step;\r
-            }\r
             elprintf(EL_YMTIMER, "timer b set to %i, %i", 256 - d, Pico.t.timer_b_next_oflow>>8);\r
           }\r
           return 0;\r
index 2be1c47..2f1747f 100644 (file)
@@ -345,7 +345,7 @@ static int PicoFrameHints(void)
   // get samples from sound chips
   PsndGetSamples(y);
 
-  timers_cycle();
+  timers_cycle(Pico.t.z80c_aim);
 
   pv->hint_cnt = hint;
 
index 055f5ee..d8b7160 100644 (file)
@@ -872,16 +872,18 @@ void ym2612_pack_state(void);
 void ym2612_unpack_state(void);\r
 \r
 #define TIMER_NO_OFLOW 0x70000000\r
-// tA =   72 * (1024 - NA) / M, with M = mclock/2 -> tick = 72 * 2/mclock\r
-#define TIMER_A_TICK_ZCYCLES  17203 // zcycles = Q8*tick*zclock = Q8*77*2*7/15\r
-// tB = 1152 * (256 - NA) / M,\r
-#define TIMER_B_TICK_ZCYCLES 275251 // zcycles = Q8*1152*2*7/15\r
 \r
-#define timers_cycle() \\r
+// NB ~0.2% timers speed up (1/8(A), 2(B) z80 cycles), HACK for A/V sync in OD2\r
+// tA =    72 * (1024 - TA) / M, with M = mclock/2\r
+#define TIMER_A_TICK_ZCYCLES (cycles_68k_to_z80(256LL*   72*2)-32) // Q8\r
+// tB = 16*72 * ( 256 - TB) / M\r
+#define TIMER_B_TICK_ZCYCLES (cycles_68k_to_z80(256LL*16*72*2)-32*16) // Q8\r
+\r
+#define timers_cycle(ticks) \\r
   if (Pico.t.timer_a_next_oflow > 0 && Pico.t.timer_a_next_oflow < TIMER_NO_OFLOW) \\r
-    Pico.t.timer_a_next_oflow -= Pico.m.pal ? 70938*256 : 59659*256; \\r
+    Pico.t.timer_a_next_oflow -= ticks << 8; \\r
   if (Pico.t.timer_b_next_oflow > 0 && Pico.t.timer_b_next_oflow < TIMER_NO_OFLOW) \\r
-    Pico.t.timer_b_next_oflow -= Pico.m.pal ? 70938*256 : 59659*256; \\r
+    Pico.t.timer_b_next_oflow -= ticks << 8; \\r
   ym2612_sync_timers(0, ym2612.OPN.ST.mode, ym2612.OPN.ST.mode);\r
 \r
 #define timers_reset() \\r