blob: 041b7831d31c5095d8045cf0c337ec871818bc87 [file] [log] [blame]
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * The following code is rewrite of the C++ code provided in VisualBoyAdvance.
11 * There are also portions of the original GNUboy code.
12 * Copyright (C) 2001 the GNUboy development team
13 *
14 * VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
15 * Copyright (C) 1999-2003 Forgotten
16 * Copyright (C) 2004 Forgotten and the VBA development team
17 *
18 * VisualBoyAdvance conversion from C++ to C by Karl Kurbjun July, 2007
19 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000020 * This program is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU General Public License
22 * as published by the Free Software Foundation; either version 2
23 * of the License, or (at your option) any later version.
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +000024 *
25 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
26 * KIND, either express or implied.
27 *
28 */
29
Jens Arnold384de102005-03-02 23:49:38 +000030#include "rockmacros.h"
31#include "defs.h"
32#include "pcm.h"
33#include "sound.h"
Jens Arnoldd2456b42005-07-03 14:05:12 +000034#include "cpu-gb.h"
Jens Arnold384de102005-03-02 23:49:38 +000035#include "hw.h"
36#include "regs.h"
Jens Arnold384de102005-03-02 23:49:38 +000037
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +000038static const byte soundWavePattern[4][32] = {
39 {0x01,0x01,0x01,0x01,
40 0xff,0xff,0xff,0xff,
41 0xff,0xff,0xff,0xff,
42 0xff,0xff,0xff,0xff,
43 0xff,0xff,0xff,0xff,
44 0xff,0xff,0xff,0xff,
45 0xff,0xff,0xff,0xff,
46 0xff,0xff,0xff,0xff},
47 {0x01,0x01,0x01,0x01,
48 0x01,0x01,0x01,0x01,
49 0xff,0xff,0xff,0xff,
50 0xff,0xff,0xff,0xff,
51 0xff,0xff,0xff,0xff,
52 0xff,0xff,0xff,0xff,
53 0xff,0xff,0xff,0xff,
54 0xff,0xff,0xff,0xff},
55 {0x01,0x01,0x01,0x01,
56 0x01,0x01,0x01,0x01,
57 0x01,0x01,0x01,0x01,
58 0x01,0x01,0x01,0x01,
59 0xff,0xff,0xff,0xff,
60 0xff,0xff,0xff,0xff,
61 0xff,0xff,0xff,0xff,
62 0xff,0xff,0xff,0xff},
63 {0x01,0x01,0x01,0x01,
64 0x01,0x01,0x01,0x01,
65 0x01,0x01,0x01,0x01,
66 0x01,0x01,0x01,0x01,
67 0x01,0x01,0x01,0x01,
68 0x01,0x01,0x01,0x01,
69 0xff,0xff,0xff,0xff,
70 0xff,0xff,0xff,0xff}
Karl Kurbjuna07b60e2007-07-21 04:23:15 +000071};
Karl Kurbjun78c45532007-06-24 16:00:55 +000072
Karl Kurbjuna07b60e2007-07-21 04:23:15 +000073int soundFreqRatio[8] ICONST_ATTR= {
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +000074 1048576, // 0
75 524288, // 1
76 262144, // 2
77 174763, // 3
78 131072, // 4
79 104858, // 5
80 87381, // 6
81 74898 // 7
Karl Kurbjuna07b60e2007-07-21 04:23:15 +000082};
Jens Arnold384de102005-03-02 23:49:38 +000083
Karl Kurbjuna07b60e2007-07-21 04:23:15 +000084int soundShiftClock[16] ICONST_ATTR= {
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +000085 2, // 0
86 4, // 1
87 8, // 2
88 16, // 3
89 32, // 4
90 64, // 5
91 128, // 6
92 256, // 7
93 512, // 8
94 1024, // 9
95 2048, // 10
96 4096, // 11
97 8192, // 12
98 16384, // 13
99 1, // 14
100 1 // 15
Karl Kurbjuna07b60e2007-07-21 04:23:15 +0000101};
Jens Arnold384de102005-03-02 23:49:38 +0000102
Daniel Stenberg137fb6c2006-01-20 13:05:52 +0000103struct snd snd IBSS_ATTR;
Jens Arnold384de102005-03-02 23:49:38 +0000104
105#define RATE (snd.rate)
Tom Ross2882b262007-02-06 21:41:08 +0000106#define WAVE (ram.hi+0x30)
Jens Arnold384de102005-03-02 23:49:38 +0000107#define S1 (snd.ch[0])
108#define S2 (snd.ch[1])
109#define S3 (snd.ch[2])
110#define S4 (snd.ch[3])
111
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000112#define SOUND_MAGIC 0x60000000
113#define SOUND_MAGIC_2 0x30000000
114#define NOISE_MAGIC 5
115
116static void gbSoundChannel1(int *r, int *l)
Jens Arnold384de102005-03-02 23:49:38 +0000117{
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000118 int vol = S1.envol;
119
120 int freq = 0;
121
122 int value = 0;
123
124 if(S1.on && (S1.len || !S1.cont))
125 {
126 S1.pos += snd.quality*S1.skip;
127 S1.pos &= 0x1fffffff;
128
129 value = ((signed char)S1.wave[S1.pos>>24]) * vol;
130 }
131
132 if (snd.balance & 1) *r += value;
133 if (snd.balance & 16) *l += value;
134
135 if(S1.on)
136 {
137 if(S1.len)
138 {
139 S1.len-=snd.quality;
140
141 if(S1.len <=0 && S1.cont)
142 {
143 R_NR52 &= 0xfe;
144 S1.on = 0;
145 }
146 }
147
148 if(S1.enlen)
149 {
150 S1.enlen-=snd.quality;
151
152 if(S1.enlen<=0)
153 {
154 if(S1.endir)
155 {
156 if(S1.envol < 15)
157 S1.envol++;
158 }
159 else
160 {
161 if(S1.envol)
162 S1.envol--;
163 }
164
165 S1.enlen += S1.enlenreload;
166 }
167 }
168
169 if(S1.swlen)
170 {
171 S1.swlen-=snd.quality;
172
173 if(S1.swlen<=0)
174 {
175 freq = (((int)(R_NR14&7) << 8) | R_NR13);
176
177 int updown = 1;
178
179 if(S1.swdir)
180 updown = -1;
181
182 int newfreq = 0;
183 if(S1.swsteps)
184 {
185 newfreq = freq + updown * freq / (1 << S1.swsteps);
186 if(newfreq == freq)
187 newfreq = 0;
188 }
189 else
190 newfreq = freq;
191
192 if(newfreq < 0)
193 {
194 S1.swlen += S1.swlenreload;
195 }
196 else if(newfreq > 2047)
197 {
198 S1.swlen = 0;
199 S1.on = 0;
200 R_NR52 &= 0xfe;
201 }
202 else
203 {
204 S1.swlen += S1.swlenreload;
205 S1.skip = SOUND_MAGIC/(2048 - newfreq);
206
207 R_NR13 = newfreq & 0xff;
208 R_NR14 = (R_NR14 & 0xf8) |((newfreq >> 8) & 7);
209 }
210 }
211 }
212 }
Jens Arnold384de102005-03-02 23:49:38 +0000213}
214
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000215static void gbSoundChannel2(int *r, int *l)
Jens Arnold384de102005-03-02 23:49:38 +0000216{
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000217 int vol = S2.envol;
218
219 int value = 0;
220
221 if(S2.on && (S2.len || !S2.cont))
222 {
223 S2.pos += snd.quality*S2.skip;
224 S2.pos &= 0x1fffffff;
225
226 value = ((signed char)S2.wave[S2.pos>>24]) * vol;
227 }
228
229 if (snd.balance & 2) *r += value;
230 if (snd.balance & 32) *l += value;
231
232 if(S2.on) {
233 if(S2.len) {
234 S2.len-=snd.quality;
235
236 if(S2.len <= 0 && S2.cont) {
237 R_NR52 &= 0xfd;
238 S2.on = 0;
239 }
240 }
241
242 if(S2.enlen) {
243 S2.enlen-=snd.quality;
244
245 if(S2.enlen <= 0) {
246 if(S2.endir) {
247 if(S2.envol < 15)
248 S2.envol++;
249 } else {
250 if(S2.envol)
251 S2.envol--;
252 }
253 S2.enlen += S2.enlenreload;
254 }
255 }
256 }
Jens Arnold384de102005-03-02 23:49:38 +0000257}
258
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000259static void gbSoundChannel3(int *r, int *l)
Jens Arnold384de102005-03-02 23:49:38 +0000260{
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000261 int s;
262 if (S3.on && (S3.len || !S3.cont))
263 {
264 S3.pos += S3.skip*snd.quality;
265 S3.pos &= 0x1fffffff;
266 s=ram.hi[0x30 + (S3.pos>>25)];
267 if (S3.pos & 0x01000000)
268 s &= 0x0f;
269 else
270 s >>= 4;
271
272 s -= 8;
273
274 switch(S3.outputlevel)
275 {
276 case 0:
277 s=0;
278 break;
279 case 1:
280 break;
281 case 2:
282 s=s>>1;
283 break;
284 case 3:
285 s=s>>2;
286 break;
287 }
288
289 if (snd.balance & 4) *r += s;
290 if (snd.balance & 64) *l += s;
291 }
292
293 if(S3.on)
294 {
295 if(S3.len)
296 {
297 S3.len-=snd.quality;
298 if(S3.len<=0 && S3.cont)
299 {
300 R_NR52 &= 0xFB;
301 S3.on=0;
302 }
303 }
304 }
Jens Arnold384de102005-03-02 23:49:38 +0000305}
306
Tom Ross437c3e42007-10-16 18:16:22 +0000307static void gbSoundChannel4(int *r, int *l)
Jens Arnold384de102005-03-02 23:49:38 +0000308{
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000309 int vol = S4.envol;
310
311 int value = 0;
312
313 if(S4.clock <= 0x0c)
314 {
315 if(S4.on && (S4.len || !S4.cont))
316 {
317 S4.pos += snd.quality*S4.skip;
318 S4.shiftpos += snd.quality*S4.shiftskip;
319
320 if(S4.nsteps)
321 {
322 while(S4.shiftpos > 0x1fffff) {
323 S4.shiftright = (((S4.shiftright << 6) ^
324 (S4.shiftright << 5)) & 0x40) | (S4.shiftright >> 1);
325 S4.shiftpos -= 0x200000;
326 }
327 }
328 else
329 {
330 while(S4.shiftpos > 0x1fffff)
331 {
332 S4.shiftright = (((S4.shiftright << 14) ^
333 (S4.shiftright << 13)) & 0x4000) | (S4.shiftright >> 1);
334 S4.shiftpos -= 0x200000;
335 }
336 }
337
338 S4.pos &= 0x1fffff;
339 S4.shiftpos &= 0x1fffff;
340
341 value = ((S4.shiftright & 1)*2-1) * vol;
342 }
343 else
344 {
345 value = 0;
346 }
347 }
348
349 if (snd.balance & 8) *r += value;
350 if (snd.balance & 128) *l += value;
351
352 if(S4.on) {
353 if(S4.len) {
354 S4.len-=snd.quality;
355
356 if(S4.len <= 0 && S4.cont) {
357 R_NR52 &= 0xfd;
358 S4.on = 0;
359 }
360 }
361
362 if(S4.enlen) {
363 S4.enlen-=snd.quality;
364
365 if(S4.enlen <= 0)
366 {
367 if(S4.endir)
368 {
369 if(S4.envol < 15)
370 S4.envol++;
371 }
372 else
373 {
374 if(S4.envol)
375 S4.envol--;
376 }
377 S4.enlen += S4.enlenreload;
378 }
379 }
380 }
Karl Kurbjun78c45532007-06-24 16:00:55 +0000381}
382
Jens Arnold384de102005-03-02 23:49:38 +0000383void sound_mix(void)
384{
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000385 int l, r;
Jens Arnold384de102005-03-02 23:49:38 +0000386
387 if (!RATE || cpu.snd < RATE) return;
388
389 for (; cpu.snd >= RATE; cpu.snd -= RATE)
390 {
391 l = r = 0;
392
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000393 gbSoundChannel1(&r,&l);
394
395 gbSoundChannel2(&r,&l);
396
397 gbSoundChannel3(&r,&l);
398
399 gbSoundChannel4(&r,&l);
400
401 if(snd.gbDigitalSound)
Jens Arnold384de102005-03-02 23:49:38 +0000402 {
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000403 l = snd.level1<<8;
404 r = snd.level2<<8;
405 }
406 else
407 {
408 l *= snd.level1*60;
409 r *= snd.level2*60;
Jens Arnold384de102005-03-02 23:49:38 +0000410 }
411
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000412 if(l > 32767)
413 l = 32767;
414 if(l < -32768)
415 l = -32768;
416
417 if(r > 32767)
418 r = 32767;
419 if(r < -32768)
420 r = -32768;
Jens Arnold384de102005-03-02 23:49:38 +0000421
422 if (pcm.buf)
423 {
424 if (pcm.pos >= pcm.len)
425 pcm_submit();
426 if (pcm.stereo)
427 {
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000428 pcm.buf[pcm.pos++] = l;
429 pcm.buf[pcm.pos++] = r;
Jens Arnold384de102005-03-02 23:49:38 +0000430 }
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000431 else pcm.buf[pcm.pos++] = ((l+r)>>1);
Jens Arnold384de102005-03-02 23:49:38 +0000432 }
433 }
434 R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3);
435}
436
Jens Arnold384de102005-03-02 23:49:38 +0000437byte sound_read(byte r)
438{
Tom Ross2882b262007-02-06 21:41:08 +0000439 if(!options.sound) return 0;
Jens Arnold384de102005-03-02 23:49:38 +0000440 sound_mix();
441 /* printf("read %02X: %02X\n", r, REG(r)); */
442 return REG(r);
443}
444
Jens Arnold384de102005-03-02 23:49:38 +0000445void sound_write(byte r, byte b)
446{
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000447 int freq=0;
448 ram.hi[r]=b;
Jens Arnold384de102005-03-02 23:49:38 +0000449
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000450 if(!options.sound)
Jens Arnold384de102005-03-02 23:49:38 +0000451 return;
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000452
Jens Arnold384de102005-03-02 23:49:38 +0000453 sound_mix();
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000454
Jens Arnold384de102005-03-02 23:49:38 +0000455 switch (r)
456 {
457 case RI_NR10:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000458 S1.swlen = S1.swlenreload = 344 * ((b >> 4) & 7);
459 S1.swsteps = b & 7;
460 S1.swdir = b & 0x08;
461 S1.swstep = 0;
Jens Arnold384de102005-03-02 23:49:38 +0000462 break;
463 case RI_NR11:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000464 S1.len = 172 * (64 - (b & 0x3f));
465 S1.wave = soundWavePattern[b >> 6];
Jens Arnold384de102005-03-02 23:49:38 +0000466 break;
467 case RI_NR12:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000468 S1.envol = b >> 4;
469 S1.endir = b & 0x08;
470 S1.enlenreload = S1.enlen = 689 * (b & 7);
Jens Arnold384de102005-03-02 23:49:38 +0000471 break;
472 case RI_NR13:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000473 freq = (((int)(R_NR14 & 7)) << 8) | b;
474 S1.len = 172 * (64 - (R_NR11 & 0x3f));
475 freq = 2048 - freq;
476 if(freq)
477 {
478 S1.skip = SOUND_MAGIC / freq;
479 }
480 else
481 {
482 S1.skip = 0;
483 }
Jens Arnold384de102005-03-02 23:49:38 +0000484 break;
485 case RI_NR14:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000486 freq = (((int)(b&7) << 8) | R_NR13);
487 freq = 2048 - freq;
488 S1.len = 172 * (64 - (R_NR11 & 0x3f));
489 S1.cont = b & 0x40;
490 if(freq)
491 {
492 S1.skip = SOUND_MAGIC / freq;
493 }
494 else
495 {
496 S1.skip = 0;
497 }
498 if(b & 0x80)
499 {
500 R_NR52 |= 1;
501 S1.envol = R_NR12 >> 4;
502 S1.endir = R_NR12 & 0x08;
503 S1.len = 172 * (64 - (R_NR11 & 0x3f));
504 S1.enlenreload = S1.enlen = 689 * (R_NR12 & 7);
505 S1.swlen = S1.swlenreload = 344 * ((R_NR10 >> 4) & 7);
506 S1.swsteps = R_NR10 & 7;
507 S1.swdir = R_NR10 & 0x08;
508 S1.swstep = 0;
509
510 S1.pos = 0;
511 S1.on = 1;
512 }
Jens Arnold384de102005-03-02 23:49:38 +0000513 break;
514 case RI_NR21:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000515 S2.wave = soundWavePattern[b >> 6];
516 S2.len = 172 * (64 - (b & 0x3f));
Jens Arnold384de102005-03-02 23:49:38 +0000517 break;
518 case RI_NR22:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000519 S2.envol = b >> 4;
520 S2.endir = b & 0x08;
521 S2.enlenreload = S2.enlen = 689 * (b & 7);
Jens Arnold384de102005-03-02 23:49:38 +0000522 break;
523 case RI_NR23:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000524 freq = (((int)(R_NR24 & 7)) << 8) | b;
525 S2.len = 172 * (64 - (R_NR21 & 0x3f));
526 freq = 2048 - freq;
527 if(freq)
528 {
529 S2.skip = SOUND_MAGIC / freq;
530 }
531 else
532 {
533 S2.skip = 0;
534 }
Jens Arnold384de102005-03-02 23:49:38 +0000535 break;
536 case RI_NR24:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000537 freq = (((int)(b&7) << 8) | R_NR23);
538 freq = 2048 - freq;
539 S2.len = 172 * (64 - (R_NR21 & 0x3f));
540 S2.cont = b & 0x40;
541 if(freq) {
542 S2.skip = SOUND_MAGIC / freq;
543 } else
544 S2.skip = 0;
545 if(b & 0x80) {
546 R_NR52 |= 2;
547 S2.envol = R_NR22 >> 4;
548 S2.endir = R_NR22 & 0x08;
549 S2.len = 172 * (64 - (R_NR21 & 0x3f));
550 S2.enlenreload = S2.enlen = 689 * (R_NR22 & 7);
551
552 S2.pos = 0;
553 S2.on = 1;
554 }
Jens Arnold384de102005-03-02 23:49:38 +0000555 break;
556 case RI_NR30:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000557 if (!(b & 0x80)){
558 R_NR52 &= 0xfb;
559 S3.on = 0;
560 }
Jens Arnold384de102005-03-02 23:49:38 +0000561 break;
562 case RI_NR31:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000563 S3.len = (256-R_NR31) * 172;
Jens Arnold384de102005-03-02 23:49:38 +0000564 break;
565 case RI_NR32:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000566 S3.outputlevel = (b >> 5) & 3;
Jens Arnold384de102005-03-02 23:49:38 +0000567 break;
568 case RI_NR33:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000569 freq = 2048 - (((int)(R_NR34&7) << 8) | b);
570 if(freq)
571 S3.skip = SOUND_MAGIC_2 / freq;
572 else
573 S3.skip = 0;
Jens Arnold384de102005-03-02 23:49:38 +0000574 break;
575 case RI_NR34:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000576 freq = 2048 - (((b&7)<<8) | R_NR33);
577
578 if(freq)
579 S3.skip = SOUND_MAGIC_2 / freq;
580 else
581 S3.skip = 0;
582
583 S3.cont=b & 0x40;
584 if((b & 0x80) && (R_NR30 & 0x80))
585 {
586 R_NR52 |= 4;
587 S3.len = 172 * (256 - R_NR31);
588 S3.pos = 0;
589 S3.on = 1;
590 }
Jens Arnold384de102005-03-02 23:49:38 +0000591 break;
592 case RI_NR41:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000593 S4.len = 172 * (64 - (b & 0x3f));
Jens Arnold384de102005-03-02 23:49:38 +0000594 break;
595 case RI_NR42:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000596 S4.envol = b >> 4;
597 S4.endir = b & 0x08;
598 S4.enlenreload = S4.enlen = 689 * (b & 7);
Jens Arnold384de102005-03-02 23:49:38 +0000599 break;
600 case RI_NR43:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000601 freq = soundFreqRatio[b & 7];
602
603 S4.nsteps = b & 0x08;
604 S4.skip = (freq << 8) / NOISE_MAGIC;
605 S4.clock = b >> 4;
606
607 freq = freq / soundShiftClock[S4.clock];
608 S4.shiftskip = (freq << 8) / NOISE_MAGIC;
Jens Arnold384de102005-03-02 23:49:38 +0000609 break;
610 case RI_NR44:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000611 S4.cont = b & 0x40;
612 if(b & 0x80)
613 {
614 R_NR52 |= 8;
615 S4.envol = R_NR42 >> 4;
616 S4.endir = R_NR42 & 0x08;
617 S4.len = 172 * (64 - (R_NR41 & 0x3f));
618 S4.enlenreload = S4.enlen = 689 * (R_NR42 & 7);
619
620 S4.on = 1;
621
622 S4.pos = 0;
623 S4.shiftpos = 0;
624
625 freq = soundFreqRatio[R_NR43 & 7];
626
627 S4.shiftpos = (freq << 8) / NOISE_MAGIC;
628
629 S4.nsteps = R_NR43 & 0x08;
630
631 freq = freq / soundShiftClock[R_NR43 >> 4];
632
633 S4.shiftskip = (freq << 8) / NOISE_MAGIC;
634 if(S4.nsteps)
635 {
636 S4.shiftright = 0x7fff;
637 }
638 else
639 {
640 S4.shiftright = 0x7f;
641 }
642 }
Jens Arnold384de102005-03-02 23:49:38 +0000643 break;
644 case RI_NR50:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000645 snd.level1 = b & 7;
646 snd.level2 = (b >> 4) & 7;
Jens Arnold384de102005-03-02 23:49:38 +0000647 break;
648 case RI_NR51:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000649 snd.balance = b;
Jens Arnold384de102005-03-02 23:49:38 +0000650 break;
651 case RI_NR52:
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000652 if (!(b & 0x80))
653 {
654 S1.on=0;
655 S2.on=0;
656 S3.on=0;
657 S4.on=0;
658 }
Jens Arnold384de102005-03-02 23:49:38 +0000659 break;
Jens Arnold384de102005-03-02 23:49:38 +0000660 }
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000661
662 snd.gbDigitalSound = true;
663
664 if(S1.on && S1.envol != 0)
665 snd.gbDigitalSound = false;
666 if(S2.on && S2.envol != 0)
667 snd.gbDigitalSound = false;
668 if(S3.on && S3.outputlevel != 0)
669 snd.gbDigitalSound = false;
670 if(S4.on && S4.envol != 0)
671 snd.gbDigitalSound = false;
672}
673
Tom Ross437c3e42007-10-16 18:16:22 +0000674void sound_reset(void)
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000675{
676 snd.level1 = 7;
677 snd.level2 = 7;
678 S1.on = S2.on = S3.on = S4.on = 0;
679 S1.len = S2.len = S3.len = S4.len = 0;
680 S1.skip = S2.skip = S3.skip = S4.skip = 0;
681 S1.pos = S2.pos = S3.pos = S4.pos = 0;
682 S1.cont = S2.cont = S3.cont = S4.cont = 0;
683 S1.envol = S2.envol = S4.envol = 0;
684 S1.enlen = S2.enlen = S4.enlen = 0;
685 S1.endir = S2.endir = S4.endir = 0;
686 S1.enlenreload = S2.enlenreload = S4.enlenreload = 0;
687 S1.swlen = 0;
688 S1.swlenreload = 0;
689 S1.swsteps = 0;
690 S1.swdir = 0;
691 S1.swstep = 0;
692 S1.wave = S2.wave = soundWavePattern[2];
693
694 S3.outputlevel = 0;
695
696 S4.clock = 0;
697 S4.shiftright = 0x7f;
698 S4.nsteps = 0;
699
700 sound_write(0x10, 0x80);
701 sound_write(0x11, 0xbf);
702 sound_write(0x12, 0xf3);
703 sound_write(0x14, 0xbf);
704 sound_write(0x16, 0x3f);
705 sound_write(0x17, 0x00);
706 sound_write(0x19, 0xbf);
707
708 sound_write(0x1a, 0x7f);
709 sound_write(0x1b, 0xff);
710 sound_write(0x1c, 0xbf);
711 sound_write(0x1e, 0xbf);
712
713 sound_write(0x20, 0xff);
714 sound_write(0x21, 0x00);
715 sound_write(0x22, 0x00);
716 sound_write(0x23, 0xbf);
717 sound_write(0x24, 0x77);
718 sound_write(0x25, 0xf3);
719
720 sound_write(0x26, 0xf0);
721
722 S1.on = 0;
723 S2.on = 0;
724 S3.on = 0;
725 S4.on = 0;
726
727 int addr = 0x30;
728 while(addr < 0x40)
729 {
730 ram.hi[addr++] = 0x00;
731 ram.hi[addr++] = 0xff;
732 }
733
734 if (pcm.hz)
735 {
736 snd.rate = (1<<21) / pcm.hz;
737 snd.quality=44100 / pcm.hz;
738 }
739 else snd.rate = 0;
740}
741
Tom Ross437c3e42007-10-16 18:16:22 +0000742void sound_dirty(void)
Karl Kurbjunfa3fc0c2007-07-21 04:00:58 +0000743{
744 sound_write(RI_NR10, R_NR10);
745 sound_write(RI_NR11, R_NR11);
746 sound_write(RI_NR12, R_NR12);
747 sound_write(RI_NR13, R_NR13);
748 sound_write(RI_NR14, R_NR14);
749
750 sound_write(RI_NR21, R_NR21);
751 sound_write(RI_NR22, R_NR22);
752 sound_write(RI_NR23, R_NR23);
753 sound_write(RI_NR24, R_NR24);
754
755 sound_write(RI_NR30, R_NR30);
756 sound_write(RI_NR31, R_NR31);
757 sound_write(RI_NR32, R_NR32);
758 sound_write(RI_NR33, R_NR33);
759 sound_write(RI_NR34, R_NR34);
760
761 sound_write(RI_NR42, R_NR42);
762 sound_write(RI_NR43, R_NR43);
763 sound_write(RI_NR44, R_NR44);
764
765 sound_write(RI_NR50, R_NR50);
766 sound_write(RI_NR51, R_NR51);
767 sound_write(RI_NR52, R_NR52);
Jens Arnold384de102005-03-02 23:49:38 +0000768}