}\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
}\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
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
\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
{\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
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
// 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
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
PsndLen_use++;\r
}\r
\r
- PsndDacLine = 0;\r
+ PsndDacLine = PsndPsgLine = 0;\r
emustatus &= ~1;\r
dac_info[224] = PsndLen_use;\r
}\r
\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
\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
\r
if (ym2612.dacen && PsndDacLine < y)\r
PsndDoDAC(y - 1);\r
+ PsndDoPSG(y - 1);\r
\r
if (y == 224)\r
{\r