14 const static byte dmgwave
[16] =
16 0xac, 0xdd, 0xda, 0x48,
17 0x36, 0x02, 0xcf, 0x16,
18 0x2c, 0x04, 0xe5, 0x2c,
19 0xac, 0xdd, 0xda, 0x48
22 const static byte cgbwave
[16] =
24 0x00, 0xff, 0x00, 0xff,
25 0x00, 0xff, 0x00, 0xff,
26 0x00, 0xff, 0x00, 0xff,
27 0x00, 0xff, 0x00, 0xff,
30 const static byte sqwave
[4][8] =
32 { 0, 0,-1, 0, 0, 0, 0, 0 },
33 { 0,-1,-1, 0, 0, 0, 0, 0 },
34 { -1,-1,-1,-1, 0, 0, 0, 0 },
35 { -1, 0, 0,-1,-1,-1,-1,-1 }
38 const static int freqtab
[8] =
52 #define RATE (snd.rate)
53 #define WAVE (snd.wave) /* ram.hi+0x30 */
54 #define S1 (snd.ch[0])
55 #define S2 (snd.ch[1])
56 #define S3 (snd.ch[2])
57 #define S4 (snd.ch[3])
59 rcvar_t sound_exports
[] =
65 static void s1_freq_d(int d
)
67 if (RATE
> (d
<<4)) S1
.freq
= 0;
68 else S1
.freq
= (RATE
<< 17)/d
;
73 s1_freq_d(2048 - (((R_NR14
&7)<<8) + R_NR13
));
78 int d
= 2048 - (((R_NR24
&7)<<8) + R_NR23
);
79 if (RATE
> (d
<<4)) S2
.freq
= 0;
80 else S2
.freq
= (RATE
<< 17)/d
;
85 int d
= 2048 - (((R_NR34
&7)<<8) + R_NR33
);
86 if (RATE
> (d
<<3)) S3
.freq
= 0;
87 else S3
.freq
= (RATE
<< 21)/d
;
92 S4
.freq
= (freqtab
[R_NR43
&7] >> (R_NR43
>> 4)) * RATE
;
93 if (S4
.freq
>> 18) S4
.freq
= 1<<18;
98 S1
.swlen
= ((R_NR10
>>4) & 7) << 14;
99 S1
.len
= (64-(R_NR11
&63)) << 13;
100 S1
.envol
= R_NR12
>> 4;
101 S1
.endir
= (R_NR12
>>3) & 1;
102 S1
.endir
|= S1
.endir
- 1;
103 S1
.enlen
= (R_NR12
& 7) << 15;
105 S2
.len
= (64-(R_NR21
&63)) << 13;
106 S2
.envol
= R_NR22
>> 4;
107 S2
.endir
= (R_NR22
>>3) & 1;
108 S2
.endir
|= S2
.endir
- 1;
109 S2
.enlen
= (R_NR22
& 7) << 15;
111 S3
.len
= (256-R_NR31
) << 20;
113 S4
.len
= (64-(R_NR41
&63)) << 13;
114 S4
.envol
= R_NR42
>> 4;
115 S4
.endir
= (R_NR42
>>3) & 1;
116 S4
.endir
|= S4
.endir
- 1;
117 S4
.enlen
= (R_NR42
& 7) << 15;
123 memset(&S1
, 0, sizeof S1
);
124 memset(&S2
, 0, sizeof S2
);
125 memset(&S3
, 0, sizeof S3
);
126 memset(&S4
, 0, sizeof S4
);
150 memset(&snd
, 0, sizeof snd
);
151 if (pcm
.hz
) snd
.rate
= (1<<21) / pcm
.hz
;
153 memcpy(WAVE
, hw
.cgb
? cgbwave
: dmgwave
, 16);
154 memcpy(ram
.hi
+0x30, WAVE
, 16);
164 if (!RATE
|| cpu
.snd
< RATE
) return;
166 for (; cpu
.snd
>= RATE
; cpu
.snd
-= RATE
)
172 s
= sqwave
[R_NR11
>>6][(S1
.pos
>>18)&7] & S1
.envol
;
174 if ((R_NR14
& 64) && ((S1
.cnt
+= RATE
) >= S1
.len
))
176 if (S1
.enlen
&& (S1
.encnt
+= RATE
) >= S1
.enlen
)
178 S1
.encnt
-= S1
.enlen
;
179 S1
.envol
+= S1
.endir
;
180 if (S1
.envol
< 0) S1
.envol
= 0;
181 if (S1
.envol
> 15) S1
.envol
= 15;
183 if (S1
.swlen
&& (S1
.swcnt
+= RATE
) >= S1
.swlen
)
185 S1
.swcnt
-= S1
.swlen
;
188 if (R_NR10
& 8) f
-= (f
>> n
);
196 R_NR14
= (R_NR14
& 0xF8) | (f
>>8);
201 if (R_NR51
& 1) r
+= s
;
202 if (R_NR51
& 16) l
+= s
;
207 s
= sqwave
[R_NR21
>>6][(S2
.pos
>>18)&7] & S2
.envol
;
209 if ((R_NR24
& 64) && ((S2
.cnt
+= RATE
) >= S2
.len
))
211 if (S2
.enlen
&& (S2
.encnt
+= RATE
) >= S2
.enlen
)
213 S2
.encnt
-= S2
.enlen
;
214 S2
.envol
+= S2
.endir
;
215 if (S2
.envol
< 0) S2
.envol
= 0;
216 if (S2
.envol
> 15) S2
.envol
= 15;
219 if (R_NR51
& 2) r
+= s
;
220 if (R_NR51
& 32) l
+= s
;
225 s
= WAVE
[(S3
.pos
>>22) & 15];
226 if (S3
.pos
& (1<<21)) s
&= 15;
230 if ((R_NR34
& 64) && ((S3
.cnt
+= RATE
) >= S3
.len
))
232 if (R_NR32
& 96) s
<<= (3 - ((R_NR32
>>5)&3));
234 if (R_NR51
& 4) r
+= s
;
235 if (R_NR51
& 64) l
+= s
;
240 if (R_NR43
& 8) s
= 1 & (noise7
[
241 (S4
.pos
>>20)&15] >> (7-((S4
.pos
>>17)&7)));
242 else s
= 1 & (noise15
[
243 (S4
.pos
>>20)&4095] >> (7-((S4
.pos
>>17)&7)));
246 if ((R_NR44
& 64) && ((S4
.cnt
+= RATE
) >= S4
.len
))
248 if (S4
.enlen
&& (S4
.encnt
+= RATE
) >= S4
.enlen
)
250 S4
.encnt
-= S4
.enlen
;
251 S4
.envol
+= S4
.endir
;
252 if (S4
.envol
< 0) S4
.envol
= 0;
253 if (S4
.envol
> 15) S4
.envol
= 15;
256 if (R_NR51
& 8) r
+= s
;
257 if (R_NR51
& 128) l
+= s
;
260 l
*= (R_NR50
& 0x07);
261 r
*= ((R_NR50
& 0x70)>>4);
265 if (l
> 127) l
= 127;
266 else if (l
< -128) l
= -128;
267 if (r
> 127) r
= 127;
268 else if (r
< -128) r
= -128;
272 if (pcm
.pos
>= pcm
.len
)
276 pcm
.buf
[pcm
.pos
++] = l
+128;
277 pcm
.buf
[pcm
.pos
++] = r
+128;
279 else pcm
.buf
[pcm
.pos
++] = ((l
+r
)>>1)+128;
282 R_NR52
= (R_NR52
&0xf0) | S1
.on
| (S2
.on
<<1) | (S3
.on
<<2) | (S4
.on
<<3);
287 byte
sound_read(byte r
)
290 /* printf("read %02X: %02X\n", r, REG(r)); */
297 S1
.swfreq
= ((R_NR14
&7)<<8) + R_NR13
;
298 S1
.envol
= R_NR12
>> 4;
299 S1
.endir
= (R_NR12
>>3) & 1;
300 S1
.endir
|= S1
.endir
- 1;
301 S1
.enlen
= (R_NR12
& 7) << 15;
302 if (!S1
.on
) S1
.pos
= 0;
310 S2
.envol
= R_NR22
>> 4;
311 S2
.endir
= (R_NR22
>>3) & 1;
312 S2
.endir
|= S2
.endir
- 1;
313 S2
.enlen
= (R_NR22
& 7) << 15;
314 if (!S2
.on
) S2
.pos
= 0;
323 if (!S3
.on
) S3
.pos
= 0;
326 if (S3
.on
) for (i
= 0; i
< 16; i
++)
327 ram
.hi
[i
+0x30] = 0x13 ^ ram
.hi
[i
+0x31];
332 S4
.envol
= R_NR42
>> 4;
333 S4
.endir
= (R_NR42
>>3) & 1;
334 S4
.endir
|= S4
.endir
- 1;
335 S4
.enlen
= (R_NR42
& 7) << 15;
343 void sound_write(byte r
, byte b
)
347 if (!timer
) timer
= sys_timer();
348 printf("write %02X: %02X @ %d\n", r
, b
, sys_elapsed(timer
));
351 if (!(R_NR52
& 128) && r
!= RI_NR52
) return;
352 if ((r
& 0xF0) == 0x30)
354 if (S3
.on
) sound_mix();
356 WAVE
[r
-0x30] = ram
.hi
[r
] = b
;
364 S1
.swlen
= ((R_NR10
>>4) & 7) << 14;
365 S1
.swfreq
= ((R_NR14
&7)<<8) + R_NR13
;
369 S1
.len
= (64-(R_NR11
&63)) << 13;
373 S1
.envol
= R_NR12
>> 4;
374 S1
.endir
= (R_NR12
>>3) & 1;
375 S1
.endir
|= S1
.endir
- 1;
376 S1
.enlen
= (R_NR12
& 7) << 15;
385 if (b
& 128) s1_init();
389 S2
.len
= (64-(R_NR21
&63)) << 13;
393 S2
.envol
= R_NR22
>> 4;
394 S2
.endir
= (R_NR22
>>3) & 1;
395 S2
.endir
|= S2
.endir
- 1;
396 S2
.enlen
= (R_NR22
& 7) << 15;
405 if (b
& 128) s2_init();
409 if (!(b
& 128)) S3
.on
= 0;
413 S3
.len
= (256-R_NR31
) << 13;
425 if (b
& 128) s3_init();
429 S4
.len
= (64-(R_NR41
&63)) << 13;
433 S4
.envol
= R_NR42
>> 4;
434 S4
.endir
= (R_NR42
>>3) & 1;
435 S4
.endir
|= S4
.endir
- 1;
436 S4
.enlen
= (R_NR42
& 7) << 15;
444 if (b
& 128) s4_init();