handle frequent psg updates
authornotaz <notasas@gmail.com>
Sat, 30 Sep 2017 19:55:57 +0000 (22:55 +0300)
committernotaz <notasas@gmail.com>
Fri, 6 Oct 2017 22:36:59 +0000 (01:36 +0300)
pico/memory.c
pico/pico_cmn.c
pico/pico_int.h
pico/sound/sound.c

index fb5fa9b..0907696 100644 (file)
@@ -385,6 +385,28 @@ void NOINLINE ctl_write_z80reset(u32 d)
   }\r
 }\r
 \r
+static int get_scanline(int is_from_z80);\r
+\r
+static void psg_write_68k(u32 d)\r
+{\r
+  // look for volume write and update if needed\r
+  if ((d & 0x90) == 0x90 && PsndPsgLine < Pico.m.scanline)\r
+    PsndDoPSG(Pico.m.scanline);\r
+\r
+  SN76496Write(d);\r
+}\r
+\r
+static void psg_write_z80(u32 d)\r
+{\r
+  if ((d & 0x90) == 0x90) {\r
+    int scanline = get_scanline(1);\r
+    if (PsndPsgLine < scanline)\r
+      PsndDoPSG(scanline);\r
+  }\r
+\r
+  SN76496Write(d);\r
+}\r
+\r
 // -----------------------------------------------------------------\r
 \r
 #ifndef _ASM_MEMORY_C\r
@@ -528,8 +550,7 @@ static void PicoWrite8_z80(u32 a, u32 d)
   }\r
   // TODO: probably other VDP access too? Maybe more mirrors?\r
   if ((a & 0x7ff9) == 0x7f11) { // PSG Sound\r
-    if (PicoOpt & POPT_EN_PSG)\r
-      SN76496Write(d);\r
+    psg_write_68k(d);\r
     return;\r
   }\r
   if ((a & 0x7f00) == 0x6000) // Z80 BANK register\r
@@ -703,8 +724,7 @@ static u32 PicoRead16_vdp(u32 a)
 static void PicoWrite8_vdp(u32 a, u32 d)\r
 {\r
   if ((a & 0x00f9) == 0x0011) { // PSG Sound\r
-    if (PicoOpt & POPT_EN_PSG)\r
-      SN76496Write(d);\r
+    psg_write_68k(d);\r
     return;\r
   }\r
   if ((a & 0x00e0) == 0x0000) {\r
@@ -718,11 +738,8 @@ static void PicoWrite8_vdp(u32 a, u32 d)
 \r
 static void PicoWrite16_vdp(u32 a, u32 d)\r
 {\r
-  if ((a & 0x00f9) == 0x0010) { // PSG Sound\r
-    if (PicoOpt & POPT_EN_PSG)\r
-      SN76496Write(d);\r
-    return;\r
-  }\r
+  if ((a & 0x00f9) == 0x0010) // PSG Sound\r
+    psg_write_68k(d);\r
   if ((a & 0x00e0) == 0x0000) {\r
     PicoVideoWrite(a, d);\r
     return;\r
@@ -1198,8 +1215,7 @@ static void z80_md_vdp_br_write(unsigned int a, unsigned char data)
 {\r
   if ((a&0xfff9) == 0x7f11) // 7f11 7f13 7f15 7f17\r
   {\r
-    if (PicoOpt & POPT_EN_PSG)\r
-      SN76496Write(data);\r
+    psg_write_z80(data);\r
     return;\r
   }\r
   // at least VDP data writes hang my machine\r
index b39cfdb..78fdd12 100644 (file)
@@ -264,6 +264,8 @@ static int PicoFrameHints(void)
     PicoSyncZ80(cycles);
   if (PsndOut && ym2612.dacen && PsndDacLine < lines)
     PsndDoDAC(lines - 1);
+  if (PsndOut && PsndPsgLine < lines)
+    PsndDoPSG(lines - 1);
 
 #ifdef PICO_CD
   if (PicoAHW & PAHW_MCD)
index 551dcbc..1276931 100644 (file)
@@ -822,10 +822,11 @@ PICO_INTERNAL_ASM void wram_1M_to_2M(unsigned char *m);
 PICO_INTERNAL void PsndReset(void);\r
 PICO_INTERNAL void PsndStartFrame(void);\r
 PICO_INTERNAL void PsndDoDAC(int line_to);\r
+PICO_INTERNAL void PsndDoPSG(int line_to);\r
 PICO_INTERNAL void PsndClear(void);\r
 PICO_INTERNAL void PsndGetSamples(int y);\r
 PICO_INTERNAL void PsndGetSamplesMS(void);\r
-extern int PsndDacLine;\r
+extern int PsndDacLine, PsndPsgLine;\r
 \r
 // sms.c\r
 #ifndef NO_SMS\r
index 8f88dd7..510a9ab 100644 (file)
@@ -19,7 +19,7 @@ void (*PsndMix_32_to_16l)(short *dest, int *src, int count) = mix_32_to_16l_ster
 // master int buffer to mix to\r
 static int PsndBuffer[2*(44100+100)/50];\r
 \r
-// dac\r
+// dac, psg\r
 static unsigned short dac_info[312+4]; // pos in sample buffer\r
 \r
 // cdda output buffer\r
@@ -30,7 +30,7 @@ int PsndRate=0;
 int PsndLen=0; // number of mono samples, multiply by 2 for stereo\r
 int PsndLen_exc_add=0; // this is for non-integer sample counts per line, eg. 22050/60\r
 int PsndLen_exc_cnt=0;\r
-int PsndDacLine=0;\r
+int PsndDacLine, PsndPsgLine;\r
 short *PsndOut=NULL; // PCM data buffer\r
 static int PsndLen_use;\r
 \r
@@ -158,7 +158,7 @@ PICO_INTERNAL void PsndStartFrame(void)
     PsndLen_use++;\r
   }\r
 \r
-  PsndDacLine = 0;\r
+  PsndDacLine = PsndPsgLine = 0;\r
   emustatus &= ~1;\r
   dac_info[224] = PsndLen_use;\r
 }\r
@@ -185,13 +185,42 @@ PICO_INTERNAL void PsndDoDAC(int line_to)
 \r
   if (PicoOpt & POPT_EN_STEREO) {\r
     short *d = PsndOut + pos*2;\r
-    for (; len > 0; len--, d+=2) *d = dout;\r
+    for (; len > 0; len--, d+=2) *d += dout;\r
   } else {\r
     short *d = PsndOut + pos;\r
-    for (; len > 0; len--, d++)  *d = dout;\r
+    for (; len > 0; len--, d++)  *d += dout;\r
   }\r
 }\r
 \r
+PICO_INTERNAL void PsndDoPSG(int line_to)\r
+{\r
+  int line_from = PsndPsgLine;\r
+  int pos, pos1, len;\r
+  int stereo = 0;\r
+\r
+  if (line_to >= 312)\r
+    line_to = 311;\r
+\r
+  pos  = dac_info[line_from];\r
+  pos1 = dac_info[line_to + 1];\r
+  len = pos1 - pos;\r
+  //elprintf(EL_STATUS, "%3d %3d %3d %3d %3d",\r
+  //  pos, pos1, len, line_from, line_to);\r
+  if (len <= 0)\r
+    return;\r
+\r
+  PsndPsgLine = line_to + 1;\r
+\r
+  if (!PsndOut || !(PicoOpt & POPT_EN_PSG))\r
+    return;\r
+\r
+  if (PicoOpt & POPT_EN_STEREO) {\r
+    stereo = 1;\r
+    pos <<= 1;\r
+  }\r
+  SN76496Update(PsndOut + pos, len, stereo);\r
+}\r
+\r
 // cdda\r
 static void cdda_raw_update(int *buffer, int length)\r
 {\r
@@ -264,10 +293,6 @@ static int PsndRender(int offset, int length)
 \r
   pprof_start(sound);\r
 \r
-  // PSG\r
-  if (PicoOpt & POPT_EN_PSG)\r
-    SN76496Update(PsndOut+offset, length, stereo);\r
-\r
   if (PicoAHW & PAHW_PICO) {\r
     PicoPicoPCMUpdate(PsndOut+offset, length, stereo);\r
     return length;\r
@@ -319,6 +344,7 @@ PICO_INTERNAL void PsndGetSamples(int y)
 \r
   if (ym2612.dacen && PsndDacLine < y)\r
     PsndDoDAC(y - 1);\r
+  PsndDoPSG(y - 1);\r
 \r
   if (y == 224)\r
   {\r