sound, increase resolution for calculating psg sound
authorkub <derkub@gmail.com>
Sat, 2 Oct 2021 19:13:48 +0000 (21:13 +0200)
committerkub <derkub@gmail.com>
Sat, 2 Oct 2021 19:31:51 +0000 (21:31 +0200)
pico/memory.c
pico/sms.c
pico/sound/sound.c

index 0487546..4d2cb7a 100644 (file)
@@ -396,19 +396,13 @@ void NOINLINE ctl_write_z80reset(u32 d)
 \r
 static void psg_write_68k(u32 d)\r
 {\r
-  // look for volume write and update if needed\r
-  if ((d & 0x90) == 0x90)\r
-    PsndDoPSG(z80_cycles_from_68k());\r
-\r
+  PsndDoPSG(z80_cycles_from_68k());\r
   SN76496Write(d);\r
 }\r
 \r
 static void psg_write_z80(u32 d)\r
 {\r
-  if ((d & 0x90) == 0x90) {\r
-    PsndDoPSG(z80_cyclesDone());\r
-  }\r
-\r
+  PsndDoPSG(z80_cyclesDone());\r
   SN76496Write(d);\r
 }\r
 \r
index 57181a3..8b37312 100644 (file)
@@ -202,8 +202,7 @@ static void z80_sms_out(unsigned short a, unsigned char d)
 
       case 0x40:
       case 0x41:
-        if ((d & 0x90) == 0x90)
-          PsndDoPSG(Pico.m.scanline);
+        PsndDoPSG(z80_cyclesDone());
         SN76496Write(d);
         break;
 
@@ -373,6 +372,7 @@ void PicoFrameMS(void)
     }
 
     cycles_aim += cycles_line;
+    Pico.t.z80c_aim = cycles_aim >> 8;
     cycles_done += z80_run((cycles_aim - cycles_done) >> 8) << 8;
   }
 
index 69cd4fb..602f290 100644 (file)
@@ -130,6 +130,10 @@ PICO_INTERNAL void PsndDoDAC(int cyc_to)
   // number of samples to fill in buffer (Q20)\r
   len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.dac_pos;\r
 \r
+  // don't do this too often (about once every 2 scanlines)\r
+  if (len <= PicoIn.sndRate << 3) // Q16, (PicoIn.sndRate << 16) >> 13\r
+    return;\r
+\r
   // update position and calculate buffer offset and length\r
   pos = (Pico.snd.dac_pos+0x80000) >> 20;\r
   Pico.snd.dac_pos += len;\r
@@ -169,17 +173,17 @@ PICO_INTERNAL void PsndDoPSG(int cyc_to)
   // number of samples to fill in buffer (Q20)\r
   len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.psg_pos;\r
 \r
+  // don't do this too often (about once every 2 scanlines)\r
+  if (len <= PicoIn.sndRate << 3) // Q16, (PicoIn.sndRate << 16) >> 13\r
+    return;\r
+\r
   // update position and calculate buffer offset and length\r
   pos = (Pico.snd.psg_pos+0x80000) >> 20;\r
   Pico.snd.psg_pos += len;\r
   len = ((Pico.snd.psg_pos+0x80000) >> 20) - pos;\r
 \r
-  // avoid loss of the 1st sample of a new block (Q rounding issues)\r
-  if (pos+len == 0)\r
-    len = 1, Pico.snd.psg_pos += 0x80000;\r
   if (len <= 0)\r
     return;\r
-\r
   if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG))\r
     return;\r
 \r
@@ -200,17 +204,17 @@ PICO_INTERNAL void PsndDoYM2413(int cyc_to)
   // number of samples to fill in buffer (Q20)\r
   len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.ym2413_pos;\r
 \r
+  // don't do this too often (about once every 2 scanlines)\r
+  if (len <= PicoIn.sndRate << 3) // Q16, (PicoIn.sndRate << 16) >> 13\r
+    return;\r
+\r
   // update position and calculate buffer offset and length\r
   pos = (Pico.snd.ym2413_pos+0x80000) >> 20;\r
   Pico.snd.ym2413_pos += len;\r
   len = ((Pico.snd.ym2413_pos+0x80000) >> 20) - pos;\r
 \r
-  // avoid loss of the 1st sample of a new block (Q rounding issues)\r
-  if (pos+len == 0)\r
-    len = 1, Pico.snd.ym2413_pos += 0x80000;\r
   if (len <= 0)\r
     return;\r
-\r
   if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_YM2413))\r
     return;\r
 \r
@@ -244,14 +248,16 @@ PICO_INTERNAL void PsndDoFM(int cyc_to)
   // Q16, number of samples since last call\r
   len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.fm_pos;\r
 \r
-  // don't do this too often (about once every 4 scanlines)\r
-  if (len <= PicoIn.sndRate << 4) // Q16, (PicoIn.sndRate << 16) >> 12\r
+  // don't do this too often (about once every 2 scanlines)\r
+  if (len <= PicoIn.sndRate << 3) // Q16, (PicoIn.sndRate << 16) >> 13\r
     return;\r
 \r
   // update position and calculate buffer offset and length\r
   pos = (Pico.snd.fm_pos+0x80000) >> 20;\r
   Pico.snd.fm_pos += len;\r
   len = ((Pico.snd.fm_pos+0x80000) >> 20) - pos;\r
+  if (len <= 0)\r
+    return;\r
 \r
   // fill buffer\r
   if (PicoIn.opt & POPT_EN_STEREO) {\r
@@ -334,7 +340,7 @@ static int PsndRender(int offset, int length)
   int stereo = (PicoIn.opt & 8) >> 3;\r
   int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);\r
   int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);\r
-  int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);\r
+  int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);\r
 \r
   buf32 = PsndBuffer+(offset<<stereo);\r
 \r
@@ -361,7 +367,7 @@ static int PsndRender(int offset, int length)
   // Add in parts of the PSG output not yet done\r
   if (length-psglen > 0) {\r
     short *psgbuf = PicoIn.sndOut + (psglen << stereo);\r
-    Pico.snd.psg_pos += (length-psglen) << 16;\r
+    Pico.snd.psg_pos += (length-psglen) << 20;\r
     if (PicoIn.opt & POPT_EN_PSG)\r
       SN76496Update(psgbuf, length-psglen, stereo);\r
   }\r
@@ -418,22 +424,22 @@ PICO_INTERNAL void PsndGetSamples(int y)
 static int PsndRenderMS(int offset, int length)\r
 {\r
   int stereo = (PicoIn.opt & 8) >> 3;\r
-  int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);\r
-  int ym2413len = ((Pico.snd.ym2413_pos+0x8000) >> 16);\r
+  int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);\r
+  int ym2413len = ((Pico.snd.ym2413_pos+0x80000) >> 20);\r
 \r
   pprof_start(sound);\r
 \r
   // Add in parts of the PSG output not yet done\r
   if (length-psglen > 0) {\r
     short *psgbuf = PicoIn.sndOut + (psglen << stereo);\r
-    Pico.snd.psg_pos += (length-psglen) << 16;\r
+    Pico.snd.psg_pos += (length-psglen) << 20;\r
     if (PicoIn.opt & POPT_EN_PSG)\r
       SN76496Update(psgbuf, length-psglen, stereo);\r
   }\r
 \r
   if (length-ym2413len > 0) {\r
     short *ym2413buf = PicoIn.sndOut + (ym2413len << stereo);\r
-    Pico.snd.ym2413_pos += (length-ym2413len) << 16;\r
+    Pico.snd.ym2413_pos += (length-ym2413len) << 20;\r
     int len = (length-ym2413len);\r
     if (PicoIn.opt & POPT_EN_YM2413){\r
       while (len-- > 0) {\r