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.c140
1 files changed, 45 insertions, 95 deletions
diff --git a/apps/plugins/rockboy/sound.c b/apps/plugins/rockboy/sound.c
index deeacc7bbf..707bb6b956 100644
--- a/apps/plugins/rockboy/sound.c
+++ b/apps/plugins/rockboy/sound.c
@@ -8,63 +8,38 @@
8#include "cpu-gb.h" 8#include "cpu-gb.h"
9#include "hw.h" 9#include "hw.h"
10#include "regs.h" 10#include "regs.h"
11#include "rc.h"
12#include "noise.h" 11#include "noise.h"
13 12
14 13
15static const byte dmgwave[16] =
16 {
17 0xac, 0xdd, 0xda, 0x48,
18 0x36, 0x02, 0xcf, 0x16,
19 0x2c, 0x04, 0xe5, 0x2c,
20 0xac, 0xdd, 0xda, 0x48
21 };
22
23static const byte cgbwave[16] =
24 {
25 0x00, 0xff, 0x00, 0xff,
26 0x00, 0xff, 0x00, 0xff,
27 0x00, 0xff, 0x00, 0xff,
28 0x00, 0xff, 0x00, 0xff,
29 };
30
31
32static const byte sqwave[4][8] = 14static const byte sqwave[4][8] =
33 { 15 {
34 { 0, 0,-1, 0, 0, 0, 0, 0 }, 16 { 0, 0,-1, 0, 0, 0, 0, 0 },
35 { 0,-1,-1, 0, 0, 0, 0, 0 }, 17 { 0,-1,-1, 0, 0, 0, 0, 0 },
36 { -1,-1,-1,-1, 0, 0, 0, 0 }, 18 { 0,-1,-1,-1,-1, 0, 0, 0 },
37 { -1, 0, 0,-1,-1,-1,-1,-1 } 19 { -1, 0, 0,-1,-1,-1,-1,-1 }
38 }; 20 };
39 21
40static const int freqtab[8] = 22static const int freqtab[8] =
41 { 23 {
42 (1<<14)*2, 24 (1<<18)*2,
43 (1<<14), 25 (1<<18),
44 (1<<14)/2, 26 (1<<18)/2,
45 (1<<14)/3, 27 (1<<18)/3,
46 (1<<14)/4, 28 (1<<18)/4,
47 (1<<14)/5, 29 (1<<18)/5,
48 (1<<14)/6, 30 (1<<18)/6,
49 (1<<14)/7 31 (1<<18)/7
50 }; 32 };
51 33
52struct snd snd IBSS_ATTR; 34struct snd snd IBSS_ATTR;
53int pcm_submit(void);
54 35
55#define RATE (snd.rate) 36#define RATE (snd.rate)
56#define WAVE (snd.wave) /* ram.hi+0x30 */ 37#define WAVE (ram.hi+0x30)
57#define S1 (snd.ch[0]) 38#define S1 (snd.ch[0])
58#define S2 (snd.ch[1]) 39#define S2 (snd.ch[1])
59#define S3 (snd.ch[2]) 40#define S3 (snd.ch[2])
60#define S4 (snd.ch[3]) 41#define S4 (snd.ch[3])
61 42
62rcvar_t sound_exports[] =
63{
64 RCV_END
65};
66
67
68static void s1_freq_d(int d) 43static void s1_freq_d(int d)
69{ 44{
70 if (RATE > (d<<4)) S1.freq = 0; 45 if (RATE > (d<<4)) S1.freq = 0;
@@ -86,14 +61,13 @@ static void s2_freq(void)
86static void s3_freq(void) 61static void s3_freq(void)
87{ 62{
88 int d = 2048 - (((R_NR34&7)<<8) + R_NR33); 63 int d = 2048 - (((R_NR34&7)<<8) + R_NR33);
89 if (RATE > (d<<3)) S3.freq = 0; 64 if (RATE > d) S3.freq = 0;
90 else S3.freq = (RATE << 21)/d; 65 else S3.freq = (RATE << 21)/d;
91} 66}
92 67
93static void s4_freq(void) 68static void s4_freq(void)
94{ 69{
95 S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE; 70 S4.freq = (freqtab[R_NR43&7] >> (R_NR43 >> 4)) * RATE;
96 if (S4.freq >> 18) S4.freq = 1<<18;
97} 71}
98 72
99void sound_dirty(void) 73void sound_dirty(void)
@@ -103,13 +77,13 @@ void sound_dirty(void)
103 S1.envol = R_NR12 >> 4; 77 S1.envol = R_NR12 >> 4;
104 S1.endir = (R_NR12>>3) & 1; 78 S1.endir = (R_NR12>>3) & 1;
105 S1.endir |= S1.endir - 1; 79 S1.endir |= S1.endir - 1;
106 S1.enlen = (R_NR12 & 7) << 15; 80 S1.enlen = (R_NR12 & 3) << 15;
107 s1_freq(); 81 s1_freq();
108 S2.len = (64-(R_NR21&63)) << 13; 82 S2.len = (64-(R_NR21&63)) << 13;
109 S2.envol = R_NR22 >> 4; 83 S2.envol = R_NR22 >> 4;
110 S2.endir = (R_NR22>>3) & 1; 84 S2.endir = (R_NR22>>3) & 1;
111 S2.endir |= S2.endir - 1; 85 S2.endir |= S2.endir - 1;
112 S2.enlen = (R_NR22 & 7) << 15; 86 S2.enlen = (R_NR22 & 3) << 15;
113 s2_freq(); 87 s2_freq();
114 S3.len = (256-R_NR31) << 20; 88 S3.len = (256-R_NR31) << 20;
115 s3_freq(); 89 s3_freq();
@@ -117,16 +91,16 @@ void sound_dirty(void)
117 S4.envol = R_NR42 >> 4; 91 S4.envol = R_NR42 >> 4;
118 S4.endir = (R_NR42>>3) & 1; 92 S4.endir = (R_NR42>>3) & 1;
119 S4.endir |= S4.endir - 1; 93 S4.endir |= S4.endir - 1;
120 S4.enlen = (R_NR42 & 7) << 15; 94 S4.enlen = (R_NR42 & 3) << 15;
121 s4_freq(); 95 s4_freq();
122} 96}
123 97
124void sound_off(void) 98void sound_reset(void)
125{ 99{
126 memset(&S1, 0, sizeof S1); 100 int i;
127 memset(&S2, 0, sizeof S2); 101 memset(&snd, 0, sizeof snd);
128 memset(&S3, 0, sizeof S3); 102 if (pcm.hz) snd.rate = (1<<21) / pcm.hz;
129 memset(&S4, 0, sizeof S4); 103 else snd.rate = 0;
130 R_NR10 = 0x80; 104 R_NR10 = 0x80;
131 R_NR11 = 0xBF; 105 R_NR11 = 0xBF;
132 R_NR12 = 0xF3; 106 R_NR12 = 0xF3;
@@ -137,7 +111,7 @@ void sound_off(void)
137 R_NR30 = 0x7F; 111 R_NR30 = 0x7F;
138 R_NR31 = 0xFF; 112 R_NR31 = 0xFF;
139 R_NR32 = 0x9F; 113 R_NR32 = 0x9F;
140 R_NR33 = 0xBF; 114 R_NR34 = 0xBF;
141 R_NR41 = 0xFF; 115 R_NR41 = 0xFF;
142 R_NR42 = 0x00; 116 R_NR42 = 0x00;
143 R_NR43 = 0x00; 117 R_NR43 = 0x00;
@@ -145,23 +119,13 @@ void sound_off(void)
145 R_NR50 = 0x77; 119 R_NR50 = 0x77;
146 R_NR51 = 0xF3; 120 R_NR51 = 0xF3;
147 R_NR52 = 0xF1; 121 R_NR52 = 0xF1;
122 for (i = 0; i < 16; i++) WAVE[i] = -(i&1);
148 sound_dirty(); 123 sound_dirty();
149} 124}
150 125
151void sound_reset(void)
152{
153 memset(&snd, 0, sizeof snd);
154 if (pcm.hz) snd.rate = (1<<21) / pcm.hz;
155 else snd.rate = 0;
156 memcpy(WAVE, hw.cgb ? cgbwave : dmgwave, 16);
157 memcpy(ram.hi+0x30, WAVE, 16);
158 sound_off();
159}
160
161void sound_mix(void) 126void sound_mix(void)
162{ 127{
163 128 if(!options.sound) return;
164 if (!options.sound) return;
165 int s, l, r, f, n; 129 int s, l, r, f, n;
166 130
167 if (!RATE || cpu.snd < RATE) return; 131 if (!RATE || cpu.snd < RATE) return;
@@ -185,8 +149,7 @@ void sound_mix(void)
185 } 149 }
186 if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen) 150 if (S1.swlen && (S1.swcnt += RATE) >= S1.swlen)
187 { 151 {
188 S1.swcnt -= S1.swlen; 152 f = ((R_NR14 & 7) << 8) + R_NR13;
189 f = S1.swfreq;
190 n = (R_NR10 & 7); 153 n = (R_NR10 & 7);
191 if (R_NR10 & 8) f -= (f >> n); 154 if (R_NR10 & 8) f -= (f >> n);
192 else f += (f >> n); 155 else f += (f >> n);
@@ -194,15 +157,14 @@ void sound_mix(void)
194 S1.on = 0; 157 S1.on = 0;
195 else 158 else
196 { 159 {
197 S1.swfreq = f;
198 R_NR13 = f; 160 R_NR13 = f;
199 R_NR14 = (R_NR14 & 0xF8) | (f>>8); 161 R_NR14 = (R_NR14 & 0xF8) | (f>>8);
200 s1_freq_d(2048 - f); 162 s1_freq_d(2048 - f);
201 } 163 }
202 } 164 }
203 s <<= 2; 165 s <<= 2;
204 if (R_NR51 & 1) r += s; 166 if (R_NR51 & 1) l += s;
205 if (R_NR51 & 16) l += s; 167 if (R_NR51 & 16) r += s;
206 } 168 }
207 169
208 if (S2.on) 170 if (S2.on)
@@ -219,8 +181,8 @@ void sound_mix(void)
219 if (S2.envol > 15) S2.envol = 15; 181 if (S2.envol > 15) S2.envol = 15;
220 } 182 }
221 s <<= 2; 183 s <<= 2;
222 if (R_NR51 & 2) r += s; 184 if (R_NR51 & 2) l += s;
223 if (R_NR51 & 32) l += s; 185 if (R_NR51 & 32) r += s;
224 } 186 }
225 187
226 if (S3.on) 188 if (S3.on)
@@ -234,16 +196,16 @@ void sound_mix(void)
234 S3.on = 0; 196 S3.on = 0;
235 if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3)); 197 if (R_NR32 & 96) s <<= (3 - ((R_NR32>>5)&3));
236 else s = 0; 198 else s = 0;
237 if (R_NR51 & 4) r += s; 199 if (R_NR51 & 4) l += s;
238 if (R_NR51 & 64) l += s; 200 if (R_NR51 & 64) r += s;
239 } 201 }
240 202
241 if (S4.on) 203 if (S4.on)
242 { 204 {
243 if (R_NR43 & 8) s = 1 & (noise7[ 205 if (R_NR43 & 8) s = 1 & (noise7[
244 (S4.pos>>20)&15] >> (7-((S4.pos>>17)&7))); 206 (S4.pos>>24)&15] >> ((S4.pos>>21)&7));
245 else s = 1 & (noise15[ 207 else s = 1 & (noise15[
246 (S4.pos>>20)&4095] >> (7-((S4.pos>>17)&7))); 208 (S4.pos>>24)&4095] >> ((S4.pos>>21)&7));
247 s = (-s) & S4.envol; 209 s = (-s) & S4.envol;
248 S4.pos += S4.freq; 210 S4.pos += S4.freq;
249 if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len)) 211 if ((R_NR44 & 64) && ((S4.cnt += RATE) >= S4.len))
@@ -255,9 +217,9 @@ void sound_mix(void)
255 if (S4.envol < 0) S4.envol = 0; 217 if (S4.envol < 0) S4.envol = 0;
256 if (S4.envol > 15) S4.envol = 15; 218 if (S4.envol > 15) S4.envol = 15;
257 } 219 }
258 s += s << 1; 220 s <<= 2;
259 if (R_NR51 & 8) r += s; 221 if (R_NR51 & 8) l += s;
260 if (R_NR51 & 128) l += s; 222 if (R_NR51 & 128) r += s;
261 } 223 }
262 224
263 l *= (R_NR50 & 0x07); 225 l *= (R_NR50 & 0x07);
@@ -276,10 +238,10 @@ void sound_mix(void)
276 pcm_submit(); 238 pcm_submit();
277 if (pcm.stereo) 239 if (pcm.stereo)
278 { 240 {
279 pcm.buf[pcm.pos++] = l+128; 241 pcm.buf[pcm.pos++] = l+128;
280 pcm.buf[pcm.pos++] = r+128; 242 pcm.buf[pcm.pos++] = r+128;
281 } 243 }
282 else pcm.buf[pcm.pos++] = ((l+r)>>1)+128; 244 else pcm.buf[pcm.pos++] = ((l+r)>>1)+128;
283 } 245 }
284 } 246 }
285 R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3); 247 R_NR52 = (R_NR52&0xf0) | S1.on | (S2.on<<1) | (S3.on<<2) | (S4.on<<3);
@@ -289,7 +251,7 @@ void sound_mix(void)
289 251
290byte sound_read(byte r) 252byte sound_read(byte r)
291{ 253{
292 if(!options.sound) return 0; 254 if(!options.sound) return 0;
293 sound_mix(); 255 sound_mix();
294 /* printf("read %02X: %02X\n", r, REG(r)); */ 256 /* printf("read %02X: %02X\n", r, REG(r)); */
295 return REG(r); 257 return REG(r);
@@ -298,13 +260,12 @@ byte sound_read(byte r)
298void s1_init(void) 260void s1_init(void)
299{ 261{
300 S1.swcnt = 0; 262 S1.swcnt = 0;
301 S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
302 S1.envol = R_NR12 >> 4; 263 S1.envol = R_NR12 >> 4;
303 S1.endir = (R_NR12>>3) & 1; 264 S1.endir = (R_NR12>>3) & 1;
304 S1.endir |= S1.endir - 1; 265 S1.endir |= S1.endir - 1;
305 S1.enlen = (R_NR12 & 7) << 15; 266 S1.enlen = (R_NR12 & 7) << 15;
306 if (!S1.on) S1.pos = 0;
307 S1.on = 1; 267 S1.on = 1;
268 S1.pos = 0;
308 S1.cnt = 0; 269 S1.cnt = 0;
309 S1.encnt = 0; 270 S1.encnt = 0;
310} 271}
@@ -315,20 +276,17 @@ void s2_init(void)
315 S2.endir = (R_NR22>>3) & 1; 276 S2.endir = (R_NR22>>3) & 1;
316 S2.endir |= S2.endir - 1; 277 S2.endir |= S2.endir - 1;
317 S2.enlen = (R_NR22 & 7) << 15; 278 S2.enlen = (R_NR22 & 7) << 15;
318 if (!S2.on) S2.pos = 0;
319 S2.on = 1; 279 S2.on = 1;
280 S2.pos = 0;
320 S2.cnt = 0; 281 S2.cnt = 0;
321 S2.encnt = 0; 282 S2.encnt = 0;
322} 283}
323 284
324void s3_init(void) 285void s3_init(void)
325{ 286{
326 int i; 287 S3.pos = 0;
327 if (!S3.on) S3.pos = 0;
328 S3.cnt = 0; 288 S3.cnt = 0;
329 S3.on = R_NR30 >> 7; 289 S3.on = R_NR30 >> 7;
330 if (S3.on) for (i = 0; i < 16; i++)
331 ram.hi[i+0x30] = 0x13 ^ ram.hi[i+0x31];
332} 290}
333 291
334void s4_init(void) 292void s4_init(void)
@@ -346,19 +304,13 @@ void s4_init(void)
346 304
347void sound_write(byte r, byte b) 305void sound_write(byte r, byte b)
348{ 306{
349 if(!options.sound) return; 307 if(!options.sound) return;
350#if 0
351 static void *timer;
352 if (!timer) timer = sys_timer();
353 printf("write %02X: %02X @ %d\n", r, b, sys_elapsed(timer));
354#endif
355 308
356 if (!(R_NR52 & 128) && r != RI_NR52) return; 309 if (!(R_NR52 & 128) && r != RI_NR52) return;
357 if ((r & 0xF0) == 0x30) 310 if ((r & 0xF0) == 0x30)
358 { 311 {
359 if (S3.on) sound_mix(); 312 if (S3.on) sound_mix();
360 if (!S3.on) 313 if (!S3.on) WAVE[r - 0x30] = b;
361 WAVE[r-0x30] = ram.hi[r] = b;
362 return; 314 return;
363 } 315 }
364 sound_mix(); 316 sound_mix();
@@ -366,8 +318,6 @@ void sound_write(byte r, byte b)
366 { 318 {
367 case RI_NR10: 319 case RI_NR10:
368 R_NR10 = b; 320 R_NR10 = b;
369 S1.swlen = ((R_NR10>>4) & 7) << 14;
370 S1.swfreq = ((R_NR14&7)<<8) + R_NR13;
371 break; 321 break;
372 case RI_NR11: 322 case RI_NR11:
373 R_NR11 = b; 323 R_NR11 = b;
@@ -415,7 +365,7 @@ void sound_write(byte r, byte b)
415 break; 365 break;
416 case RI_NR31: 366 case RI_NR31:
417 R_NR31 = b; 367 R_NR31 = b;
418 S3.len = (256-R_NR31) << 13; 368 S3.len = (256-R_NR31) << 20;
419 break; 369 break;
420 case RI_NR32: 370 case RI_NR32:
421 R_NR32 = b; 371 R_NR32 = b;
@@ -457,7 +407,7 @@ void sound_write(byte r, byte b)
457 case RI_NR52: 407 case RI_NR52:
458 R_NR52 = b; 408 R_NR52 = b;
459 if (!(R_NR52 & 128)) 409 if (!(R_NR52 & 128))
460 sound_off(); 410 sound_reset();
461 break; 411 break;
462 default: 412 default:
463 return; 413 return;