PCem
view src/sound_sb.c @ 133:24b744b9a632
ViRGE S3D triangle rendering now uses worker thread.
Fixed clipping bug on ViRGE.
Fixed status window crash.
| author | TomW |
|---|---|
| date | Tue Jul 22 21:10:39 2014 +0100 |
| parents | f749363ad763 |
| children |
line source
1 #include <stdlib.h>
2 #include "ibm.h"
3 #include "device.h"
4 #include "sound_emu8k.h"
5 #include "sound_mpu401_uart.h"
6 #include "sound_opl.h"
7 #include "sound_sb.h"
8 #include "sound_sb_dsp.h"
10 #include "filters.h"
12 typedef struct sb_mixer_t
13 {
14 int master_l, master_r;
15 int voice_l, voice_r;
16 int fm_l, fm_r;
17 int bass_l, bass_r;
18 int treble_l, treble_r;
19 int filter;
21 int index;
22 uint8_t regs[256];
23 } sb_mixer_t;
25 typedef struct sb_t
26 {
27 opl_t opl;
28 sb_dsp_t dsp;
29 sb_mixer_t mixer;
30 mpu401_uart_t mpu;
31 emu8k_t emu8k;
33 int16_t opl_buffer[SOUNDBUFLEN * 2];
34 int16_t dsp_buffer[SOUNDBUFLEN * 2];
35 int16_t emu8k_buffer[SOUNDBUFLEN * 2];
37 int pos;
38 } sb_t;
40 static int sb_att[]=
41 {
42 310,368,437,520,618,735,873,1038,1234,1467,1743,2072,2463,2927,3479,
43 4134,4914,5840,6941,8250,9805,11653,13850,16461,19564,23252,27635,32845,
44 39036,46395,55140,65535
45 };
49 static void sb_opl2_poll(void *p)
50 {
51 sb_t *sb = (sb_t *)p;
53 if (sb->pos >= SOUNDBUFLEN) return;
55 opl2_poll(&sb->opl, &sb->opl_buffer[sb->pos * 2], &sb->opl_buffer[(sb->pos * 2) + 1]);
56 sb_dsp_poll(&sb->dsp, &sb->dsp_buffer[sb->pos * 2], &sb->dsp_buffer[(sb->pos * 2) + 1]);
57 sb->pos++;
58 }
60 static void sb_opl3_poll(void *p)
61 {
62 sb_t *sb = (sb_t *)p;
64 if (sb->pos >= SOUNDBUFLEN) return;
66 opl3_poll(&sb->opl, &sb->opl_buffer[sb->pos * 2], &sb->opl_buffer[(sb->pos * 2) + 1]);
67 sb_dsp_poll(&sb->dsp, &sb->dsp_buffer[sb->pos * 2], &sb->dsp_buffer[(sb->pos * 2) + 1]);
68 sb->pos++;
69 }
71 static void sb_emu8k_poll(void *p)
72 {
73 sb_t *sb = (sb_t *)p;
75 if (sb->pos >= SOUNDBUFLEN) return;
77 opl3_poll(&sb->opl, &sb->opl_buffer[sb->pos * 2], &sb->opl_buffer[(sb->pos * 2) + 1]);
78 sb_dsp_poll(&sb->dsp, &sb->dsp_buffer[sb->pos * 2], &sb->dsp_buffer[(sb->pos * 2) + 1]);
79 emu8k_poll_getsamp(&sb->emu8k, &sb->emu8k_buffer[sb->pos * 2], &sb->emu8k_buffer[(sb->pos * 2) + 1]);
80 sb->pos++;
81 }
83 static void sb_get_buffer(int16_t *buffer, int len, void *p)
84 {
85 sb_t *sb = (sb_t *)p;
86 sb_mixer_t *mixer = &sb->mixer;
88 int c;
90 for (c = 0; c < len * 2; c += 2)
91 {
92 int16_t out_l, out_r;
94 out_l = ((sb->opl_buffer[c] * mixer->fm_l) >> 16);
95 out_r = ((sb->opl_buffer[c + 1] * mixer->fm_r) >> 16);
97 out_l += ((sb->emu8k_buffer[c] * mixer->fm_l) >> 16);
98 out_r += ((sb->emu8k_buffer[c + 1] * mixer->fm_l) >> 16);
100 if (sb->mixer.filter)
101 {
102 out_l += (int)(((sb_iir(0, (float)sb->dsp_buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 16;
103 out_r += (int)(((sb_iir(1, (float)sb->dsp_buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16;
104 }
105 else
106 {
107 out_l += ((sb->dsp_buffer[c] * mixer->voice_l) / 3) >> 16;
108 out_r += ((sb->dsp_buffer[c + 1] * mixer->voice_r) / 3) >> 16;
109 }
111 out_l = (out_l * mixer->master_l) >> 16;
112 out_r = (out_r * mixer->master_r) >> 16;
114 if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8)
115 {
116 if (mixer->bass_l>8) out_l = (out_l + (((int16_t) low_iir(0, (float)out_l) * (mixer->bass_l - 8)) >> 1)) * ((15 - mixer->bass_l) + 16) >> 5;
117 if (mixer->bass_r>8) out_r = (out_r + (((int16_t) low_iir(1, (float)out_r) * (mixer->bass_r - 8)) >> 1)) * ((15 - mixer->bass_r) + 16) >> 5;
118 if (mixer->treble_l>8) out_l = (out_l + (((int16_t) high_iir(0, (float)out_l) * (mixer->treble_l - 8)) >> 1)) * ((15 - mixer->treble_l) + 16) >> 5;
119 if (mixer->treble_r>8) out_r = (out_r + (((int16_t) high_iir(1, (float)out_r) * (mixer->treble_r - 8)) >> 1)) * ((15 - mixer->treble_r) + 16) >> 5;
120 if (mixer->bass_l<8) out_l = (out_l + (((int16_t) low_cut_iir(0, (float)out_l) * (8 - mixer->bass_l)) >> 1)) * (mixer->bass_l + 16) >> 5;
121 if (mixer->bass_r<8) out_r = (out_r + (((int16_t) low_cut_iir(1, (float)out_r) * (8 - mixer->bass_r)) >> 1)) * (mixer->bass_r + 16) >> 5;
122 if (mixer->treble_l<8) out_l = (out_l + (((int16_t)high_cut_iir(0, (float)out_l) * (8 - mixer->treble_l)) >> 1)) * (mixer->treble_l + 16) >> 5;
123 if (mixer->treble_r<8) out_r = (out_r + (((int16_t)high_cut_iir(1, (float)out_r) * (8 - mixer->treble_r)) >> 1)) * (mixer->treble_r + 16) >> 5;
124 }
126 buffer[c] += out_l;
127 buffer[c + 1] += out_r;
128 }
130 sb->pos = 0;
131 }
134 void sb_pro_mixer_write(uint16_t addr, uint8_t val, void *p)
135 {
136 sb_t *sb = (sb_t *)p;
137 sb_mixer_t *mixer = &sb->mixer;
139 if (!(addr & 1))
140 mixer->index = val & 0xff;
141 else
142 {
143 mixer->regs[mixer->index] = val;
145 mixer->master_l = sb_att[(mixer->regs[0x22] >> 4) | 0x11];
146 mixer->master_r = sb_att[(mixer->regs[0x22] & 0xf) | 0x11];
147 mixer->voice_l = sb_att[(mixer->regs[0x04] >> 4) | 0x11];
148 mixer->voice_r = sb_att[(mixer->regs[0x04] & 0xf) | 0x11];
149 mixer->fm_l = sb_att[(mixer->regs[0x26] >> 4) | 0x11];
150 mixer->fm_r = sb_att[(mixer->regs[0x26] & 0xf) | 0x11];
151 mixer->filter = !(mixer->regs[0xe] & 0x20);
152 mixer->bass_l = mixer->bass_r = 8;
153 mixer->treble_l = mixer->treble_r = 8;
154 // pclog("%02X %02X %02X\n", mixer->regs[0x04], mixer->regs[0x22], mixer->regs[0x26]);
155 // pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r);
156 if (mixer->index == 0xe)
157 sb_dsp_set_stereo(&sb->dsp, val & 2);
158 }
159 }
161 uint8_t sb_pro_mixer_read(uint16_t addr, void *p)
162 {
163 sb_t *sb = (sb_t *)p;
164 sb_mixer_t *mixer = &sb->mixer;
166 if (!(addr & 1))
167 return mixer->index;
169 return mixer->regs[mixer->index];
170 }
172 void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p)
173 {
174 sb_t *sb = (sb_t *)p;
175 sb_mixer_t *mixer = &sb->mixer;
177 if (!(addr & 1))
178 mixer->index = val;
179 else
180 {
181 mixer->regs[mixer->index] = val;
182 switch (mixer->index)
183 {
184 case 0x22:
185 mixer->regs[0x30] = ((mixer->regs[0x22] >> 4) | 0x11) << 3;
186 mixer->regs[0x31] = ((mixer->regs[0x22] & 0xf) | 0x11) << 3;
187 break;
188 case 0x04:
189 mixer->regs[0x32] = ((mixer->regs[0x04] >> 4) | 0x11) << 3;
190 mixer->regs[0x33] = ((mixer->regs[0x04] & 0xf) | 0x11) << 3;
191 break;
192 case 0x26:
193 mixer->regs[0x34] = ((mixer->regs[0x26] >> 4) | 0x11) << 3;
194 mixer->regs[0x35] = ((mixer->regs[0x26] & 0xf) | 0x11) << 3;
195 break;
196 case 0x80:
197 if (val & 1) sb->dsp.sb_irqnum = 2;
198 if (val & 2) sb->dsp.sb_irqnum = 5;
199 if (val & 4) sb->dsp.sb_irqnum = 7;
200 if (val & 8) sb->dsp.sb_irqnum = 10;
201 break;
202 }
203 mixer->master_l = sb_att[mixer->regs[0x30] >> 3];
204 mixer->master_r = sb_att[mixer->regs[0x31] >> 3];
205 mixer->voice_l = sb_att[mixer->regs[0x32] >> 3];
206 mixer->voice_r = sb_att[mixer->regs[0x33] >> 3];
207 mixer->fm_l = sb_att[mixer->regs[0x34] >> 3];
208 mixer->fm_r = sb_att[mixer->regs[0x35] >> 3];
209 mixer->bass_l = mixer->regs[0x46] >> 4;
210 mixer->bass_r = mixer->regs[0x47] >> 4;
211 mixer->treble_l = mixer->regs[0x44] >> 4;
212 mixer->treble_r = mixer->regs[0x45] >> 4;
213 mixer->filter = 0;
214 // pclog("%02X %02X %02X %02X %02X %02X\n", mixer->regs[0x30], mixer->regs[0x31], mixer->regs[0x32], mixer->regs[0x33], mixer->regs[0x34], mixer->regs[0x35]);
215 // pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r);
216 }
217 }
219 uint8_t sb_16_mixer_read(uint16_t addr, void *p)
220 {
221 sb_t *sb = (sb_t *)p;
222 sb_mixer_t *mixer = &sb->mixer;
224 if (!(addr & 1))
225 return mixer->index;
227 switch (mixer->index)
228 {
229 case 0x80:
230 switch (sb->dsp.sb_irqnum)
231 {
232 case 2: return 1; /*IRQ 7*/
233 case 5: return 2; /*IRQ 7*/
234 case 7: return 4; /*IRQ 7*/
235 case 10: return 8; /*IRQ 7*/
236 }
237 break;
238 case 0x81:
239 return 0x22; /*DMA 1 and 5*/
240 case 0x82:
241 return ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0);
242 }
243 return mixer->regs[mixer->index];
244 }
246 void sb_mixer_init(sb_mixer_t *mixer)
247 {
248 mixer->master_l = mixer->master_r = 65535;
249 mixer->voice_l = mixer->voice_r = 65535;
250 mixer->fm_l = mixer->fm_r = 65535;
251 mixer->bass_l = mixer->bass_r = 8;
252 mixer->treble_l = mixer->treble_r = 8;
253 mixer->filter = 1;
254 }
256 void *sb_1_init()
257 {
258 sb_t *sb = malloc(sizeof(sb_t));
259 uint16_t addr = device_get_config_int("addr");
260 memset(sb, 0, sizeof(sb_t));
262 opl2_init(&sb->opl);
263 sb_dsp_init(&sb->dsp, SB1);
264 sb_dsp_setaddr(&sb->dsp, addr);
265 sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
266 sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
267 sb_mixer_init(&sb->mixer);
268 io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
269 io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
270 sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
271 return sb;
272 }
273 void *sb_15_init()
274 {
275 sb_t *sb = malloc(sizeof(sb_t));
276 uint16_t addr = device_get_config_int("addr");
277 memset(sb, 0, sizeof(sb_t));
279 opl2_init(&sb->opl);
280 sb_dsp_init(&sb->dsp, SB15);
281 sb_dsp_setaddr(&sb->dsp, addr);
282 sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
283 sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
284 sb_mixer_init(&sb->mixer);
285 io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
286 io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
287 sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
288 return sb;
289 }
290 void *sb_2_init()
291 {
292 sb_t *sb = malloc(sizeof(sb_t));
293 uint16_t addr = device_get_config_int("addr");
294 memset(sb, 0, sizeof(sb_t));
296 opl2_init(&sb->opl);
297 sb_dsp_init(&sb->dsp, SB2);
298 sb_dsp_setaddr(&sb->dsp, addr);
299 sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
300 sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
301 sb_mixer_init(&sb->mixer);
302 io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
303 io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
304 sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
305 return sb;
306 }
308 void *sb_pro_v1_init()
309 {
310 sb_t *sb = malloc(sizeof(sb_t));
311 uint16_t addr = device_get_config_int("addr");
312 memset(sb, 0, sizeof(sb_t));
314 opl2_init(&sb->opl);
315 sb_dsp_init(&sb->dsp, SBPRO);
316 sb_dsp_setaddr(&sb->dsp, addr);
317 sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
318 sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
319 sb_mixer_init(&sb->mixer);
320 io_sethandler(addr+0, 0x0002, opl2_l_read, NULL, NULL, opl2_l_write, NULL, NULL, &sb->opl);
321 io_sethandler(addr+2, 0x0002, opl2_r_read, NULL, NULL, opl2_r_write, NULL, NULL, &sb->opl);
322 io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
323 io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
324 io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb);
325 sound_add_handler(sb_opl2_poll, sb_get_buffer, sb);
327 sb->mixer.regs[0x22] = 0xff;
328 sb->mixer.regs[0x04] = 0xff;
329 sb->mixer.regs[0x26] = 0xff;
330 sb->mixer.regs[0xe] = 0;
332 return sb;
333 }
335 void *sb_pro_v2_init()
336 {
337 sb_t *sb = malloc(sizeof(sb_t));
338 uint16_t addr = device_get_config_int("addr");
339 memset(sb, 0, sizeof(sb_t));
341 opl3_init(&sb->opl);
342 sb_dsp_init(&sb->dsp, SBPRO2);
343 sb_dsp_setaddr(&sb->dsp, addr);
344 sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
345 sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
346 sb_mixer_init(&sb->mixer);
347 io_sethandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
348 io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
349 io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
350 io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb);
351 sound_add_handler(sb_opl3_poll, sb_get_buffer, sb);
353 sb->mixer.regs[0x22] = 0xff;
354 sb->mixer.regs[0x04] = 0xff;
355 sb->mixer.regs[0x26] = 0xff;
356 sb->mixer.regs[0xe] = 0;
358 return sb;
359 }
361 void *sb_16_init()
362 {
363 sb_t *sb = malloc(sizeof(sb_t));
364 memset(sb, 0, sizeof(sb_t));
366 opl3_init(&sb->opl);
367 sb_dsp_init(&sb->dsp, SB16);
368 sb_dsp_setaddr(&sb->dsp, 0x0220);
369 sb_mixer_init(&sb->mixer);
370 io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
371 io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
372 io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
373 io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb);
374 sound_add_handler(sb_opl3_poll, sb_get_buffer, sb);
375 mpu401_uart_init(&sb->mpu, 0x330);
377 sb->mixer.regs[0x30] = 31 << 3;
378 sb->mixer.regs[0x31] = 31 << 3;
379 sb->mixer.regs[0x32] = 31 << 3;
380 sb->mixer.regs[0x33] = 31 << 3;
381 sb->mixer.regs[0x34] = 31 << 3;
382 sb->mixer.regs[0x35] = 31 << 3;
383 sb->mixer.regs[0x44] = 8 << 4;
384 sb->mixer.regs[0x45] = 8 << 4;
385 sb->mixer.regs[0x46] = 8 << 4;
386 sb->mixer.regs[0x47] = 8 << 4;
387 sb->mixer.regs[0x22] = (sb->mixer.regs[0x30] & 0xf0) | (sb->mixer.regs[0x31] >> 4);
388 sb->mixer.regs[0x04] = (sb->mixer.regs[0x32] & 0xf0) | (sb->mixer.regs[0x33] >> 4);
389 sb->mixer.regs[0x26] = (sb->mixer.regs[0x34] & 0xf0) | (sb->mixer.regs[0x35] >> 4);
391 return sb;
392 }
394 int sb_awe32_available()
395 {
396 return rom_present("roms/awe32.raw");
397 }
399 void *sb_awe32_init()
400 {
401 sb_t *sb = malloc(sizeof(sb_t));
402 memset(sb, 0, sizeof(sb_t));
404 opl3_init(&sb->opl);
405 sb_dsp_init(&sb->dsp, SB16 + 1);
406 sb_dsp_setaddr(&sb->dsp, 0x0220);
407 sb_mixer_init(&sb->mixer);
408 io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
409 io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
410 io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
411 io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb);
412 sound_add_handler(sb_emu8k_poll, sb_get_buffer, sb);
413 mpu401_uart_init(&sb->mpu, 0x330);
414 emu8k_init(&sb->emu8k);
416 sb->mixer.regs[0x30] = 31 << 3;
417 sb->mixer.regs[0x31] = 31 << 3;
418 sb->mixer.regs[0x32] = 31 << 3;
419 sb->mixer.regs[0x33] = 31 << 3;
420 sb->mixer.regs[0x34] = 31 << 3;
421 sb->mixer.regs[0x35] = 31 << 3;
422 sb->mixer.regs[0x44] = 8 << 4;
423 sb->mixer.regs[0x45] = 8 << 4;
424 sb->mixer.regs[0x46] = 8 << 4;
425 sb->mixer.regs[0x47] = 8 << 4;
426 sb->mixer.regs[0x22] = (sb->mixer.regs[0x30] & 0xf0) | (sb->mixer.regs[0x31] >> 4);
427 sb->mixer.regs[0x04] = (sb->mixer.regs[0x32] & 0xf0) | (sb->mixer.regs[0x33] >> 4);
428 sb->mixer.regs[0x26] = (sb->mixer.regs[0x34] & 0xf0) | (sb->mixer.regs[0x35] >> 4);
430 return sb;
431 }
433 void sb_close(void *p)
434 {
435 sb_t *sb = (sb_t *)p;
437 free(sb);
438 }
440 void sb_speed_changed(void *p)
441 {
442 sb_t *sb = (sb_t *)p;
444 sb_dsp_speed_changed(&sb->dsp);
445 }
447 void sb_add_status_info(char *s, int max_len, void *p)
448 {
449 sb_t *sb = (sb_t *)p;
451 sb_dsp_add_status_info(s, max_len, &sb->dsp);
452 }
454 static device_config_t sb_config[] =
455 {
456 {
457 .name = "addr",
458 .description = "Address",
459 .type = CONFIG_BINARY,
460 .type = CONFIG_SELECTION,
461 .selection =
462 {
463 {
464 .description = "0x220",
465 .value = 0x220
466 },
467 {
468 .description = "0x240",
469 .value = 0x240
470 },
471 {
472 .description = ""
473 }
474 },
475 .default_int = 0x220
476 },
477 {
478 .name = "irq",
479 .description = "IRQ",
480 .type = CONFIG_SELECTION,
481 .selection =
482 {
483 {
484 .description = "IRQ 2",
485 .value = 2
486 },
487 {
488 .description = "IRQ 3",
489 .value = 3
490 },
491 {
492 .description = "IRQ 5",
493 .value = 5
494 },
495 {
496 .description = "IRQ 7",
497 .value = 7
498 },
499 {
500 .description = ""
501 }
502 },
503 .default_int = 7
504 },
505 {
506 .name = "dma",
507 .description = "DMA",
508 .type = CONFIG_SELECTION,
509 .selection =
510 {
511 {
512 .description = "DMA 1",
513 .value = 1
514 },
515 {
516 .description = "DMA 3",
517 .value = 3
518 },
519 {
520 .description = ""
521 }
522 },
523 .default_int = 1
524 },
525 {
526 .type = -1
527 }
528 };
530 static device_config_t sb_pro_config[] =
531 {
532 {
533 .name = "addr",
534 .description = "Address",
535 .type = CONFIG_BINARY,
536 .type = CONFIG_SELECTION,
537 .selection =
538 {
539 {
540 .description = "0x220",
541 .value = 0x220
542 },
543 {
544 .description = "0x240",
545 .value = 0x240
546 },
547 {
548 .description = ""
549 }
550 },
551 .default_int = 0x220
552 },
553 {
554 .name = "irq",
555 .description = "IRQ",
556 .type = CONFIG_SELECTION,
557 .selection =
558 {
559 {
560 .description = "IRQ 2",
561 .value = 2
562 },
563 {
564 .description = "IRQ 5",
565 .value = 5
566 },
567 {
568 .description = "IRQ 7",
569 .value = 7
570 },
571 {
572 .description = "IRQ 10",
573 .value = 10
574 },
575 {
576 .description = ""
577 }
578 },
579 .default_int = 7
580 },
581 {
582 .name = "dma",
583 .description = "DMA",
584 .type = CONFIG_SELECTION,
585 .selection =
586 {
587 {
588 .description = "DMA 1",
589 .value = 1
590 },
591 {
592 .description = "DMA 3",
593 .value = 3
594 },
595 {
596 .description = ""
597 }
598 },
599 .default_int = 1
600 },
601 {
602 .type = -1
603 }
604 };
606 device_t sb_1_device =
607 {
608 "Sound Blaster v1.0",
609 0,
610 sb_1_init,
611 sb_close,
612 NULL,
613 sb_speed_changed,
614 NULL,
615 sb_add_status_info,
616 sb_config
617 };
618 device_t sb_15_device =
619 {
620 "Sound Blaster v1.5",
621 0,
622 sb_15_init,
623 sb_close,
624 NULL,
625 sb_speed_changed,
626 NULL,
627 sb_add_status_info,
628 sb_config
629 };
630 device_t sb_2_device =
631 {
632 "Sound Blaster v2.0",
633 0,
634 sb_2_init,
635 sb_close,
636 NULL,
637 sb_speed_changed,
638 NULL,
639 sb_add_status_info,
640 sb_config
641 };
642 device_t sb_pro_v1_device =
643 {
644 "Sound Blaster Pro v1",
645 0,
646 sb_pro_v1_init,
647 sb_close,
648 NULL,
649 sb_speed_changed,
650 NULL,
651 sb_add_status_info,
652 sb_pro_config
653 };
654 device_t sb_pro_v2_device =
655 {
656 "Sound Blaster Pro v2",
657 0,
658 sb_pro_v2_init,
659 sb_close,
660 NULL,
661 sb_speed_changed,
662 NULL,
663 sb_add_status_info,
664 sb_pro_config
665 };
666 device_t sb_16_device =
667 {
668 "Sound Blaster 16",
669 0,
670 sb_16_init,
671 sb_close,
672 NULL,
673 sb_speed_changed,
674 NULL,
675 sb_add_status_info
676 };
677 device_t sb_awe32_device =
678 {
679 "Sound Blaster AWE32",
680 0,
681 sb_awe32_init,
682 sb_close,
683 sb_awe32_available,
684 sb_speed_changed,
685 NULL,
686 sb_add_status_info
687 };
