summaryrefslogtreecommitdiff
path: root/apps/plugins/rockboy/sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/rockboy/sound.c')
-rw-r--r--apps/plugins/rockboy/sound.c129
1 files changed, 80 insertions, 49 deletions
diff --git a/apps/plugins/rockboy/sound.c b/apps/plugins/rockboy/sound.c
index 516b9c3f71..aba7f924b4 100644
--- a/apps/plugins/rockboy/sound.c
+++ b/apps/plugins/rockboy/sound.c
@@ -7,26 +7,41 @@
7#include "regs.h" 7#include "regs.h"
8#include "noise.h" 8#include "noise.h"
9 9
10static const byte dmgwave[16] =
11{
12 0xac, 0xdd, 0xda, 0x48,
13 0x36, 0x02, 0xcf, 0x16,
14 0x2c, 0x04, 0xe5, 0x2c,
15 0xac, 0xdd, 0xda, 0x48
16};
17
18static const byte cgbwave[16] =
19{
20 0x00, 0xff, 0x00, 0xff,
21 0x00, 0xff, 0x00, 0xff,
22 0x00, 0xff, 0x00, 0xff,
23 0x00, 0xff, 0x00, 0xff,
24};
10 25
11static const byte sqwave[4][8] = 26static const byte sqwave[4][8] =
12 { 27{
13 { 0, 0,-1, 0, 0, 0, 0, 0 }, 28 { 0, 0,-1, 0, 0, 0, 0, 0 },
14 { 0,-1,-1, 0, 0, 0, 0, 0 }, 29 { 0,-1,-1, 0, 0, 0, 0, 0 },
15 { 0,-1,-1,-1,-1, 0, 0, 0 }, 30 { -1,-1,-1,-1, 0, 0, 0, 0 },
16 { -1, 0, 0,-1,-1,-1,-1,-1 } 31 { -1, 0, 0,-1,-1,-1,-1,-1 }
17 }; 32};
18 33
19static const int freqtab[8] = 34static const int freqtab[8] =
20 { 35{
21 (1<<18)*2, 36 (1<<14)*2,
22 (1<<18), 37 (1<<14),
23 (1<<18)/2, 38 (1<<14)/2,
24 (1<<18)/3, 39 (1<<14)/3,
25 (1<<18)/4, 40 (1<<14)/4,
26 (1<<18)/5, 41 (1<<14)/5,
27 (1<<18)/6, 42 (1<<14)/6,
28 (1<<18)/7 43 (1<<14)/7
29 }; 44};
30 45
31struct snd snd IBSS_ATTR; 46struct snd snd IBSS_ATTR;
32 47
@@ -58,13 +73,14 @@ static void s2_freq(void)
58static void s3_freq(void) 73static void s3_freq(void)
59{ 74{
60 int d = 2048 - (((R_NR34&7)<<8) + R_NR33); 75 int d = 2048 - (((R_NR34&7)<<8) + R_NR33);
61 if (RATE > d) S3.freq = 0; 76 if (RATE > (d<<3)) S3.freq = 0;
62 else S3.freq = (RATE << 21)/d; 77 else S3.freq = (RATE << 21)/d;
63} 78}
64 79
65static void s4_freq(void) 80static void s4_freq(void)
66{ 81{
67 S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE; 82 S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE;
83 if (S4.freq >> 18) S4.freq = 1<<18;
68} 84}
69 85
70void sound_dirty(void) 86void sound_dirty(void)
@@ -74,13 +90,13 @@ void sound_dirty(void)
74 S1.envol = R_NR12 >> 4; 90 S1.envol = R_NR12 >> 4;
75 S1.endir = (R_NR12>>3) & 1; 91 S1.endir = (R_NR12>>3) & 1;
76 S1.endir |= S1.endir - 1; 92 S1.endir |= S1.endir - 1;
77 S1.enlen = (R_NR12 & 3) << 15; 93 S1.enlen = (R_NR12 & 7) << 15;
78 s1_freq(); 94 s1_freq();
79 S2.len = (64-(R_NR21&63)) << 13; 95 S2.len = (64-(R_NR21&63)) << 13;
80 S2.envol = R_NR22 >> 4; 96 S2.envol = R_NR22 >> 4;
81 S2.endir = (R_NR22>>3) & 1; 97 S2.endir = (R_NR22>>3) & 1;
82 S2.endir |= S2.endir - 1; 98 S2.endir |= S2.endir - 1;
83 S2.enlen = (R_NR22 & 3) << 15; 99 S2.enlen = (R_NR22 & 7) << 15;
84 s2_freq(); 100 s2_freq();
85 S3.len = (256-R_NR31) << 20; 101 S3.len = (256-R_NR31) << 20;
86 s3_freq(); 102 s3_freq();
@@ -88,13 +104,12 @@ void sound_dirty(void)
88 S4.envol = R_NR42 >> 4; 104 S4.envol = R_NR42 >> 4;
89 S4.endir = (R_NR42>>3) & 1; 105 S4.endir = (R_NR42>>3) & 1;
90 S4.endir |= S4.endir - 1; 106 S4.endir |= S4.endir - 1;
91 S4.enlen = (R_NR42 & 3) << 15; 107 S4.enlen = (R_NR42 & 7) << 15;
92 s4_freq(); 108 s4_freq();
93} 109}
94 110
95void sound_reset(void) 111void sound_off(void)
96{ 112{
97 int i;
98 memset(&snd, 0, sizeof snd); 113 memset(&snd, 0, sizeof snd);
99 if (pcm.hz) snd.rate = (1<<21) / pcm.hz; 114 if (pcm.hz) snd.rate = (1<<21) / pcm.hz;
100 else snd.rate = 0; 115 else snd.rate = 0;
@@ -115,11 +130,22 @@ void sound_reset(void)
115 R_NR44 = 0xBF; 130 R_NR44 = 0xBF;
116 R_NR50 = 0x77; 131 R_NR50 = 0x77;
117 R_NR51 = 0xF3; 132 R_NR51 = 0xF3;
118 R_NR52 = 0xF1; 133 R_NR52 = 0x70;
119 for (i = 0; i < 16; i++) WAVE[i] = -(i&1); 134// for (i = 0; i < 16; i++) WAVE[i] = -(i&1);
120 sound_dirty(); 135 sound_dirty();
121} 136}
122 137
138void sound_reset()
139{
140 memset(&snd, 0, sizeof snd);
141 if (pcm.hz) snd.rate = (1<<21) / pcm.hz;
142 else snd.rate = 0;
143 memcpy(WAVE, hw.cgb ? cgbwave : dmgwave, 16);
144 memcpy(ram.hi+0x30, WAVE, 16);
145 sound_off();
146 R_NR52 = 0xF1;
147}
148
123void sound_mix(void) 149void sound_mix(void)
124{ 150{
125 int s, l, r, f, n; 151 int s, l, r, f, n;
@@ -145,7 +171,8 @@ void sound_mix(void)
145 } 171 }
146 if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen) 172 if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen)
147 { 173 {
148 f = ((R_NR14 & 7) << 8) + R_NR13; 174 S1.swcnt -= S1.swlen;
175 f = S1.swfreq;
149 n = (R_NR10 & 7); 176 n = (R_NR10 & 7);
150 if (R_NR10 & 8) f -= (f >> n); 177 if (R_NR10 & 8) f -= (f >> n);
151 else f += (f >> n); 178 else f += (f >> n);
@@ -153,14 +180,15 @@ void sound_mix(void)
153 S1.on = 0; 180 S1.on = 0;
154 else 181 else
155 { 182 {
183 S1.swfreq = f;
156 R_NR13 = f; 184 R_NR13 = f;
157 R_NR14 = (R_NR14 & 0xF8) | (f>>8); 185 R_NR14 = (R_NR14 & 0xF8) | (f>>8);
158 s1_freq_d(2048 - f); 186 s1_freq_d(2048 - f);
159 } 187 }
160 } 188 }
161 s <<= 2; 189 s <<= 2;
162 if (R_NR51 & 1) l += s; 190 if (R_NR51 & 1) r += s;
163 if (R_NR51 & 16) r += s; 191 if (R_NR51 & 16) l += s;
164 } 192 }
165 193
166 if (S2.on) 194 if (S2.on)
@@ -177,8 +205,8 @@ void sound_mix(void)
177 if (S2.envol > 15) S2.envol = 15; 205 if (S2.envol > 15) S2.envol = 15;
178 } 206 }
179 s <<= 2; 207 s <<= 2;
180 if (R_NR51 & 2) l += s; 208 if (R_NR51 & 2) r += s;
181 if (R_NR51 & 32) r += s; 209 if (R_NR51 & 32) l += s;
182 } 210 }
183 211
184 if (S3.on) 212 if (S3.on)
@@ -192,16 +220,16 @@ void sound_mix(void)
192 S3.on = 0; 220 S3.on = 0;
193 if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3)); 221 if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3));
194 else s = 0; 222 else s = 0;
195 if (R_NR51 & 4) l += s; 223 if (R_NR51 & 4) r += s;
196 if (R_NR51 & 64) r += s; 224 if (R_NR51 & 64) l += s;
197 } 225 }
198 226
199 if (S4.on) 227 if (S4.on)
200 { 228 {
201 if (R_NR43 & 8) s = 1 & (noise7[ 229 if (R_NR43 & 8) s = 1 & (noise7[
202 (S4.pos>>24)&15] >> ((S4.pos>>21)&7)); 230 (S4.pos>>20)&15] >> (7-((S4.pos>>17)&7)));
203 else s = 1 & (noise15[ 231 else s = 1 & (noise15[
204 (S4.pos>>24)&4095] >> ((S4.pos>>21)&7)); 232 (S4.pos>>20)&4095] >> (7-((S4.pos>>17)&7)));
205 s = (-s) & S4.envol; 233 s = (-s) & S4.envol;
206 S4.pos += S4.freq; 234 S4.pos += S4.freq;
207 if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len)) 235 if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len))
@@ -213,9 +241,9 @@ void sound_mix(void)
213 if (S4.envol < 0) S4.envol = 0; 241 if (S4.envol < 0) S4.envol = 0;
214 if (S4.envol > 15) S4.envol = 15; 242 if (S4.envol > 15) S4.envol = 15;
215 } 243 }
216 s <<= 2; 244 s += s << 1;
217 if (R_NR51 & 8) l += s; 245 if (R_NR51 & 8) r += s;
218 if (R_NR51 & 128) r += s; 246 if (R_NR51 & 128) l += s;
219 } 247 }
220 248
221 l *= (R_NR50 & 0x07); 249 l *= (R_NR50 & 0x07);
@@ -234,10 +262,10 @@ void sound_mix(void)
234 pcm_submit(); 262 pcm_submit();
235 if (pcm.stereo) 263 if (pcm.stereo)
236 { 264 {
237 pcm.buf[pcm.pos++] = l+128; 265 pcm.buf[pcm.pos++] = ((signed char)(l))<<7;
238 pcm.buf[pcm.pos++] = r+128; 266 pcm.buf[pcm.pos++] = ((signed char)(r))<<7;
239 } 267 }
240 else pcm.buf[pcm.pos++] = ((l+r)>>1)+128; 268 else pcm.buf[pcm.pos++] = ((signed char)((l+r)>>1))<<7;
241 } 269 }
242 } 270 }
243 R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3); 271 R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3);
@@ -256,12 +284,13 @@ byte sound_read(byte r)
256void s1_init(void) 284void s1_init(void)
257{ 285{
258 S1.swcnt = 0; 286 S1.swcnt = 0;
287 S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
259 S1.envol = R_NR12 >> 4; 288 S1.envol = R_NR12 >> 4;
260 S1.endir = (R_NR12>>3) & 1; 289 S1.endir = (R_NR12>>3) & 1;
261 S1.endir |= S1.endir - 1; 290 S1.endir |= S1.endir - 1;
262 S1.enlen = (R_NR12 & 7) << 15; 291 S1.enlen = (R_NR12 & 7) << 15;
292 if (!S1.on) S1.pos = 0;
263 S1.on = 1; 293 S1.on = 1;
264 S1.pos = 0;
265 S1.cnt = 0; 294 S1.cnt = 0;
266 S1.encnt = 0; 295 S1.encnt = 0;
267} 296}
@@ -272,17 +301,20 @@ void s2_init(void)
272 S2.endir = (R_NR22>>3) & 1; 301 S2.endir = (R_NR22>>3) & 1;
273 S2.endir |= S2.endir - 1; 302 S2.endir |= S2.endir - 1;
274 S2.enlen = (R_NR22 & 7) << 15; 303 S2.enlen = (R_NR22 & 7) << 15;
304 if (!S2.on) S2.pos = 0;
275 S2.on = 1; 305 S2.on = 1;
276 S2.pos = 0;
277 S2.cnt = 0; 306 S2.cnt = 0;
278 S2.encnt = 0; 307 S2.encnt = 0;
279} 308}
280 309
281void s3_init(void) 310void s3_init(void)
282{ 311{
283 S3.pos = 0; 312 int i;
313 if (!S3.on) S3.pos = 0;
284 S3.cnt = 0; 314 S3.cnt = 0;
285 S3.on = R_NR30 >> 7; 315 S3.on = R_NR30 >> 7;
316 if (S3.on) for (i = 0; i < 16; i++)
317 ram.hi[i+0x30] = 0x13 ^ ram.hi[i+0x31];
286} 318}
287 319
288void s4_init(void) 320void s4_init(void)
@@ -306,7 +338,8 @@ void sound_write(byte r, byte b)
306 if ((r & 0xF0) == 0x30) 338 if ((r & 0xF0) == 0x30)
307 { 339 {
308 if (S3.on) sound_mix(); 340 if (S3.on) sound_mix();
309 if (!S3.on) WAVE[r - 0x30] = b; 341 if (!S3.on)
342 WAVE[r-0x30] = ram.hi[r] = b;
310 return; 343 return;
311 } 344 }
312 sound_mix(); 345 sound_mix();
@@ -314,6 +347,8 @@ void sound_write(byte r, byte b)
314 { 347 {
315 case RI_NR10: 348 case RI_NR10:
316 R_NR10 = b; 349 R_NR10 = b;
350 S1.swlen = ((R_NR10>>4) & 7) << 14;
351 S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
317 break; 352 break;
318 case RI_NR11: 353 case RI_NR11:
319 R_NR11 = b; 354 R_NR11 = b;
@@ -361,7 +396,7 @@ void sound_write(byte r, byte b)
361 break; 396 break;
362 case RI_NR31: 397 case RI_NR31:
363 R_NR31 = b; 398 R_NR31 = b;
364 S3.len = (256-R_NR31) << 20; 399 S3.len = (256-R_NR31) << 13;
365 break; 400 break;
366 case RI_NR32: 401 case RI_NR32:
367 R_NR32 = b; 402 R_NR32 = b;
@@ -403,13 +438,9 @@ void sound_write(byte r, byte b)
403 case RI_NR52: 438 case RI_NR52:
404 R_NR52 = b; 439 R_NR52 = b;
405 if (!(R_NR52 & 128)) 440 if (!(R_NR52 & 128))
406 sound_reset(); 441 sound_off();
407 break; 442 break;
408 default: 443 default:
409 return; 444 return;
410 } 445 }
411} 446}
412
413
414
415