1 /* FIXME: This code is failing to detect that it's running under the latest (4.3) VirtualBox. Why? */
3 /* TODO: Add a flag to the sound blaster context to track whether or not DSP playback/record is active. */
5 /* TODO: How to add support for full duplex audio? ESS 688 and 1869 chipsets for example can do full
6 * duplex but only at the same sample rate. I'm not sure if Sound Blaster 16 ViBRA cards can
9 /* FIXME: This just in: your IRQ testing routine can hang the system especially (as in DOSBox) when IRQs that are
10 * normally masked have a corresponding interrupt vector set to NULL (0000:0000). You need to double-check
11 * the probe function and make sure there is no possible way uninitialized vectors execute when any
12 * particular IRQ is fired. */
14 /* FIXME: On a laptop with ESS 688 playing 16-bit PCM with auto-init DSP and auto-init DMA, the IRQ does not
15 * fire periodically as it should. Any other mode (auto-init DMA with single-cycle DMA, or any of the
16 * 8-bit modes) fires the IRQ periodically as in auto-init. This is important for anyone who might try
17 * to use this library to play music entirely from the interrupt. */
19 /* FIXME: There might be a way to deal with some troubles you've been having with this code:
22 * - Gravis SBOS/MEGA-EM NMI causes DOS4GW.EXE to hard-reset the machine rather than deal with it
23 * - Even when your code caught the NMI and forwarded it to Gravis's TSRs, Sound Blaster emulation
24 * failed to signal your interrupt handler, which is probably why 16-bit real mode builds worked
25 * fine with SBOS/MEGA-EM while 32-bit builds did not.
26 * - Under DOS4GW.EXE (but not DOS32A.EXE) using IRQ 8-15 eventually resulted in missing an IRQ.
27 * I initially panned it as DOS4GW.EXE being a cheap son-of-a-bitch but it might be related instead
28 * to a combination of the BIOS forwarding interrupts in real mode, and the lack of a real-mode
29 * interrupt handler for the Sound Blaster library.
32 * - Add code to set the interrupt vector for the IRQ on behalf of the calling program. The calling
33 * program provides a function to call, and you set the vector (and keep track of the previous one).
34 * - Also add function to remove interrupt vector. Write the code so that if someone else hooked,
35 * the unhook function returns an error.
36 * - Add code to interrupt vector hooking code so that in 32-bit builds, if MEGA-EM or SBOS is resident
37 * or DOS4GW.EXE is resident and IRQ 8-15 is to be used, this code automatically installs a real-mode
38 * interrupt vector that reflects the interrupt into protected mode.
39 * - Add code so that, in 32-bit builds, if MEGA-EM or SBOS is resident, the library hooks the NMI
40 * interrupt in protected mode and reflects it to real-mode so Gravis's emulation can work. [FIXME
41 * can you also resolve DOS4GW.EXE hard-crashing in this situation?] */
43 /* Primary Sound Blaster support library.
44 * This compiles into sndsb.lib.
45 * This DOES NOT include support for Plug & Play versions,
46 * functions for that are in sndsbpnp.c -> sndsbpnp.lib */
49 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
58 #include <hw/dos/dos.h>
59 #include <hw/dos/dosbox.h>
60 #include <hw/8237/8237.h> /* 8237 DMA */
61 #include <hw/8254/8254.h> /* 8254 timer */
62 #include <hw/8259/8259.h> /* 8259 PIC interrupts */
63 #include <hw/sndsb/sndsb.h>
64 #include <hw/dos/doswin.h>
65 #include <hw/dos/tgusmega.h>
66 #include <hw/dos/tgussbos.h>
68 /* Windows 9x VxD enumeration */
69 #include <windows/w9xvmm/vxd_enum.h>
71 /* uncomment this to enable debugging messages */
80 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
83 static int adpcm_pred = 128;
84 static signed char adpcm_last = 0;
85 static unsigned char adpcm_step = 0;
86 static unsigned char adpcm_error = 0;
87 static unsigned char adpcm_lim = 0;
90 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
94 struct sndsb_mixer_control sndsb_mixer_ct1335[] = {
95 /* index, of,ln,name */
96 {0x02, 1, 3, "Master"},
103 struct sndsb_mixer_control sndsb_mixer_ct1345[] = {
104 /* index, of,ln,name */
105 {0x04, 1, 3, "Voice R"}, {0x04, 5, 3, "Voice L"},
107 {0x0C, 1, 2, "Input source"}, {0x0C, 3, 1, "Lowpass filter"}, {0x0C, 5, 1, "Input filter"},
108 {0x0E, 1, 1, "Stereo switch"}, {0x0E, 5, 1, "Output filter"},
109 {0x22, 1, 3, "Master R"}, {0x22, 5, 3, "Master L"},
110 {0x26, 1, 3, "MIDI R"}, {0x26, 5, 3, "MIDI L"},
111 {0x28, 1, 3, "CD R"}, {0x28, 5, 3, "CD L"},
112 {0x2E, 1, 3, "Line R"}, {0x2E, 5, 3, "Line L"}
116 struct sndsb_mixer_control sndsb_mixer_ct1745[] = {
117 /* index, of,ln,name */
118 {0x30, 3, 5, "Master L"}, {0x31, 3, 5, "Master R"},
119 {0x32, 3, 5, "Volume L"}, {0x33, 3, 5, "Volume R"},
120 {0x34, 3, 5, "MIDI L"}, {0x35, 3, 5, "MIDI R"},
121 {0x36, 3, 5, "CD L"}, {0x37, 3, 5, "CD R"},
122 {0x38, 3, 5, "Line L"}, {0x39, 3, 5, "Line R"},
124 {0x3B, 6, 2, "PC speaker"},
126 {0x3C, 0, 1, "Out mixer: mic"},
127 {0x3C, 1, 1, "Out mixer: CD R"},
128 {0x3C, 2, 1, "Out mixer: CD L"},
129 {0x3C, 3, 1, "Out mixer: Line R"},
130 {0x3C, 4, 1, "Out mixer: Line L"},
132 {0x3D, 0, 1, "In mixer L: Mic"},
133 {0x3D, 1, 1, "In mixer L: CD R"},
134 {0x3D, 2, 1, "In mixer L: CD L"},
135 {0x3D, 3, 1, "In mixer L: Line R"},
136 {0x3D, 4, 1, "In mixer L: Line L"},
137 {0x3D, 5, 1, "In mixer L: MIDI R"},
138 {0x3D, 6, 1, "In mixer L: MIDI L"},
140 {0x3E, 0, 1, "In mixer R: Mic"},
141 {0x3E, 1, 1, "In mixer R: CD R"},
142 {0x3E, 2, 1, "In mixer R: CD L"},
143 {0x3E, 3, 1, "In mixer R: Line R"},
144 {0x3E, 4, 1, "In mixer R: Line L"},
145 {0x3E, 5, 1, "In mixer R: MIDI R"},
146 {0x3E, 6, 1, "In mixer R: MIDI L"},
148 {0x3F, 6, 2, "Input gain L"},
149 {0x40, 6, 2, "Input gain R"},
150 {0x41, 6, 2, "Output gain L"},
151 {0x42, 6, 2, "Output gain R"},
153 {0x44, 4, 4, "Treble L"},
154 {0x45, 4, 4, "Treble R"},
155 {0x46, 4, 4, "Bass L"},
156 {0x47, 4, 4, "Bass R"}
160 signed char gallant_sc6600_map_to_dma[4] = {-1, 0, 1, 3};
161 signed char gallant_sc6600_map_to_irq[8] = {-1, 7, 9,10,11, 5,-1,-1};
163 const char* sndsb_adpcm_mode_str[4] = {
170 const char *sndsb_mixer_chip_name[SNDSB_MIXER_MAX] = {
177 const char *sndsb_dspoutmethod_str[SNDSB_DSPOUTMETHOD_MAX] = {
186 const char *sndsb_ess_chipsets_str[SNDSB_ESS_MAX] = {
192 #if TARGET_MSDOS == 32
193 signed char sndsb_nmi_32_hook = -1;
196 struct sndsb_probe_opts sndsb_probe_options={0};
197 struct sndsb_ctx sndsb_card[SNDSB_MAX_CARDS];
198 struct sndsb_ctx *sndsb_card_blaster=NULL;
199 int sndsb_card_next = 0;
201 const char *sndsb_ess_chipset_str(unsigned int c) {
202 if (c >= SNDSB_ESS_MAX) return NULL;
203 return sndsb_ess_chipsets_str[c];
206 void sndsb_timer_tick_gen(struct sndsb_ctx *cx) {
207 cx->timer_tick_signal = 1;
210 static inline void sndsb_timer_tick_directio_post_read(unsigned short port,unsigned short count) {
211 while (count-- != 0) inp(port);
214 static inline unsigned char sndsb_timer_tick_directio_poll_ready(unsigned short port,unsigned short count) {
218 } while ((r&0x80) && count-- != 0);
223 void sndsb_timer_tick_directi_data(struct sndsb_ctx *cx) {
224 if (sndsb_timer_tick_directio_poll_ready(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0),cx->dsp_direct_dac_poll_retry_timeout)) {
225 cx->buffer_lin[cx->direct_dsp_io] = inp(cx->baseio+SNDSB_BIO_DSP_READ_DATA);
227 if (cx->direct_dsp_io == 0) cx->direct_dsp_io = cx->buffer_size - 1;
228 else cx->direct_dsp_io--;
231 if ((++cx->direct_dsp_io) >= cx->buffer_size) cx->direct_dsp_io = 0;
233 cx->timer_tick_func = sndsb_timer_tick_directi_cmd;
234 cx->direct_dac_sent_command = 0;
235 sndsb_timer_tick_directio_post_read(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0),cx->dsp_direct_dac_read_after_command);
239 void sndsb_timer_tick_directi_cmd(struct sndsb_ctx *cx) {
240 if (sndsb_timer_tick_directio_poll_ready(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0),cx->dsp_direct_dac_poll_retry_timeout)) {
241 outp(cx->baseio+SNDSB_BIO_DSP_WRITE_DATA+(cx->dsp_alias_port?1:0),0x20); /* direct DAC read */
242 cx->timer_tick_func = sndsb_timer_tick_directi_data;
243 cx->direct_dac_sent_command = 1;
244 sndsb_timer_tick_directio_post_read(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0),cx->dsp_direct_dac_read_after_command);
248 void sndsb_timer_tick_directo_data(struct sndsb_ctx *cx) {
249 if (sndsb_timer_tick_directio_poll_ready(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0),cx->dsp_direct_dac_poll_retry_timeout)) {
250 outp(cx->baseio+SNDSB_BIO_DSP_WRITE_DATA+(cx->dsp_alias_port?1:0),cx->buffer_lin[cx->direct_dsp_io]);
252 if (cx->direct_dsp_io == 0) cx->direct_dsp_io = cx->buffer_size - 1;
253 else cx->direct_dsp_io--;
256 if ((++cx->direct_dsp_io) >= cx->buffer_size) cx->direct_dsp_io = 0;
258 cx->timer_tick_func = sndsb_timer_tick_directo_cmd;
259 cx->direct_dac_sent_command = 0;
260 sndsb_timer_tick_directio_post_read(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0),cx->dsp_direct_dac_read_after_command);
264 void sndsb_timer_tick_directo_cmd(struct sndsb_ctx *cx) {
265 if (sndsb_timer_tick_directio_poll_ready(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0),cx->dsp_direct_dac_poll_retry_timeout)) {
266 outp(cx->baseio+SNDSB_BIO_DSP_WRITE_DATA+(cx->dsp_alias_port?1:0),0x10); /* direct DAC write */
267 cx->timer_tick_func = sndsb_timer_tick_directo_data;
268 cx->direct_dac_sent_command = 1;
269 sndsb_timer_tick_directio_post_read(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0),cx->dsp_direct_dac_read_after_command);
273 void sndsb_timer_tick_goldi_cpy(struct sndsb_ctx *cx) {
274 cx->timer_tick_signal = 1;
275 #if TARGET_MSDOS == 32
276 memcpy(cx->buffer_lin+cx->direct_dsp_io,cx->goldplay_dma->lin,cx->gold_memcpy);
278 _fmemcpy(cx->buffer_lin+cx->direct_dsp_io,cx->goldplay_dma,cx->gold_memcpy);
281 if (cx->direct_dsp_io < cx->gold_memcpy) cx->direct_dsp_io = cx->buffer_size - cx->gold_memcpy;
282 else cx->direct_dsp_io -= cx->gold_memcpy;
285 if ((cx->direct_dsp_io += cx->gold_memcpy) >= cx->buffer_size) cx->direct_dsp_io = 0;
289 void sndsb_timer_tick_goldo_cpy(struct sndsb_ctx *cx) {
290 cx->timer_tick_signal = 1;
291 #if TARGET_MSDOS == 32
292 memcpy(cx->goldplay_dma->lin,cx->buffer_lin+cx->direct_dsp_io,cx->gold_memcpy);
294 _fmemcpy(cx->goldplay_dma,cx->buffer_lin+cx->direct_dsp_io,cx->gold_memcpy);
297 if (cx->direct_dsp_io < cx->gold_memcpy) cx->direct_dsp_io = cx->buffer_size - cx->gold_memcpy;
298 else cx->direct_dsp_io -= cx->gold_memcpy;
301 if ((cx->direct_dsp_io += cx->gold_memcpy) >= cx->buffer_size) cx->direct_dsp_io = 0;
305 struct sndsb_ctx *sndsb_by_base(uint16_t x) {
308 for (i=0;i < SNDSB_MAX_CARDS;i++) {
309 if (sndsb_card[i].baseio == x)
316 struct sndsb_ctx *sndsb_by_mpu(uint16_t x) {
319 for (i=0;i < SNDSB_MAX_CARDS;i++) {
320 if (sndsb_card[i].mpuio == x)
327 struct sndsb_ctx *sndsb_by_irq(int8_t x) {
330 for (i=0;i < SNDSB_MAX_CARDS;i++) {
331 if (sndsb_card[i].irq == x)
338 struct sndsb_ctx *sndsb_by_dma(uint16_t x) {
341 for (i=0;i < SNDSB_MAX_CARDS;i++) {
342 if (sndsb_card[i].baseio > 0 && (sndsb_card[i].dma8 == x || sndsb_card[i].dma16 == x))
349 #if TARGET_MSDOS == 32
350 int sb_nmi_32_auto_choose_hook() {
351 if (sndsb_nmi_32_hook >= 0)
352 return sndsb_nmi_32_hook;
354 /* auto-detect SBOS/MEGA-EM and enable nmi reflection if present */
355 if (gravis_mega_em_detect(&megaem_info) || gravis_sbos_detect() >= 0)
363 #if TARGET_MSDOS == 32
364 if (sndsb_nmi_32_hook) do_nmi_32_unhook();
371 memset(sndsb_card,0,sizeof(sndsb_card));
372 for (i=0;i < SNDSB_MAX_CARDS;i++)
373 sndsb_card[i].pnp_bios_node = 0xFF;
375 sndsb_card_blaster = NULL;
377 #if TARGET_MSDOS == 32
378 sndsb_nmi_32_hook = sb_nmi_32_auto_choose_hook();
379 if (sndsb_nmi_32_hook) do_nmi_32_hook();
384 struct sndsb_ctx *sndsb_alloc_card() {
387 for (i=0;i < SNDSB_MAX_CARDS;i++) {
388 if (sndsb_card[i].baseio == 0 && sndsb_card[i].mpuio == 0)
395 void sndsb_free_card(struct sndsb_ctx *c) {
396 #if TARGET_MSDOS == 32
397 if (c->goldplay_dma) {
398 dma_8237_free_buffer(c->goldplay_dma);
399 c->goldplay_dma = NULL;
402 memset(c,0,sizeof(*c));
403 c->pnp_bios_node = 0xFF;
404 if (c == sndsb_card_blaster) sndsb_card_blaster = NULL;
407 struct sndsb_ctx *sndsb_try_blaster_var() {
408 int A=-1,I=-1,D=-1,H=-1,P=-1;
412 if (sndsb_card_blaster != NULL)
413 return sndsb_card_blaster;
415 /* some of our detection relies on knowing what OS we're running under */
420 s = getenv("BLASTER");
421 if (s == NULL) return NULL;
433 else if (*s == 'P') {
437 else if (*s == 'I') {
441 else if (*s == 'D') {
445 else if (*s == 'H') {
450 while (*s && *s != ' ') s++;
451 while (*s == ' ') s++;
455 if (A < 0 || I < 0 || D < 0 || I > 15 || D > 7)
458 if (sndsb_by_base(A) != NULL)
461 e = sndsb_alloc_card();
462 if (e == NULL) return NULL;
463 #if TARGET_MSDOS == 32
464 e->goldplay_dma = NULL;
466 e->is_gallant_sc6600 = 0;
467 e->baseio = (uint16_t)A;
468 e->mpuio = (uint16_t)(P > 0 ? P : 0);
470 e->dma16 = (int8_t)H;
477 return (sndsb_card_blaster=e);
480 const char *sndsb_mixer_chip_str(uint8_t c) {
481 if (c >= SNDSB_MIXER_MAX) return NULL;
482 return sndsb_mixer_chip_name[c];
485 /* NTS: this function enforces a timeout of 250ms */
486 int sndsb_read_dsp(struct sndsb_ctx *cx) {
487 unsigned int patience = 25000;
491 if (inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS+(cx->dsp_alias_port?1:0)) & 0x80) { /* data available? */
492 c = inp(cx->baseio+SNDSB_BIO_DSP_READ_DATA);
496 t8254_wait(t8254_us2ticks(10));
497 if (--patience == 0) {
498 DEBUG(fprintf(stdout,"sndsb_read_dsp() read timeout\n"));
503 DEBUG(fprintf(stdout,"sndsb_read_dsp() == 0x%02X\n",c));
507 int sndsb_read_dsp_timeout(struct sndsb_ctx *cx,unsigned long timeout_ms) {
508 unsigned int patience = (unsigned int)(timeout_ms / 10UL);
512 if (inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS+(cx->dsp_alias_port?1:0)) & 0x80) { /* data available? */
513 c = inp(cx->baseio+SNDSB_BIO_DSP_READ_DATA);
517 t8254_wait(t8254_us2ticks(10));
518 if (--patience == 0) {
519 DEBUG(fprintf(stdout,"sndsb_read_dsp() read timeout\n"));
524 DEBUG(fprintf(stdout,"sndsb_read_dsp() == 0x%02X\n",c));
528 unsigned int sndsb_ess_set_extended_mode(struct sndsb_ctx *cx,int enable) {
529 if (cx->ess_chipset == 0) return 0; /* if not an ESS chipset then, no */
530 if (!cx->ess_extensions) return 0; /* if caller/user says not to use extensions, then, no */
531 if (cx->ess_extended_mode == !!enable) return 1;
533 if (!sndsb_write_dsp(cx,enable?0xC6:0xC7))
536 cx->ess_extended_mode = !!enable;
540 int sndsb_ess_read_controller(struct sndsb_ctx *cx,int reg) {
541 if (reg < 0xA0 || reg >= 0xC0) return -1;
542 if (sndsb_ess_set_extended_mode(cx,1) == 0) return -1;
543 /* "Reading the data buffer of the ESS 1869: Command C0h is used to read
544 * the ES1869 controller registers used for Extended mode. Send C0h
545 * followed by the register number, Axh or Bxh. */
546 if (!sndsb_write_dsp_timeout(cx,0xC0,20000UL)) return -1;
547 if (!sndsb_write_dsp_timeout(cx,reg,20000UL)) return -1;
548 return sndsb_read_dsp(cx);
551 int sndsb_ess_write_controller(struct sndsb_ctx *cx,int reg,unsigned char value) {
552 if (reg < 0xA0 || reg >= 0xC0) return -1;
553 if (sndsb_ess_set_extended_mode(cx,1) == 0) return -1;
554 if (!sndsb_write_dsp_timeout(cx,reg,20000UL)) return -1;
555 if (!sndsb_write_dsp_timeout(cx,value,20000UL)) return -1;
559 int sndsb_reset_dsp(struct sndsb_ctx *cx) {
560 if (cx->baseio == 0) {
561 DEBUG(fprintf(stdout,"BUG: sndsb baseio == 0\n"));
565 /* DSP reset takes the ESS out of extended mode */
566 if (cx->ess_chipset != 0)
567 cx->ess_extended_mode = 0;
569 /* DSP reset procedure */
570 /* "write 1 to the DSP and wait 3 microseconds" */
571 DEBUG(fprintf(stdout,"sndsb_reset_dsp() reset in progress\n"));
572 if (cx->ess_extensions)
573 outp(cx->baseio+SNDSB_BIO_DSP_RESET,3); /* ESS reset and flush FIFO */
575 outp(cx->baseio+SNDSB_BIO_DSP_RESET,1); /* normal reset */
577 t8254_wait(t8254_us2ticks(1000)); /* be safe and wait 1ms */
578 outp(cx->baseio+SNDSB_BIO_DSP_RESET,0);
580 /* wait for the DSP to return 0xAA */
581 /* "typically the DSP takes about 100us to initialize itself" */
582 if (sndsb_read_dsp(cx) != 0xAA) {
583 if (sndsb_read_dsp(cx) != 0xAA) {
584 DEBUG(fprintf(stdout,"sndsb_read_dsp() did not return satisfactory answer\n"));
592 int sndsb_read_mixer(struct sndsb_ctx *cx,uint8_t i) {
593 outp(cx->baseio+SNDSB_BIO_MIXER_INDEX,i);
594 return inp(cx->baseio+SNDSB_BIO_MIXER_DATA);
597 void sndsb_write_mixer(struct sndsb_ctx *cx,uint8_t i,uint8_t d) {
598 outp(cx->baseio+SNDSB_BIO_MIXER_INDEX,i);
599 outp(cx->baseio+SNDSB_BIO_MIXER_DATA,d);
602 unsigned char sndsb_test_write_mixer(struct sndsb_ctx *cx,uint8_t i,uint8_t d) {
604 o = sndsb_read_mixer(cx,i); sndsb_write_mixer(cx,i,d);
605 c = sndsb_read_mixer(cx,i); sndsb_write_mixer(cx,i,o);
609 /* NTS: If DOSBox's emulation is correct, 0xFF is not necessarily what is returned for
610 * unknown registers, therefore it's not an accurate way to probe the chipset.
611 * DOSBox for example seems to return 0x0A. */
612 int sndsb_probe_mixer(struct sndsb_ctx *cx) {
615 /* if there is a wider "master volume" control 0x30 then we're a CT1745 or higher */
616 if ( (sndsb_test_write_mixer(cx,0x30,0x08)&0xF8) == 0x08 &&
617 (sndsb_test_write_mixer(cx,0x30,0x38)&0xF8) == 0x38 &&
618 (sndsb_test_write_mixer(cx,0x31,0x08)&0xF8) == 0x08 &&
619 (sndsb_test_write_mixer(cx,0x31,0x38)&0xF8) == 0x38) {
620 cx->mixer_chip = SNDSB_MIXER_CT1745;
622 /* If there is a "master volume" control at 0x22 then we're at CT1345 or higher */
623 else if((sndsb_test_write_mixer(cx,0x22,0x33)&0xEE) == 0x22 &&
624 (sndsb_test_write_mixer(cx,0x22,0xCC)&0xEE) == 0xCC) {
625 cx->mixer_chip = SNDSB_MIXER_CT1345;
627 /* hm, may be at CT1335 */
628 else if((sndsb_test_write_mixer(cx,0x02,0x02)&0x0E) == 0x02 &&
629 (sndsb_test_write_mixer(cx,0x02,0x0C)&0x0E) == 0x0C) {
630 cx->mixer_chip = SNDSB_MIXER_CT1335;
633 sndsb_choose_mixer(cx,-1);
634 return (cx->mixer_chip != 0);
637 int sndsb_mpu_command(struct sndsb_ctx *cx,uint8_t d) {
638 unsigned int patience = 100;
641 if (inp(cx->mpuio+SNDSB_MPUIO_STATUS) & 0x40) /* if not ready for cmd, wait and try again */
642 t8254_wait(t8254_us2ticks(100));
644 outp(cx->mpuio+SNDSB_MPUIO_COMMAND,d);
647 } while (--patience != 0);
651 int sndsb_mpu_write(struct sndsb_ctx *cx,uint8_t d) {
652 unsigned int patience = 100;
655 if (inp(cx->mpuio+SNDSB_MPUIO_STATUS) & 0x40) /* if not ready for cmd, wait and try again */
656 t8254_wait(t8254_us2ticks(100));
658 outp(cx->mpuio+SNDSB_MPUIO_DATA,d);
661 } while (--patience != 0);
665 int sndsb_mpu_read(struct sndsb_ctx *cx) {
666 unsigned int patience = 100;
669 if (inp(cx->mpuio+SNDSB_MPUIO_STATUS) & 0x80) /* if data ready not ready, wait and try again */
670 t8254_wait(t8254_us2ticks(100));
672 return inp(cx->mpuio+SNDSB_MPUIO_DATA);
674 } while (--patience != 0);
679 /* this code makes sure the MPU exists */
680 int sndsb_probe_mpu401(struct sndsb_ctx *cx) {
681 unsigned int patience = 10;
684 if (cx->mpuio == 0) return 0;
686 /* check the command register. note however that if neither data is available
687 * or a command can be written this can return 0xFF */
688 if (inp(cx->mpuio+SNDSB_MPUIO_STATUS) == 0xFF) {
689 /* hm, perhaps it's stuck returning data? */
690 do { /* wait for it to signal no data and/or ability to write command */
691 inp(cx->mpuio+SNDSB_MPUIO_DATA);
692 if (inp(cx->mpuio+SNDSB_MPUIO_STATUS) != 0xFF)
695 if (--patience == 0) return 0;
696 t8254_wait(t8254_us2ticks(100)); /* 100us */
702 /* OK we got the status register to return something other than 0xFF.
704 if (sndsb_mpu_command(cx,0xFF)) {
705 if ((c=sndsb_mpu_read(cx)) == 0xFE) {
713 t8254_wait(t8254_us2ticks(10)); /* 10us */
719 int sndsb_write_dsp(struct sndsb_ctx *cx,uint8_t d) {
720 unsigned int patience = 25000;
722 DEBUG(fprintf(stdout,"sndsb_write_dsp(0x%02X)\n",d));
724 if (inp(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0)) & 0x80)
725 t8254_wait(t8254_us2ticks(10));
727 outp(cx->baseio+SNDSB_BIO_DSP_WRITE_DATA+(cx->dsp_alias_port?1:0),d);
730 } while (--patience != 0);
731 DEBUG(fprintf(stdout,"sndsb_write_dsp() timeout\n"));
735 int sndsb_write_dsp_timeout(struct sndsb_ctx *cx,uint8_t d,unsigned long timeout_ms) {
736 unsigned int patience = (unsigned int)(timeout_ms / 10UL);
738 DEBUG(fprintf(stdout,"sndsb_write_dsp(0x%02X)\n",d));
740 if (inp(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0)) & 0x80)
741 t8254_wait(t8254_us2ticks(10));
743 outp(cx->baseio+SNDSB_BIO_DSP_WRITE_DATA+(cx->dsp_alias_port?1:0),d);
746 } while (--patience != 0);
747 DEBUG(fprintf(stdout,"sndsb_write_dsp() timeout\n"));
751 int sndsb_write_dsp_timeconst(struct sndsb_ctx *cx,uint8_t tc) {
752 if (!sndsb_write_dsp(cx,0x40))
754 if (!sndsb_write_dsp(cx,tc))
759 int sndsb_query_dsp_version(struct sndsb_ctx *cx) {
762 if (!sndsb_write_dsp(cx,SNDSB_DSPCMD_GET_VERSION))
765 if ((a=sndsb_read_dsp(cx)) < 0)
767 if ((b=sndsb_read_dsp(cx)) < 0)
769 if (a == 0xFF || b == 0xFF)
772 cx->dsp_vmaj = (uint8_t)a;
773 cx->dsp_vmin = (uint8_t)b;
774 DEBUG(fprintf(stdout,"sndsb_query_dsp_version() == v%u.%u\n",a,b));
778 /* NTS: We do not test IRQ and DMA channels here */
779 /* NTS: The caller may have set irq == -1, dma8 == -1, or dma16 == -1, such as
780 * when probing. If any of them are -1, and this code knows how to deduce
781 * it directly from the hardware, then they will be updated */
782 int sndsb_init_card(struct sndsb_ctx *cx) {
783 /* some of our detection relies on knowing what OS we're running under */
788 #if TARGET_MSDOS == 32
789 cx->goldplay_dma = NULL;
793 cx->dsp_nag_mode = 0;
794 cx->ess_extensions = 0;
795 cx->dsp_nag_hispeed = 0;
796 cx->ess_extended_mode = 0;
797 cx->hispeed_matters = 1; /* assume it does */
798 cx->dosbox_emulation = 0;
799 cx->hispeed_blocking = 1; /* assume it does */
800 cx->timer_tick_signal = 0;
801 cx->timer_tick_func = NULL;
802 cx->poll_ack_when_no_irq = 1;
803 cx->virtualbox_emulation = 0;
804 cx->reason_not_supported = NULL;
805 cx->dsp_alias_port = sndsb_probe_options.use_dsp_alias;
806 cx->dsp_direct_dac_poll_retry_timeout = 16; /* assume at least 16 I/O reads to wait for DSP ready */
807 cx->dsp_direct_dac_read_after_command = 0;
808 cx->windows_creative_sb16_drivers_ver = 0;
809 cx->windows_creative_sb16_drivers = 0;
810 cx->dsp_4xx_fifo_single_cycle = 0;
811 cx->windows_9x_me_sbemul_sys = 0;
812 cx->audio_data_flipped_sign = 0;
813 cx->dsp_4xx_fifo_autoinit = 1;
814 cx->dsp_autoinit_command = 1;
815 cx->buffer_irq_interval = 0;
816 cx->windows_springwait = 0;
817 cx->chose_autoinit_dma = 0;
818 cx->chose_autoinit_dsp = 0;
819 cx->do_not_probe_irq = 0;
820 cx->do_not_probe_dma = 0;
821 cx->is_gallant_sc6600 = 0;
822 cx->windows_emulation = 0;
823 cx->windows_xp_ntvdm = 0;
824 cx->dsp_copyright[0] = 0;
825 cx->dsp_autoinit_dma = 1;
826 cx->buffer_last_io = 0;
827 cx->direct_dsp_io = 0;
828 cx->goldplay_mode = 0;
829 cx->force_hispeed = 0;
830 cx->chose_use_dma = 0;
840 cx->buffer_lin = NULL;
841 cx->buffer_rate = 22050;
842 cx->enable_adpcm_autoinit = 0;
845 cx->sb_mixer_items = 0;
847 cx->max_sample_rate_sb_play_dac = 23000;
848 cx->max_sample_rate_sb_rec_dac = 13000;
850 if (!sndsb_reset_dsp(cx)) return 0;
853 /* hm, what version are you? */
854 if (!sndsb_query_dsp_version(cx)) {
855 /* hm? failed the DSP version command?
856 * are you OK? test by sending "disable speaker" */
857 if (!sndsb_write_dsp(cx,0xD1))
861 /* FIX: Apparently when SBOS unloads it leaves behind the I/O
862 port stuck returning 0xAA, which can trick most SB
863 compatible DOS programs into thinking the DSP is still
864 there. But if we read back the DSP version as 0xAA 0xAA
865 then we know it's just SBOS not cleaning up after itself */
866 if (cx->dsp_vmaj == 0xAA && cx->dsp_vmin == 0xAA)
867 return 0; /* That's not a Sound Blaster! */
869 /* FIX: Gravis Ultrasound MEGA-EM emulates a VERY LIMITED SUBSET
870 of the Sound Blaster. Worse, it hangs the machine with an
871 error message when you use any command it doesn't know!
873 MEGA-EM usually reports itself as v1.3, but you can also
874 use EMUSET -X2 to enable a rudimentary sort of DSP v2.1
875 emulation. True SB hardware doesn't carry a DSP copyright
876 string until v3.0, so it's probable we wouldn't get anything
877 anyway. The DSP copyright string command is not recognized
879 if (cx->dsp_vmaj <= 2) {
880 if (gravis_mega_em_detect(&megaem_info)) { /* is that you, MEGA-EM? */
881 /* FIXME: Is there some sort of hack we can use
882 to determine what I/O port MEGA-EM is
883 watching? I would like this code to
884 not self-limit it's capabilities to
885 ALL interfaces just because one happens
886 to be a GUS with MEGA-EM. */
888 cx->dsp_autoinit_dma = 0;
889 strcpy(cx->dsp_copyright,"Gravis MEGA-EM");
893 /* if the DSP is recent enough, it might have a copyright string.
895 DSPs prior to the Sound Blaster Pro don't really seem to return
896 anything in response to DSP command 0xE3, in fact it might be that
897 Creative added it with the SB16 (DSP v4.x). However I also know
898 from programming experience that many SB clones DO return a string
899 and report themselves with varying version numbers like v3.1, v2.5,
901 if (!cx->mega_em && cx->dsp_vmaj >= 2) {
904 sndsb_write_dsp(cx,0xE3);
905 for (i=0;i < (sizeof(cx->dsp_copyright)-1);i++) {
906 c = sndsb_read_dsp(cx);
908 cx->dsp_copyright[i] = (char)c;
911 cx->dsp_copyright[i] = (char)0;
912 DEBUG(fprintf(stdout,"sndsb_init_card() copyright == '%s'\n",cx->dsp_copyright));
914 /* check for whacked-out DSP "strings" like a continuous
915 sequence of 0x01 bytes. it might be Gravis SBOS, which
916 also reports itself as DSP v2.1 */
917 if (cx->dsp_vmaj <= 2 && i >= (sizeof(cx->dsp_copyright)-1)) {
918 for (i=0,c=0;i < (sizeof(cx->dsp_copyright)-1);i++) {
919 if (cx->dsp_copyright[i] == 1)
926 if (gravis_sbos_detect() >= 0) { /* is that you, SBOS? */
927 strcpy(cx->dsp_copyright,"Gravis SBOS");
928 cx->dsp_autoinit_dma = 0;
935 if (sndsb_probe_mixer(cx)) /* NTS: Don't reset the mixer, just probe it */
938 /* Sound Blaster 16 (DSP 4.xx): we read the mixer registers, unless this card was initialized from a PnP device */
939 /* Earlier cards: we have to probe around for it */
940 if (cx->dsp_vmaj == 4 && !sndsb_probe_options.disable_sb16_read_config_byte && cx->pnp_id == 0) {
941 unsigned char irqm = sndsb_read_mixer(cx,0x80);
942 unsigned char dmam = sndsb_read_mixer(cx,0x81);
943 if (cx->irq < 0 && irqm != 0xFF && irqm != 0x00) {
944 if (irqm & 8) cx->irq = 10;
945 else if (irqm & 4) cx->irq = 7;
946 else if (irqm & 2) cx->irq = 5;
947 else if (irqm & 1) cx->irq = 2;
949 cx->do_not_probe_irq = 1;
951 if (dmam != 0xFF && dmam != 0x00) {
953 if (dmam & 8) cx->dma8 = 3;
954 else if (dmam & 2) cx->dma8 = 1;
955 else if (dmam & 1) cx->dma8 = 0;
959 if (dmam & 0x80) cx->dma16 = 7;
960 else if (dmam & 0x40) cx->dma16 = 6;
961 else if (dmam & 0x20) cx->dma16 = 5;
964 /* NTS: From the Creative programming guide:
965 * "DSP version 4.xx also supports the transfer of 16-bit sound data through
966 * 8-bit DMA channel. To make this possible, set all 16-bit DMA channel bits
967 * to 0 leaving only 8-bit DMA channel set" */
969 cx->dma16 = cx->dma8;
971 cx->do_not_probe_dma = 1;
975 /* Reveal SC400 SB16 clone: I have this card and I can tell
976 * from programming experience that while it reports itself
977 * as DSP v3.5 (Sound Blaster Pro) it actually has a SB16
978 * type mixer and supports most (but not all) of the SB16
979 * type DSP commands. It lacks however the configuration
980 * registers in the mixer for DMA and IRQ settings, on
981 * this card you use secret undocumented DSP commands.
982 * The card also has a "Windows Sound System" interface
983 * at 0x530, which is not relevent here since we focus on
984 * the Sound Blaster part.
986 * It also has a amusing hardware bug where I can set the
987 * DSP up as if doing a DMA transfer, and then my code can
988 * fake the DMA transfer by writing to the DSP command
989 * port, something I took advantage of prior to figuring out
990 * the DMA controller back in the day */
991 if (!strcmp(cx->dsp_copyright,"SC-6000")) {
992 if (sndsb_write_dsp(cx,0x58)) {
994 a = (unsigned char)sndsb_read_dsp(cx);
995 if (a == 0xAA) a = (unsigned char)sndsb_read_dsp(cx);
996 /* observation: if the card is jumpered to 220h, the first byte is 0x2E, second is 0xC5.
997 if the card is jumpered to 240h, the first byte is 0x2F, second is 0xC3.
998 is that really what bit 0 indicates? */
999 if ((a&0xFE) == 0x2E) {
1000 cx->is_gallant_sc6600 = 1;
1001 b = (unsigned char)sndsb_read_dsp(cx);
1002 c = (unsigned char)sndsb_read_dsp(cx);
1003 if (b != 0 && c != 0) {
1004 /* SC400: Experience says the card always works over
1005 * the 8-bit DMA even for 16-bit PCM audio */
1007 cx->dma8 = gallant_sc6600_map_to_dma[c&3];
1009 cx->dma16 = cx->dma8;
1011 cx->irq = gallant_sc6600_map_to_irq[(c>>3)&7];
1013 cx->do_not_probe_irq = 1;
1014 cx->do_not_probe_dma = 1;
1020 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
1021 /* trimmed to keep total code <= 64KB */
1023 if (windows_mode == WINDOWS_NT) {
1024 /* Windows NT would never let a DOS program like us talk directly to hardware,
1025 * so if we see a Sound Blaster like device it's very likely an emulation driver.
1026 * Working correctly then requires us to deduce what emulation driver we're running under. */
1028 /* No copyright string and DSP v2.1: Microsoft Windows XP/Vista/7 native NTVDM.EXE SB emulation */
1029 if (cx->dsp_copyright[0] == 0 && cx->dsp_vmaj == 2 && cx->dsp_vmin == 1) {
1030 cx->windows_xp_ntvdm = 1;
1031 cx->windows_emulation = 1;
1032 strcpy(cx->dsp_copyright,"Microsoft Windows XP/Vista/7 NTVDM.EXE SB emulation");
1034 /* anything else: probably VDMSOUND.EXE, which provides good enough emulation we don't need workarounds */
1035 /* TODO: Is there anything we can do to detect with certainty that it's VDMSOUND.EXE? */
1037 /* NTS: VDMSOUND.EXE emulates everything down to the copyright string, so append to the string instead of replacing */
1038 char *x = cx->dsp_copyright+strlen(cx->dsp_copyright);
1039 char *f = cx->dsp_copyright+sizeof(cx->dsp_copyright)-1;
1040 const char *add = " [VDMSOUND]";
1043 cx->windows_emulation = 1;
1044 if (x != cx->dsp_copyright) {
1045 while (x < f && *add) *x++ = *add++;
1049 strcpy(cx->dsp_copyright,"VDMSOUND");
1053 else if (windows_mode == WINDOWS_ENHANCED) { /* Windows 9x/ME Sound Blaster */
1054 struct w9x_vmm_DDB_scan vxdscan;
1055 unsigned char vxdscanned = 0;
1057 /* Two possibilities from experience:
1058 * a) We can see and talk to the Sound Blaster because the driver
1059 * implements a "pass through" virtualization like mode. Meaning,
1060 * if we start talking to the Sound Blaster the driver catches it
1061 * and treats it as yet another process opening the sound card.
1062 * Meaning that, as long as we have the sound card playing audio,
1063 * other Windows applications cannot open it, and if other Windows
1064 * applications have it open, we cannot initialize the card.
1066 * That scenario is typical of:
1068 * - Microsoft Windows 95 with Microsoft stock Sound Blaster 16 drivers
1070 * That scenario brings up an interesting problem as well: Since
1071 * it literally "passes through" the I/O, we see the card for what
1072 * it is. So we can't check for inconsistencies in I/O like we can
1073 * with most emulations. If knowing about this matters enough, we
1074 * have to know how to poke around inside the Windows kernel and
1075 * autodetect which drivers are resident.
1077 * b) The Sound Blaster is virtual. In the most common case with
1078 * Windows 9x, it likely means there's a PCI-based sound card
1079 * installed with kernel-level emulation enabled. What we are able
1080 * to do depends on what the driver offers us.
1082 * That scenario is typical of:
1084 * Microsoft Windows 98/ME with PCI-based sound hardware. In
1085 * one test scenario of mine, it was a Sound Blaster Live!
1086 * value card and Creative "Sound Blaster 16 emulation" drivers.
1088 * Microsoft Windows ME, through SBEMUL.SYS, which uses the
1089 * systemwide default sound driver to completely virtualize
1090 * the sound card. On one virtual machine, Windows ME uses the
1091 * AC'97 codec driver to emulate a Sound Blaster Pro.
1093 * Since emulation can vary greatly, detecting the emulator through
1094 * I/O inconsistencies is unlikely to work, again, if it matters we
1095 * need a way to poke into the Windows kernel and look at which drivers
1098 * c) The Sound Blaster is actual hardware, and Windows is not blocking
1099 * or virtualizing any I/O ports.
1101 * I know you're probably saying to yourself: Ick! But under Windows 95
1102 * such scenarios are possible: if there is a SB16 compatible sound
1103 * card out there and no drivers are installed to talk to it, Windows
1104 * 95 itself will not talk to the card, but will allow DOS programs
1105 * to do so. Amazingly, it will still virtualize the DMA controller
1106 * in a manner that allows everything to work!
1108 * Whatever you do in this scenario: Don't let multiple DOS boxes talk
1109 * to the same Sound Blaster card!!!
1111 * So unlike the Windows NT case, we can't assume emulators or capabilities
1112 * because it varies greatly depending on the host configuration. But we
1113 * can try our best and at least try to avoid things that might trip up
1115 cx->windows_emulation = 1; /* NTS: The "pass thru" scenario counts as emulation */
1117 if (!sndsb_probe_options.disable_windows_vxd_checks && w9x_vmm_first_vxd(&vxdscan)) {
1120 /* If SBEMUL.SYS is present, then it's definitely Windows 98/ME SBEMUL.SYS */
1121 if (!memcmp(vxdscan.ddb.name,"SBEMUL ",8)) {
1122 cx->windows_9x_me_sbemul_sys = 1;
1124 /* If a Sound Blaster 16 is present, usually Windows 9x/ME will install the
1125 * stock Creative drivers shipped on the CD-ROM */
1126 else if (!memcmp(vxdscan.ddb.name,"VSB16 ",8)) {
1127 cx->windows_creative_sb16_drivers = 1;
1128 cx->windows_creative_sb16_drivers_ver = ((uint16_t)vxdscan.ddb.Mver << 8U) | ((uint16_t)vxdscan.ddb.minorver);
1130 } while (w9x_vmm_next_vxd(&vxdscan));
1131 w9x_vmm_last_vxd(&vxdscan);
1134 /* DSP v3.2, no copyright string, and (no VxD scan OR SBEMUL.SYS is visible)
1135 * Might be Microsoft Windows 98/ME SBEMUL.SYS */
1136 if ((!vxdscanned || cx->windows_9x_me_sbemul_sys) && cx->dsp_vmaj == 3 && cx->dsp_vmin == 2 && cx->dsp_copyright[0] == 0) {
1137 /* No hacks required, the emulation is actually quite reasonable, though as usual
1138 * using extremely short block sizes will cause stuttering. The only recognition
1139 * necessary is that SBEMUL.SYS does not support the ADPCM modes. Applies to Windows 98
1140 * and Windows ME. */
1141 strcpy(cx->dsp_copyright,"Microsoft Windows 98/ME SBEMUL.SYS");
1143 /* Sound Blaster 16 DSP, and VSB16 (SB16.VXD) is visible.
1144 * Might be Creative's Sound Blaster 16 drivers. */
1145 else if (cx->windows_creative_sb16_drivers && cx->dsp_vmaj == 4 && !strcmp(cx->dsp_copyright,"COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.")) {
1146 sprintf(cx->dsp_copyright,"Creative Sound Blaster 16 driver for Win 3.1/9x/ME v%u.%u",
1147 cx->windows_creative_sb16_drivers_ver>>8,
1148 cx->windows_creative_sb16_drivers_ver&0xFF);
1152 /* add our commentary for other emulation environments we can detect */
1153 if (!cx->windows_emulation && detect_dosbox_emu()) {
1154 /* add commentary if we know we're running under the DOSBox emulator.
1155 * Nothing special, DOSBox does a damn good job at it's emulation so
1156 * no workarounds are required. */
1157 char *x = cx->dsp_copyright+strlen(cx->dsp_copyright);
1158 char *f = cx->dsp_copyright+sizeof(cx->dsp_copyright)-1;
1159 const char *add = " [DOSBox]";
1161 cx->dosbox_emulation = 1;
1162 if (x != cx->dsp_copyright) {
1163 while (x < f && *add) *x++ = *add++;
1167 strcpy(cx->dsp_copyright,"DOSBox emulator");
1171 if (!cx->windows_emulation && detect_virtualbox_emu())
1172 cx->virtualbox_emulation = 1;
1174 /* DSP v3.1 and no copyright string means it might be an ESS 688/1869 chipset */
1175 /* FIXME: A freak accident during development shows me it's possible to change the DSP version to v2.1 */
1176 if (!cx->windows_emulation && !cx->is_gallant_sc6600 && cx->dsp_vmaj == 3 && cx->dsp_vmin == 1 &&
1177 cx->dsp_copyright[0] == 0 && !sndsb_probe_options.disable_ess_extensions) {
1178 /* Use DSP command 0xE7 to detect ESS chipset */
1179 if (sndsb_write_dsp(cx,0xE7)) {
1180 unsigned char c1,c2;
1183 c1 = sndsb_read_dsp(cx);
1184 c2 = sndsb_read_dsp(cx);
1185 if (c1 == 0x68 && (c2 & 0xF0) == 0x80) { /* ESS responds 0x68 0x8x where x = version code */
1188 cx->ess_chipset = (c2 & 8) ? SNDSB_ESS_1869 : SNDSB_ESS_688;
1190 if (cx->ess_chipset == SNDSB_ESS_688) { /* ESS 688? I know how to program that! */
1191 cx->ess_extensions = 1;
1193 /* that also means that we can deduce the true IRQ/DMA from the chipset */
1194 if ((in=sndsb_ess_read_controller(cx,0xB1)) != -1) { /* 0xB1 Legacy Audio Interrupt Control */
1205 case 0x0: /* "2,9,all others" */
1212 if ((in=sndsb_ess_read_controller(cx,0xB2)) != -1) { /* 0xB2 DRQ Control */
1215 cx->dma8 = cx->dma16 = -1;
1218 cx->dma8 = cx->dma16 = 0;
1221 cx->dma8 = cx->dma16 = 1;
1224 cx->dma8 = cx->dma16 = 3;
1227 if (cx->dma8 >= 0 && cx->dma16 < 0)
1228 cx->dma16 = cx->dma8;
1229 if (cx->dma16 >= 0 && cx->dma8 < 0)
1230 cx->dma8 = cx->dma16;
1235 else if (cx->ess_chipset == SNDSB_ESS_1869) { /* ESS 1869? I know how to program that! */
1236 cx->ess_extensions = 1;
1238 /* NTS: The ESS 1869 and later have PnP methods to configure themselves, and the
1239 * registers are documented as readonly for that reason, AND, on the ESS 1887 in
1240 * the Compaq system I test, the 4-bit value that supposedly corresponds to IRQ
1241 * doesn't seem to do anything. */
1243 /* The ESS 1869 (on the Compaq) appears to use the same 8-bit DMA for 16-bit as well.
1244 * Perhaps the second DMA channel listed by the BIOS is the second channel (for full
1246 if (cx->dma8 >= 0 && cx->dma16 < 0)
1247 cx->dma16 = cx->dma8;
1248 if (cx->dma16 >= 0 && cx->dma8 < 0)
1249 cx->dma8 = cx->dma16;
1252 /* TODO: 1869 datasheet recommends reading mixer index 0x40
1253 * four times to read back 0x18 0x69 A[11:8] A[7:0]
1254 * where A is the base address of the configuration
1255 * device. I don't have an ESS 1869 on hand to test
1256 * and dev that. Sorry. --J.C. */
1263 if (cx->ess_chipset != 0 && cx->dsp_copyright[0] == 0) {
1264 const char *s = sndsb_ess_chipset_str(cx->ess_chipset);
1265 if (s != NULL) strcpy(cx->dsp_copyright,s);
1268 /* check DMA against the DMA controller presence.
1269 * If there is no 16-bit DMA (channels 4-7) then we cannot use
1271 if (!(d8237_flags&D8237_DMA_SECONDARY)) {
1272 if (cx->dma16 >= 4) cx->dma16 = -1;
1273 if (cx->dma8 >= 4) cx->dma8 = -1;
1275 if (!(d8237_flags&D8237_DMA_PRIMARY)) {
1276 if (cx->dma16 >= 0 && cx->dma16 < 4) cx->dma16 = -1;
1277 if (cx->dma8 >= 0 && cx->dma8 < 4) cx->dma8 = -1;
1280 if (cx->mpuio == 0) { /* uh oh, we have to probe for it */
1281 if (sndsb_by_mpu(0x330) == NULL) {
1282 cx->mpuio = 0x330; /* more common */
1283 if (sndsb_probe_mpu401(cx))
1286 if (sndsb_by_mpu(0x300) == NULL) {
1287 cx->mpuio = 0x300; /* less common */
1288 if (sndsb_probe_mpu401(cx))
1298 if (sndsb_probe_mpu401(cx))
1302 if (cx->dsp_vmaj >= 4) {
1303 /* Highspeed DSP commands don't matter anymore, they're just an alias to older commands */
1304 cx->hispeed_matters = 0;
1305 cx->hispeed_blocking = 0;
1306 /* The DSP is responsive even during hispeed mode, you can nag it then just fine */
1307 cx->dsp_nag_hispeed = 1;
1308 /* FIXME: At exactly what DSP version did SB16 allow going up to 48KHz?
1309 * I'm going by the ViBRA test card I own having DSP 4.13 vs DOSBox sbtype=sb16
1310 * reporting DSP v4.5 */
1311 if (cx->dsp_vmaj == 4 && cx->dsp_vmin > 5)
1312 cx->max_sample_rate_dsp4xx = 48000;
1314 cx->max_sample_rate_dsp4xx = 44100;
1316 cx->enable_adpcm_autoinit = 1; /* NTS: Unless there are DSP 4.xx SB clones out there that don't, we can assume auto-init ADPCM */
1317 cx->max_sample_rate_sb_hispeed_rec = cx->max_sample_rate_dsp4xx;
1318 cx->max_sample_rate_sb_hispeed = cx->max_sample_rate_dsp4xx;
1319 cx->max_sample_rate_sb_play = cx->max_sample_rate_dsp4xx;
1320 cx->max_sample_rate_sb_rec = cx->max_sample_rate_dsp4xx;
1321 if (cx->max_sample_rate_dsp4xx > 44100) { /* SB16 ViBRA cards apparently allow Direct DAC output up to 24KHz instead of 23KHz */
1322 cx->max_sample_rate_sb_play_dac = 24000;
1323 /* TODO: Is recording speed affected? */
1326 else if (cx->dsp_vmaj == 3) {
1327 if (cx->ess_chipset != 0) { /* ESS 688/1869 */
1328 /* NTS: The ESS 688 (Sharp laptop) and ESS 1869 (Compaq desktop) I test against seems quite capable
1329 * of playing back at 48KHz, in fact it will happily go beyond 48KHz up to 64KHz in my tests
1330 * barring ISA bus limitations (16-bit stereo at 54KHz audibly "warbles" for example). For
1331 * for consistentcy's sake, we'll just go ahead and say the chip goes up to 48KHz */
1332 cx->dsp_direct_dac_poll_retry_timeout = 4; /* DSP is responsive to direct DAC to allow lesser timeout */
1333 cx->max_sample_rate_dsp4xx = 48000;
1334 cx->max_sample_rate_sb_hispeed_rec = 48000;
1335 cx->max_sample_rate_sb_hispeed = 48000;
1336 cx->max_sample_rate_sb_play = 48000;
1337 cx->max_sample_rate_sb_rec = 48000;
1338 cx->enable_adpcm_autoinit = 0; /* does NOT support auto-init ADPCM */
1339 /* also: hi-speed DSP is blocking, and it matters: to go above 23KHz you have to use hi-speed DSP commands */
1341 else if (cx->is_gallant_sc6600) { /* SC-6600 clone card */
1342 cx->dsp_direct_dac_poll_retry_timeout = 4; /* DSP is responsive to direct DAC to allow lesser timeout */
1343 /* NTS: Officially, the max sample rate is 24000Hz, but the DSP seems to allow up to 25000Hz,
1344 * then limit the sample rate to that up until about 35000Hz where it suddenly clamps
1345 * the rate down to 24000Hz. Mildly strange bug. */
1346 cx->max_sample_rate_dsp4xx = 44100;
1347 cx->max_sample_rate_sb_hispeed_rec = 44100; /* playback and recording rate (it's halved to 22050Hz for stereo) */
1348 cx->max_sample_rate_sb_hispeed = 44100; /* playback and recording rate (it's halved to 22050Hz for stereo) */
1349 cx->max_sample_rate_sb_play = 25000; /* non-hispeed mode (and it's halved to 11500Hz for stereo) */
1350 cx->max_sample_rate_sb_rec = 25000; /* non-hispeed mode (and it's halved to 11500Hz for stereo) */
1351 cx->enable_adpcm_autoinit = 0; /* does NOT support auto-init ADPCM */
1352 /* also: hi-speed DSP is blocking, and it matters: to go above 23KHz you have to use hi-speed DSP commands */
1354 else { /* Sound Blaster Pro */
1355 cx->max_sample_rate_dsp4xx = 0;
1356 cx->max_sample_rate_sb_hispeed_rec = 44100; /* playback and recording rate (it's halved to 22050Hz for stereo) */
1357 cx->max_sample_rate_sb_hispeed = 44100; /* playback and recording rate (it's halved to 22050Hz for stereo) */
1358 cx->max_sample_rate_sb_play = 23000; /* non-hispeed mode (and it's halved to 11500Hz for stereo) */
1359 cx->max_sample_rate_sb_rec = 23000; /* non-hispeed mode (and it's halved to 11500Hz for stereo) */
1362 else if (cx->dsp_vmaj == 2) {
1363 if (cx->dsp_vmin >= 1) { /* Sound Blaster 2.01 */
1364 cx->max_sample_rate_dsp4xx = 0;
1365 cx->max_sample_rate_sb_hispeed_rec = 15000;
1366 cx->max_sample_rate_sb_rec = 13000;
1367 cx->max_sample_rate_sb_hispeed = 44100; /* NTS: On actual SB 2.1 hardware I own you can apparently go up to 46KHz? */
1368 cx->max_sample_rate_sb_play = 23000;
1370 else { /* Sound Blaster 2.0, without hispeed DSP commands */
1371 cx->max_sample_rate_dsp4xx = 0;
1372 cx->max_sample_rate_sb_hispeed_rec = cx->max_sample_rate_sb_rec = 13000;
1373 cx->max_sample_rate_sb_hispeed = cx->max_sample_rate_sb_play = 23000;
1376 else { /* Sound Blaster 1.x */
1377 cx->max_sample_rate_dsp4xx = 0;
1378 cx->max_sample_rate_sb_hispeed_rec = cx->max_sample_rate_sb_rec = 13000;
1379 cx->max_sample_rate_sb_hispeed = cx->max_sample_rate_sb_play = 23000;
1382 /* if any of our tests left the SB IRQ hanging, clear it now */
1384 sndsb_interrupt_ack(cx,3);
1385 sndsb_interrupt_ack(cx,3);
1388 /* DSP 2xx and earlier do not have auto-init commands */
1389 if (cx->dsp_vmaj < 2 || (cx->dsp_vmaj == 2 && cx->dsp_vmin == 0))
1390 cx->dsp_autoinit_command = 0;
1392 if (cx->dsp_autoinit_command)
1393 cx->dsp_nag_mode = 0;
1395 cx->dsp_nag_mode = 1;
1398 sndsb_determine_ideal_dsp_play_method(cx);
1403 int sndsb_determine_ideal_dsp_play_method(struct sndsb_ctx *cx) {
1404 if (cx->dma8 < 0) /* No IRQ, no DMA, fallback to direct */
1405 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_DIRECT;
1406 else if (cx->dsp_vmaj >= 4 || cx->is_gallant_sc6600)
1407 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_4xx;
1408 else if (cx->dsp_vmaj == 3)
1409 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_3xx;
1410 else if (cx->dsp_vmaj == 2 && cx->dsp_vmin >= 1) {
1411 /* Gravis SBOS does not do auto-init at all.
1412 Gravis MEGA-EM will fucking hang the computer and gripe
1413 about "unknown DSP command 1Ch" despite reporting itself
1414 as DSP v2.1 (EMUSET -X2). So don't do it! */
1415 if (cx->sbos || cx->mega_em)
1416 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_1xx;
1418 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_201;
1420 else if (cx->dsp_vmaj == 2)
1421 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_200;
1422 else if (cx->dsp_vmaj == 1)
1423 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_1xx;
1425 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_DIRECT;
1430 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
1432 static unsigned char sb_test_irq_number = 0;
1433 static volatile unsigned short int sb_test_irq_flag = 0;
1434 static void interrupt far sb_test_irq() {
1436 if (sb_test_irq_number >= 8) p8259_OCW2(8,P8259_OCW2_NON_SPECIFIC_EOI);
1437 p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
1441 /* alternative "lite" IRQ probing that hooks the interrupt and wait for an event.
1442 * Microsoft Windows friendly version that avoids 1) PIC commands to read back
1443 * events and 2) The undocumented DSP command 0xF2 that triggers an interrupt.
1445 * While the primary method in manual_probe_irq() works well in pure DOS and
1446 * some DOS boxes, this lite version works better in virtualized environments
1447 * like Windows NT/9x DOS boxes. */
1448 void sndsb_alt_lite_probe_irq(struct sndsb_ctx *cx) {
1449 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
1452 void (interrupt *old_irq)() = NULL;
1453 unsigned int round = 0,tolerance;
1454 unsigned char ml,mh,maybe;
1455 unsigned int patience = 0;
1456 unsigned short eliminated = 0U,possible;
1457 unsigned char tries[] = {5,7},tri;
1458 unsigned int testlen = 22050/20; /* 1/20th of a second */
1459 struct dma_8237_allocation *dma;
1460 const unsigned char timeconst = (unsigned char)((65536UL - (256000000UL / 22050UL)) >> 8UL);
1461 DEBUG(fprintf(stdout,"Sound blaster IRQ unknown, I'm going to have to probe for it [alt lite]\n"));
1463 /* for this test we initiate playback of short blocks. so we must ensure that this
1464 * card has a known DMA channel assignment. */
1465 if (cx->dma8 < 0) return;
1467 dma = dma_8237_alloc_buffer(testlen);
1468 if (dma == NULL) return;
1470 #if TARGET_MSDOS == 32
1471 memset(dma->lin,128,testlen);
1473 _fmemset(dma->lin,128,testlen);
1476 /* save the IRQ mask */
1478 ml = p8259_read_mask(0); /* IRQ0-7 */
1479 mh = p8259_read_mask(8); /* IRQ8-15 */
1487 /* go through the remaining ones, one at a time */
1488 for (tri=0;tri < sizeof(tries);tri++) {
1489 if (eliminated & (1U << tries[tri]))
1491 if (!sndsb_reset_dsp(cx)) {
1492 DEBUG(fprintf(stdout,"WARNING: DSP reset failed, aborting IRQ probe\n"));
1496 DEBUG(fprintf(stdout," Now testing IRQ %u\n",tries[tri]));
1498 /* clear SoundBlaster's previous interrupt */
1499 inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
1501 p8259_mask(tries[tri]);
1502 /* hook the interrupt, reset the flag, unmask the interrupt */
1503 sb_test_irq_flag = 0;
1504 sb_test_irq_number = tries[tri];
1505 old_irq = _dos_getvect(irq2int(tries[tri]));
1506 _dos_setvect(irq2int(tries[tri]),sb_test_irq);
1507 p8259_unmask(tries[tri]);
1509 /* wait for IRQ to show response (prior to triggering one) */
1515 if (sb_test_irq_flag) {
1517 /* VDMSOUND bugfix: a previous invocation of this program without playing sound
1518 * leaves the IRQ primed and ready to trigger the instant this code tests again,
1519 * leading to false "Caught IRQ prior to DSP command" situations. It's sort of
1520 * like the "stuck IRQ" situation and Gravis Ultrasound cards. */
1521 if (tri == 0 && tolerance == 0) {
1522 sb_test_irq_flag = 0;
1531 t8254_wait(t8254_us2ticks(1000));
1532 } while (--patience != 0);
1534 /* if the IRQ triggered between unmasking and NOW, then clearly it doesn't belong to the SB */
1535 if (sb_test_irq_flag) {
1536 eliminated |= 1U << tries[tri];
1537 DEBUG(fprintf(stdout,"Caught IRQ prior to DSP command, updating IRQ elimination: 0x%04x\n",eliminated));
1538 p8259_mask(tries[tri]);
1539 _dos_setvect(irq2int(tries[tri]),old_irq);
1543 /* make the SoundBlaster trigger an interrupt by playing a short sample block */
1544 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(cx->dma8) | D8237_MASK_SET); /* mask */
1545 outp(D8237_REG_W_WRITE_MODE,
1546 D8237_MODER_CHANNEL(cx->dma8) |
1547 D8237_MODER_TRANSFER(D8237_MODER_XFER_READ) |
1548 D8237_MODER_MODESEL(D8237_MODER_MODESEL_SINGLE));
1549 d8237_write_base(cx->dma8,dma->phys); /* RAM location with not much around */
1550 d8237_write_count(cx->dma8,testlen);
1551 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(cx->dma8)); /* unmask */
1554 if (!sndsb_write_dsp_timeconst(cx,timeconst) || !sndsb_write_dsp(cx,0x14) ||
1555 !sndsb_write_dsp(cx,testlen-1) || !sndsb_write_dsp(cx,(testlen-1)>>8)) {
1556 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(cx->dma8) | D8237_MASK_SET); /* unmask */
1557 p8259_mask(tries[tri]);
1558 _dos_setvect(irq2int(tries[tri]),old_irq);
1562 /* wait for IRQ to show response */
1567 if (sb_test_irq_flag) {
1568 DEBUG(fprintf(stdout,"Flag with %ums to go for IRQ %d\n",patience,tries[tri]));
1570 sb_test_irq_flag = 0; /* immediately clear it */
1574 t8254_wait(t8254_us2ticks(1000));
1575 } while (--patience != 0);
1576 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(cx->dma8) | D8237_MASK_SET); /* unmask */
1578 DEBUG(fprintf(stdout," maybe=%u\n",maybe));
1580 p8259_mask(tries[tri]);
1581 _dos_setvect(irq2int(tries[tri]),old_irq);
1585 if (!sndsb_reset_dsp(cx)) {
1586 DEBUG(fprintf(stdout,"WARNING: DSP reset failed, aborting IRQ probe\n"));
1587 p8259_mask(tries[tri]);
1588 _dos_setvect(irq2int(tries[tri]),old_irq);
1592 /* wait for IRQ to show response (prior to triggering one) */
1594 sb_test_irq_flag = 0;
1599 if (sb_test_irq_flag) break;
1600 t8254_wait(t8254_us2ticks(1000));
1601 } while (--patience != 0);
1603 /* if the IRQ triggered between unmasking and NOW, then clearly it doesn't belong to the SB */
1604 if (sb_test_irq_flag) {
1605 eliminated |= 1U << tries[tri];
1606 DEBUG(fprintf(stdout,"Caught IRQ prior to DSP command, updating IRQ elimination: 0x%04x\n",eliminated));
1607 p8259_mask(tries[tri]);
1608 _dos_setvect(irq2int(tries[tri]),old_irq);
1612 /* make the SoundBlaster trigger an interrupt by playing a short sample block */
1613 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(cx->dma8) | D8237_MASK_SET); /* mask */
1614 outp(D8237_REG_W_WRITE_MODE,
1615 D8237_MODER_CHANNEL(cx->dma8) |
1616 D8237_MODER_TRANSFER(D8237_MODER_XFER_READ) |
1617 D8237_MODER_MODESEL(D8237_MODER_MODESEL_SINGLE));
1618 d8237_write_base(cx->dma8,dma->phys); /* RAM location with not much around */
1619 d8237_write_count(cx->dma8,testlen);
1620 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(cx->dma8)); /* unmask */
1623 if (!sndsb_write_dsp_timeconst(cx,timeconst) || !sndsb_write_dsp(cx,0x14) ||
1624 !sndsb_write_dsp(cx,testlen-1) || !sndsb_write_dsp(cx,(testlen-1)>>8)) {
1625 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(cx->dma8) | D8237_MASK_SET); /* unmask */
1626 p8259_mask(tries[tri]);
1627 _dos_setvect(irq2int(tries[tri]),old_irq);
1631 /* wait for IRQ to show response */
1636 if (sb_test_irq_flag) {
1637 DEBUG(fprintf(stdout,"Flag with %ums to go on IRQ %d\n",patience,tries[tri]));
1639 sb_test_irq_flag = 0; /* immediately clear it */
1643 t8254_wait(t8254_us2ticks(1000));
1644 } while (--patience != 0);
1645 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(cx->dma8) | D8237_MASK_SET); /* unmask */
1647 DEBUG(fprintf(stdout," maybe2=%u\n",maybe));
1649 p8259_mask(tries[tri]);
1650 _dos_setvect(irq2int(tries[tri]),old_irq);
1654 if (!sndsb_reset_dsp(cx)) {
1655 DEBUG(fprintf(stdout,"WARNING: DSP reset failed, aborting IRQ probe\n"));
1656 p8259_mask(tries[tri]);
1657 _dos_setvect(irq2int(tries[tri]),old_irq);
1662 p8259_mask(tries[tri]);
1663 _dos_setvect(irq2int(tries[tri]),old_irq);
1665 possible |= 1U << tries[tri];
1666 DEBUG(fprintf(stdout,"Possible=0x%04X\n",possible));
1668 /* loop while we see possibilities, but more than one IRQ appears to be it */
1669 DEBUG(fprintf(stdout,"Round %u result: possible=0x%04x\n",possible));
1670 } while (possible != 0 && (possible&(possible-1)) != 0);
1672 if (possible != 0 && (possible&(possible-1)) == 0) {
1673 for (tri=0;tri < sizeof(tries);tri++) {
1674 if (possible & (1U << tries[tri])) {
1675 cx->irq = tries[tri];
1681 /* release DMA buffer */
1682 dma_8237_free_buffer(dma);
1684 /* restore interrupt mask */
1686 p8259_write_mask(0,ml);
1687 p8259_write_mask(8,mh);
1692 /* On Sound Blaster cards prior to the SB16 the only way to autodetect the IRQ
1693 * was to cause a SB IRQ and watch the interrupt controller to see which one
1694 * went off. that's what this function does. */
1695 /* NTS: This doesn't work in some situations:
1696 * - Windows XP native Sound Blaster emulation under NTVDM.EXE
1697 * Workaround: use the SBLASTER environment variable given by NTVDM.EXE itself
1698 * - Sun/Oracle VirtualBox SB16 emulation (short DSP blocks fail to trigger IRQ activity)
1699 * Workaround: read the SB16 compatible mixer byte to obtain configuration
1700 * - Microsoft Virtual PC SB16 emulation (short DSP blocks fail to trigger IRQ activity)
1701 * Workaround: read the SB16 compatible mixer byte to obtain configuration */
1702 void sndsb_manual_probe_irq(struct sndsb_ctx *cx) {
1703 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
1706 unsigned int round = 0;
1707 unsigned char ml,mh,maybe;
1708 unsigned int patience = 0;
1709 unsigned short eliminated = 0U,irr,possible;
1710 unsigned char tries[] = {2,3,5,7,10},tri;
1711 DEBUG(fprintf(stdout,"Sound blaster IRQ unknown, I'm going to have to probe for it\n"));
1714 ml = p8259_read_mask(0); /* IRQ0-7 */
1715 mh = p8259_read_mask(8); /* IRQ8-15 */
1716 p8259_write_mask(0,0xFF); /* mask off all interrupts */
1717 p8259_write_mask(8,0xFF);
1719 /* wait a bit. during the wait, mark off any interrupts
1720 * that happen while we're waiting because they're obviously
1721 * not coming from the Sound Blaster */
1724 t8254_wait(t8254_us2ticks(1000));
1725 irr = (unsigned short)p8259_read_IRR(0);
1726 irr |= (unsigned short)p8259_read_IRR(8) << 8U;
1727 for (tri=0;tri < sizeof(tries);tri++) {
1728 if (irr & (1U << tries[tri])) {
1729 eliminated |= 1U << tries[tri];
1732 } while (--patience != 0);
1733 DEBUG(fprintf(stdout,"Pre-test IRQ elimination: 0x%04X\n",eliminated));
1735 /* restore interrupt mask */
1736 p8259_write_mask(0,ml);
1737 p8259_write_mask(8,mh);
1745 /* go through the remaining ones, one at a time */
1747 for (tri=0;tri < sizeof(tries);tri++) {
1748 if (eliminated & (1U << tries[tri]))
1750 if (!sndsb_reset_dsp(cx)) {
1751 DEBUG(fprintf(stdout,"WARNING: DSP reset failed, aborting IRQ probe\n"));
1755 DEBUG(fprintf(stdout," Now testing IRQ %u\n",tries[tri]));
1757 /* clear SoundBlaster's previous interrupt */
1758 inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
1761 p8259_write_mask(0,0xFF); /* mask off all interrupts */
1762 p8259_write_mask(8,0xFF);
1764 /* did this IRQ already trigger? then the SB didn't do it */
1765 irr = (unsigned short)p8259_read_IRR(tries[tri]);
1766 if (irr & (1 << (tries[tri] & 7))) {
1767 eliminated |= 1U << tries[tri];
1768 DEBUG(fprintf(stdout,"Caught IRQ prior to DSP command, updating IRQ elimination: 0x%04x\n",eliminated));
1772 /* make the SoundBlaster trigger an interrupt */
1773 if (!sndsb_write_dsp(cx,0xF2)) {
1774 if (!sndsb_write_dsp(cx,0xF2)) {
1775 DEBUG(fprintf(stdout,"WARNING: DSP write failed, aborting IRQ probe\n"));
1780 /* wait for IRQ to show response */
1784 irr = (unsigned short)p8259_read_IRR(tries[tri]);
1785 if (irr & (1 << (tries[tri] & 7))) {
1789 t8254_wait(t8254_us2ticks(1000));
1790 } while (--patience != 0);
1792 DEBUG(fprintf(stdout," maybe=%u\n",maybe));
1796 /* restore interrupt mask */
1797 p8259_write_mask(0,ml);
1798 p8259_write_mask(8,mh);
1801 if (!sndsb_reset_dsp(cx)) {
1802 DEBUG(fprintf(stdout,"WARNING: DSP reset failed, aborting IRQ probe\n"));
1806 /* clear SoundBlaster's previous interrupt */
1807 inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
1810 p8259_write_mask(0,0xFF); /* mask off all interrupts */
1811 p8259_write_mask(8,0xFF);
1813 /* did this IRQ already trigger? then the SB didn't do it */
1814 irr = (unsigned short)p8259_read_IRR(tries[tri]);
1815 if (irr & (1 << (tries[tri] & 7))) {
1816 eliminated |= 1U << tries[tri];
1817 DEBUG(fprintf(stdout,"Caught IRQ prior to DSP command, updating IRQ elimination: 0x%04x\n",eliminated));
1821 /* make the SoundBlaster trigger an interrupt */
1822 if (!sndsb_write_dsp(cx,0xF2)) {
1823 if (!sndsb_write_dsp(cx,0xF2)) {
1824 DEBUG(fprintf(stdout,"WARNING: DSP write failed, aborting IRQ probe\n"));
1829 /* wait for IRQ to show response */
1833 irr = (unsigned short)p8259_read_IRR(tries[tri]);
1834 if (irr & (1 << (tries[tri] & 7))) {
1838 t8254_wait(t8254_us2ticks(1000));
1839 } while (--patience != 0);
1841 DEBUG(fprintf(stdout," maybe2=%u\n",maybe));
1845 possible |= 1U << tries[tri];
1847 /* loop while we see possibilities, but more than one IRQ appears to be it */
1848 DEBUG(fprintf(stdout,"Round %u result: possible=0x%04x\n",possible));
1849 } while (possible != 0 && (possible&(possible-1)) != 0);
1851 if (possible != 0 && (possible&(possible-1)) == 0) {
1852 for (tri=0;tri < sizeof(tries);tri++) {
1853 if (possible & (1U << tries[tri])) {
1854 cx->irq = tries[tri];
1860 /* restore interrupt mask */
1861 p8259_write_mask(0,ml);
1862 p8259_write_mask(8,mh);
1867 void sndsb_manual_probe_high_dma(struct sndsb_ctx *cx) {
1868 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
1871 /* NTS: Original code test-played 8192 bytes at 8KHz.
1872 * On every test machine, this meant a considerably long delay when probing.
1873 * To help speed it up, we now play a much shorter sample at 22KHz.
1874 * Unfortunately a sample playback block that short doesn't trigger an IRQ
1875 * under certain emulators like VirtualBox or Virtual PC. If we detect that we're
1876 * running under such emulators we then use a longer block size. */
1877 unsigned int testlen = 22050/20; /* 1/20th of a second */
1878 unsigned char tries[] = {5,6,7},tri;
1879 unsigned int srate = 22050;
1880 unsigned char dma_count_began = 0;
1881 unsigned char eliminated = 0;
1882 uint16_t prev[sizeof(tries)];
1883 unsigned int patience = 0,rem;
1884 struct dma_8237_allocation *dma;
1885 DEBUG(fprintf(stdout,"Sound blaster high DMA unknown, I'm going to have to probe for it\n"));
1887 if (windows_mode != WINDOWS_NT) {
1888 /* Sun/Oracle VirtualBox: Sound transfers that are too short are dropped without any
1889 * IRQ signal from the emulated SB16 card. Apparently this also has to do with a bug
1890 * in their DMA controller emulation where 'terminal count' is the original programmed
1891 * value rather than the 0xFFFF value most DMA controllers return. In other words,
1892 * we're compensating for VirtualBox's mediocre DMA emulation. */
1893 if (detect_virtualbox_emu()) {
1894 cx->virtualbox_emulation = 1;
1895 DEBUG(fprintf(stdout,"Setting test duration to longer period to work with VirtualBox\n"));
1900 /* sit back for a bit and watch the DMA channels. if any of them
1901 * are cycling, then they are active. NTS: Because the SB16 is
1902 * the only one using high DMA and it has a function to tell us
1903 * directly, we only probe the lower 8-bit channels */
1905 for (tri=0;tri < sizeof(tries);tri++) prev[tri] = d8237_read_count_lo16(tries[tri]);
1908 for (tri=0;tri < sizeof(tries);tri++) {
1909 if (eliminated & (1U << tries[tri]))
1911 if (prev[tri] != d8237_read_count_lo16(tries[tri]))
1912 eliminated |= 1U << tries[tri];
1914 } while (--patience != 0);
1915 DEBUG(fprintf(stdout,"Pre-test DMA elimination 0x%02x\n",eliminated));
1917 dma = dma_8237_alloc_buffer(testlen);
1919 #if TARGET_MSDOS == 32
1920 memset(dma->lin,0,testlen);
1922 _fmemset(dma->lin,0,testlen);
1925 for (tri=0;tri < sizeof(tries);tri++) {
1926 if (eliminated & (1U << tries[tri]))
1928 if (!sndsb_reset_dsp(cx))
1931 /* clear SoundBlaster's previous interrupt */
1932 /* note that some emulations of the card will fail to play the block
1933 * unless we clear the interrupt status. */
1934 inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
1935 inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS16);
1937 DEBUG(fprintf(stdout," Testing DMA channel %u\n",tries[tri]));
1939 /* set up the DMA channel */
1940 outp(d8237_ioport(tries[tri],D8237_REG_W_SINGLE_MASK),
1941 D8237_MASK_CHANNEL(tries[tri]) | D8237_MASK_SET); /* mask */
1942 outp(d8237_ioport(tries[tri],D8237_REG_W_WRITE_MODE),
1943 D8237_MODER_CHANNEL(tries[tri]) |
1944 D8237_MODER_TRANSFER(D8237_MODER_XFER_READ) |
1945 D8237_MODER_MODESEL(D8237_MODER_MODESEL_SINGLE));
1946 d8237_write_base(tries[tri],dma->phys); /* RAM location with not much around */
1947 d8237_write_count(tries[tri],testlen);
1948 outp(d8237_ioport(tries[tri],D8237_REG_W_SINGLE_MASK),
1949 D8237_MASK_CHANNEL(tries[tri])); /* unmask */
1952 if (!sndsb_write_dsp_outrate(cx,srate))
1955 /* play a short block */
1956 if (!sndsb_write_dsp(cx,0xB0|0x02)) continue; /* 16-bit single block FIFO on */
1957 if (!sndsb_write_dsp(cx,0x10)) continue; /* mono signed */
1958 if (!sndsb_write_dsp(cx,testlen)) continue;
1959 if (!sndsb_write_dsp(cx,testlen>>8)) continue;
1960 DEBUG(fprintf(stdout," DSP block started\n",tries[tri]));
1963 dma_count_began = 0;
1964 patience = (unsigned int)(((unsigned long)testlen * 1500UL) / (unsigned long)srate);
1966 rem = d8237_read_count(tries[tri]);
1967 if (rem <= 2 || rem >= 0xFFFF) break; /* if below 2 or at terminal count */
1969 /* explanation: it turns out some emulation software doesn't quite do the DMA
1970 * controllers correctly: on terminal count their counter register reverts to
1971 * the value we originally set it to, rather than 0xFFFF. so to detect terminal
1972 * count we have to watch it count down, then return to 0xFFFF or to it's
1975 * This hack is necessary to detect DMA cycling under Sun/Oracle VirtualBox */
1976 if (dma_count_began) {
1977 if (rem == testlen) {
1978 DEBUG(fprintf(stdout,
1979 "DMA controller snafu: Terminal count appears to be the original\n"
1980 "counter value, not the 0xFFFF value returned by most controllers.\n"
1981 "Expect other DOS programs to choke on it too!\n"));
1988 dma_count_began = 1;
1991 t8254_wait(t8254_us2ticks(1000));
1992 } while (--patience != 0);
1993 if (rem >= 0xFFFF) rem = 0; /* the DMA counter might return 0xFFFF when terminal count reached */
1994 outp(d8237_ioport(tries[tri],D8237_REG_W_SINGLE_MASK),
1995 D8237_MASK_CHANNEL(tries[tri]) | D8237_MASK_SET); /* mask */
1996 sndsb_reset_dsp(cx);
1998 /* clear SoundBlaster's previous interrupt */
1999 inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
2000 inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS16);
2002 if ((unsigned int)(rem+1) < testlen) { /* it moved, this must be the right one */
2003 DEBUG(fprintf(stdout," This one changed, must be the right one\n"));
2004 cx->dma16 = tries[tri];
2009 dma_8237_free_buffer(dma);
2016 void sndsb_manual_probe_dma(struct sndsb_ctx *cx) {
2017 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
2020 /* NTS: Original code test-played 8192 bytes at 8KHz.
2021 * On every test machine, this meant a considerably long delay when probing.
2022 * To help speed it up, we now play a much shorter sample at 22KHz.
2023 * Unfortunately a sample playback block that short doesn't trigger an IRQ
2024 * under certain emulators like VirtualBox or Virtual PC. If we detect that we're
2025 * running under such emulators we then use a longer block size. */
2026 unsigned char timeconst = (unsigned char)((65536UL - (256000000UL / 22050UL)) >> 8UL);
2027 unsigned int testlen = 22050/20; /* 1/20th of a second */
2028 unsigned char tries[] = {0,1,3},tri;
2029 unsigned int srate = 22050;
2030 unsigned char dma_count_began = 0;
2031 unsigned char eliminated = 0;
2032 uint16_t prev[sizeof(tries)];
2033 unsigned int patience = 0,rem;
2034 struct dma_8237_allocation *dma;
2035 DEBUG(fprintf(stdout,"Sound blaster DMA unknown, I'm going to have to probe for it\n"));
2037 if (windows_mode != WINDOWS_NT) {
2038 /* Sun/Oracle VirtualBox: Sound transfers that are too short are dropped without any
2039 * IRQ signal from the emulated SB16 card. Apparently this also has to do with a bug
2040 * in their DMA controller emulation where 'terminal count' is the original programmed
2041 * value rather than the 0xFFFF value most DMA controllers return. In other words,
2042 * we're compensating for VirtualBox's mediocre DMA emulation. */
2043 if (detect_virtualbox_emu()) {
2044 cx->virtualbox_emulation = 1;
2045 DEBUG(fprintf(stdout,"Setting test duration to longer period to work with VirtualBox\n"));
2050 /* sit back for a bit and watch the DMA channels. if any of them
2051 * are cycling, then they are active. NTS: Because the SB16 is
2052 * the only one using high DMA and it has a function to tell us
2053 * directly, we only probe the lower 8-bit channels */
2055 for (tri=0;tri < sizeof(tries);tri++) prev[tri] = d8237_read_count_lo16(tries[tri]);
2058 for (tri=0;tri < sizeof(tries);tri++) {
2059 if (eliminated & (1U << tries[tri]))
2061 if (prev[tri] != d8237_read_count_lo16(tries[tri]))
2062 eliminated |= 1U << tries[tri];
2064 } while (--patience != 0);
2065 DEBUG(fprintf(stdout,"Pre-test DMA elimination 0x%02x\n",eliminated));
2067 dma = dma_8237_alloc_buffer(testlen);
2069 #if TARGET_MSDOS == 32
2070 memset(dma->lin,128,testlen);
2072 _fmemset(dma->lin,128,testlen);
2075 /* then, initiate short playback tests to figure out which one */
2077 * - Microsoft Virtual PC: works
2079 * - Sun/Oracle VirtualBox: works
2081 * Some emulators like VPC and VirtualBox are not concerned with
2082 * accurate emulation. Unfortunately for us this means any attempt
2083 * to play really short blocks would fail, because those emulators
2084 * would just drop the block and not fire the IRQ. */
2085 for (tri=0;tri < sizeof(tries);tri++) {
2086 if (eliminated & (1U << tries[tri]))
2088 if (!(d8237_flags&D8237_DMA_SECONDARY) && tries[tri] >= 4)
2090 if (!(d8237_flags&D8237_DMA_PRIMARY) && tries[tri] < 4)
2092 if (!sndsb_reset_dsp(cx))
2095 /* clear SoundBlaster's previous interrupt */
2096 /* note that some emulations of the card will fail to play the block
2097 * unless we clear the interrupt status. */
2098 inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
2100 DEBUG(fprintf(stdout," Testing DMA channel %u\n",tries[tri]));
2102 /* set up the DMA channel */
2103 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(tries[tri]) | D8237_MASK_SET); /* mask */
2104 outp(D8237_REG_W_WRITE_MODE,
2105 D8237_MODER_CHANNEL(tries[tri]) |
2106 D8237_MODER_TRANSFER(D8237_MODER_XFER_READ) |
2107 D8237_MODER_MODESEL(D8237_MODER_MODESEL_SINGLE));
2108 d8237_write_base(tries[tri],dma->phys); /* RAM location with not much around */
2109 d8237_write_count(tries[tri],testlen);
2110 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(tries[tri])); /* unmask */
2113 if (!sndsb_write_dsp_timeconst(cx,timeconst))
2116 /* play a short block */
2117 if (!sndsb_write_dsp(cx,0x14)) continue;
2118 if (!sndsb_write_dsp(cx,testlen-1)) continue;
2119 if (!sndsb_write_dsp(cx,(testlen-1)>>8)) continue;
2120 DEBUG(fprintf(stdout," DSP block started\n",tries[tri]));
2123 dma_count_began = 0;
2124 patience = (unsigned int)(((unsigned long)testlen * 1500UL) / (unsigned long)srate);
2126 rem = d8237_read_count(tries[tri]);
2127 if (rem <= 2 || rem >= 0xFFFF) break; /* if below 2 or at terminal count */
2129 /* explanation: it turns out some emulation software doesn't quite do the DMA
2130 * controllers correctly: on terminal count their counter register reverts to
2131 * the value we originally set it to, rather than 0xFFFF. so to detect terminal
2132 * count we have to watch it count down, then return to 0xFFFF or to it's
2135 * This hack is necessary to detect DMA cycling under Sun/Oracle VirtualBox */
2136 if (dma_count_began) {
2137 if (rem == testlen) {
2138 DEBUG(fprintf(stdout,
2139 "DMA controller snafu: Terminal count appears to be the original\n"
2140 "counter value, not the 0xFFFF value returned by most controllers.\n"
2141 "Expect other DOS programs to choke on it too!\n"));
2148 dma_count_began = 1;
2151 t8254_wait(t8254_us2ticks(1000));
2152 } while (--patience != 0);
2153 if (rem >= 0xFFFF) rem = 0; /* the DMA counter might return 0xFFFF when terminal count reached */
2154 outp(D8237_REG_W_SINGLE_MASK,D8237_MASK_CHANNEL(tries[tri]) | D8237_MASK_SET); /* mask */
2155 sndsb_reset_dsp(cx);
2157 if ((unsigned int)(rem+1) < testlen) { /* it moved, this must be the right one */
2158 DEBUG(fprintf(stdout," This one changed, must be the right one\n"));
2159 cx->dma8 = tries[tri];
2164 dma_8237_free_buffer(dma);
2171 /* this is for taking a base address and probing the I/O ports there to see if something like a SB DSP is there. */
2172 /* it is STRONGLY recommended that you don't do this unless you try only 0x220 or 0x240 and you know that nothing
2173 * else important is there */
2174 int sndsb_try_base(uint16_t iobase) {
2175 struct sndsb_ctx *cx;
2177 if ((iobase&0xF) != 0)
2179 if (iobase < 0x210 || iobase > 0x270)
2181 if (sndsb_by_base(iobase) != NULL)
2184 /* some of our detection relies on knowing what OS we're running under */
2189 cx = sndsb_alloc_card();
2190 if (cx == NULL) return 0;
2192 DEBUG(fprintf(stdout,"sndsb_try_base(0x%03X)\n",iobase));
2194 cx->baseio = iobase;
2195 cx->dma8 = cx->dma16 = cx->irq = -1; /* NTS: zero HERE, the init card routine might figure them out */
2196 if (!sndsb_init_card(cx)) {
2197 DEBUG(fprintf(stdout,"failed to init card\n"));
2198 sndsb_free_card(cx);
2202 /* if we still have to figure out the IRQ, and it's not PnP then probe around to figure it out */
2203 if (cx->dsp_ok && !cx->is_gallant_sc6600 && !cx->do_not_probe_irq && cx->pnp_id == 0 && cx->irq == -1 &&
2204 windows_mode == WINDOWS_NONE && !sndsb_probe_options.disable_manual_irq_probing)
2205 sndsb_manual_probe_irq(cx);
2207 /* if we have to, detect the DMA channel. */
2208 if (cx->dsp_ok && !cx->is_gallant_sc6600 && !cx->do_not_probe_dma && cx->pnp_id == 0 && cx->dma8 == -1 &&
2209 !sndsb_probe_options.disable_manual_dma_probing)
2210 sndsb_manual_probe_dma(cx);
2211 /* and the high DMA channel too, if a SB16 or compatible. */
2212 if (cx->dsp_ok && !cx->is_gallant_sc6600 && !cx->do_not_probe_dma && cx->pnp_id == 0 && cx->dma16 == -1 &&
2213 cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_4xx && !sndsb_probe_options.disable_manual_high_dma_probing)
2214 sndsb_manual_probe_high_dma(cx);
2216 /* if we still have to figure out the IRQ, then probe around to figure it out */
2217 if (cx->dsp_ok && !cx->is_gallant_sc6600 && !cx->do_not_probe_irq && cx->pnp_id == 0 && cx->irq == -1 &&
2218 !sndsb_probe_options.disable_alt_irq_probing)
2219 sndsb_alt_lite_probe_irq(cx);
2221 /* If an ESS chipset, there's a good chance that 16-bit PCM is played over the 8-bit DMA channel */
2222 if (cx->ess_extensions && cx->dma16 < 0 && cx->dma8 >= 0)
2223 cx->dma16 = cx->dma8;
2225 sndsb_determine_ideal_dsp_play_method(cx);
2229 int sndsb_interrupt_reason(struct sndsb_ctx *cx) {
2230 if (cx->dsp_vmaj >= 4) {
2231 /* Sound Blaster 16: We can read a mixer byte to determine why the interrupt happened */
2232 /* bit 0: 1=8-bit DSP or MIDI */
2233 /* bit 1: 1=16-bit DSP */
2234 /* bit 2: 1=MPU-401 */
2235 return sndsb_read_mixer(cx,0x82) & 7;
2237 else if (cx->ess_extensions) {
2238 return cx->buffer_16bit ? 2 : 1;
2241 /* DSP 3.xx and earlier: just assume the interrupt happened because of the DSP */
2245 int sndsb_reset_mixer(struct sndsb_ctx *cx) {
2246 if (cx->baseio == 0)
2249 sndsb_write_mixer(cx,0x00,0x00); /* "write any 8-bit value to reset the chip" */
2253 /* general main loop idle function. does nothing, unless we're playing with no IRQ,
2254 * in which case we're expected to poll IRQ status */
2255 void sndsb_main_idle(struct sndsb_ctx *cx) {
2256 unsigned int oflags;
2258 oflags = get_cpu_flags();
2260 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && cx->timer_tick_signal) {
2261 /* DSP "nag" mode: when the host program's IRQ handler called our timer tick callback, we
2262 * noted it so that at idle() we can nag the DSP at moderate intervals. Note that nag mode
2263 * only makes sense when autoinit DMA is in use, otherwise we risk skipping popping and
2264 * crackling. We also don't nag if the DSP is doing auto-init playback, because it makes
2265 * no sense to do so.
2267 * The idea is to mimic for testing purposes the DSP "nagging" technique used by the
2268 * Triton Crystal Dreams demo that allow it to do full DMA playback Goldplay style
2269 * without needing to autodetect what IRQ the card is on. The programmer did not
2270 * write the code to use auto-init DSP commands. Instead, the demo uses the single
2271 * cycle DSP playback command (1.xx commands) with the DMA settings set to one sample
2272 * wide (Goldplay style), then, from the same IRQ 0 handler that does the music,
2273 * polls the DSP write status register to check DSP busy state. If the DSP is not busy,
2274 * it counts down a timer internally on each IRQ 0, then when it hits zero, begins
2275 * sending another DSP playback block (DSP command 0x14,xx,xx). It does this whether
2276 * or not the last DSP 0x14 command has finished playing or not, thus, "nagging" the
2277 * DSP. The upshot of this bizarre technique is that it doesn't need to pay any
2278 * attention to the Sound Blaster IRQ. The downside, of course, is that later
2279 * "emulations" of the Sound Blaster don't recognize the technique and playback will
2280 * not work properly like that.
2282 * The other reason to use such a technique is to avoid artifacts caused by the amount
2283 * of time it takes the signal an IRQ vs the CPU to program another single-cycle block
2284 * (longer than one sample period), since nagging the DSP ensures it never stops despite
2285 * the single-cycle mode it's in. The side effect of course is that since the DSP is
2286 * never given a chance to complete a whole block, it never fires the IRQ! */
2287 if (cx->dsp_nag_mode && sndsb_will_dsp_nag(cx))
2288 sndsb_send_buffer_again(cx);
2290 cx->timer_tick_signal = 0;
2292 if (oflags & 0x200/* if interrupts were enabled */) _sti();
2294 /* if DMA based playback and no IRQ assigned, then we need to poll the ack register to keep
2295 * playback from halting on SB16 hardware. Clones and SBpro and earlier don't seem to care. */
2296 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && cx->irq < 0 && cx->poll_ack_when_no_irq)
2297 sndsb_interrupt_ack(cx,3);
2300 /* we can do output method. if we can't, then don't bother playing, because it flat out won't work.
2301 * if we can, then you want to check if it's supported, because if it's not, you may get weird results, but nothing catastrophic. */
2302 int sndsb_dsp_out_method_can_do(struct sndsb_ctx *cx,unsigned long wav_sample_rate,unsigned char wav_stereo,unsigned char wav_16bit) {
2303 #if !(TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__COMPACT__))) /* this is too much to cram into a small model EXE */
2304 # define MSG(x) cx->reason_not_supported = x
2307 cx->reason_not_supported = "";
2311 MSG("DSP not detected");
2312 return 0; /* No DSP, no playback */
2314 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_MAX) {
2315 MSG("play method out of range");
2316 return 0; /* invalid DSP output method */
2318 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && !wav_16bit && cx->dma8 < 0) {
2319 MSG("DMA-based playback, 8-bit PCM, no channel assigned (dma8)");
2323 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx && cx->ess_extensions) {
2324 /* OK. we can use ESS extensions with flipped sign */
2326 else if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_4xx && cx->audio_data_flipped_sign) {
2327 MSG("Flipped sign playback requires DSP 4.xx playback");
2331 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx && cx->ess_extensions) {
2332 /* OK. we can use ESS extensions to do 16-bit playback */
2334 else if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_4xx && wav_16bit) {
2335 MSG("16-bit PCM playback requires DSP 4.xx mode");
2339 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && wav_16bit && cx->dma16 < 0) {
2340 MSG("DMA-based playback, 16-bit PCM, no channel assigned (dma16)");
2343 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && wav_16bit && cx->dma16 >= 4 && !(d8237_flags&D8237_DMA_SECONDARY)) {
2344 MSG("DMA-based playback, 16-bit PCM, dma16 channel refers to\nnon-existent secondary DMA controller");
2347 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && wav_16bit && cx->dma16 >= 0 && cx->dma16 < 4 && !(d8237_flags&D8237_DMA_PRIMARY)) {
2348 MSG("DMA-based playback, 16-bit PCM, dma16 channel refers to\nnon-existent primary DMA controller");
2351 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && !wav_16bit && cx->dma8 >= 4 && !(d8237_flags&D8237_DMA_SECONDARY)) { /* as if this would ever happen, but.. */
2352 MSG("DMA-based playback, 8-bit PCM, dma8 channel refers to\nnon-existent secondary DMA controller");
2355 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && !wav_16bit && cx->dma8 >= 0 && cx->dma8 < 4 && !(d8237_flags&D8237_DMA_PRIMARY)) {
2356 MSG("DMA-based playback, 8-bit PCM, dma8 channel refers to\nnon-existent primary DMA controller");
2360 if (cx->dsp_adpcm > 0) {
2361 if (cx->dsp_record) {
2362 MSG("No such thing as ADPCM recording");
2365 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) {
2366 MSG("No such thing as direct DAC ADPCM playback");
2370 MSG("No such thing as 16-bit ADPCM playback");
2374 MSG("No such thing as stereo ADPCM playback");
2377 if (cx->audio_data_flipped_sign) {
2378 MSG("No such thing as flipped sign ADPCM playback");
2381 if (cx->goldplay_mode) {
2382 MSG("Goldplay ADPCM playback not supported");
2386 else if (cx->goldplay_mode) {
2387 #if TARGET_MSDOS == 16
2388 /* bug-check: goldplay 16-bit DMA is not possible if somehow the goldplay_dma[] field is not WORD-aligned
2389 * and 16-bit audio is using the 16-bit DMA channel (misaligned while 8-bit DMA is fine) */
2390 if (cx->buffer_16bit && cx->dma16 >= 4 && ((unsigned int)(cx->goldplay_dma))&1) {
2391 MSG("16-bit PCM Goldplay playback requested\nand DMA buffer is not word-aligned.");
2397 # if !(TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__COMPACT__))) /* this is too much to cram into a small model EXE */
2398 cx->reason_not_supported = NULL;
2404 unsigned int sndsb_will_dsp_nag(struct sndsb_ctx *cx) {
2405 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT)
2408 if (cx->chose_autoinit_dma && !cx->chose_autoinit_dsp) {
2409 /* NTS: Do not nag the DSP when it's in "highspeed" DMA mode. Normal DSPs cannot accept
2410 * commands in that state and any attempt will cause this function to hang for the
2411 * DSP timeout period causing the main loop to jump and stutter. But if the user
2412 * really *wants* us to do it (signified by setting dsp_nag_highspeed) then we'll do it */
2413 if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_4xx && cx->buffer_hispeed && cx->hispeed_matters && cx->hispeed_blocking && !cx->dsp_nag_hispeed)
2420 /* meant to be called from an IRQ */
2421 void sndsb_irq_continue(struct sndsb_ctx *cx,unsigned char c) {
2422 if (cx->dsp_nag_mode) {
2423 /* if the main loop is nagging the DSP then we shouldn't do anything */
2424 if (sndsb_will_dsp_nag(cx)) return;
2427 /* only call send_buffer_again if 8-bit DMA completed
2428 and bit 0 set, or if 16-bit DMA completed and bit 1 set */
2429 if ((c & 1) && !cx->buffer_16bit)
2430 sndsb_send_buffer_again(cx);
2431 else if ((c & 2) && cx->buffer_16bit)
2432 sndsb_send_buffer_again(cx);
2435 /* output method is supported (as in, recommended) */
2436 int sndsb_dsp_out_method_supported(struct sndsb_ctx *cx,unsigned long wav_sample_rate,unsigned char wav_stereo,unsigned char wav_16bit) {
2437 #if !(TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__COMPACT__))) /* this is too much to cram into a small model EXE */
2438 # define MSG(x) cx->reason_not_supported = x
2441 cx->reason_not_supported = "";
2444 if (!sndsb_dsp_out_method_can_do(cx,wav_sample_rate,wav_stereo,wav_16bit))
2447 if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_4xx && wav_sample_rate < 4000) {
2448 MSG("Non-SB16 playback below 4000Hz probably not going to work");
2451 if (cx->dsp_alias_port && cx->dsp_vmaj > 2) {
2452 MSG("DSP alias I/O ports only exist on original Sound Blaster\nDSP 1.xx and 2.xx");
2456 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_4xx) {
2457 if (cx->is_gallant_sc6600) {
2458 if (cx->dsp_vmaj < 3) {
2459 MSG("DSP 4.xx playback requires SB16 or clone [SC-6000]");
2464 if (cx->dsp_vmaj < 4) {
2465 MSG("DSP 4.xx playback requires SB16");
2471 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && cx->goldplay_mode && !cx->dsp_autoinit_dma) {
2472 MSG("Goldplay mode requires auto-init DMA to work properly");
2475 if (cx->dsp_autoinit_command && cx->dsp_vmaj < 2) {
2476 MSG("Auto-init DSP command support requires DSP 2.0 or higher");
2479 if ((cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT || cx->goldplay_mode) && cx->windows_emulation) {
2480 MSG("Direct mode or goldplay mode not recommended\nfor use within a Windows DOS box, it won't work");
2484 if (wav_stereo && cx->dsp_vmaj < 3) {
2485 MSG("You are playing stereo audio on a DSP that doesn't support stereo");
2489 if (wav_stereo && cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && cx->dsp_play_method < SNDSB_DSPOUTMETHOD_3xx) {
2490 MSG("You are playing stereo audio in a DSP mode\nthat doesn't support stereo");
2493 if (wav_stereo && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) {
2494 MSG("Direct DAC mode does not support stereo");
2498 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_201 &&
2499 (cx->dsp_vmaj < 2 || (cx->dsp_vmaj == 2 && cx->dsp_vmin == 0))) {
2500 MSG("DSP 2.01+ or higher playback requested for DSP older than v2.01");
2503 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_200 && cx->dsp_vmaj < 2) {
2504 MSG("DSP 2.0 or higher playback requested for DSP older than v2.0");
2507 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && cx->dsp_vmaj < 1) {
2508 MSG("DSP 1.xx or higher playback requested for\na DSP who's version I can't determine");
2512 /* this library can play DMA without an IRQ channel assigned, but there are some restrictions on doing so */
2513 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && cx->irq < 0) {
2514 /* we can do it if auto-init DMA and auto-init DSP and we poll the ack register (best for SB16).
2515 * for pre-SB16, we can ignore the IRQ and playback will continue anyway. */
2516 if (cx->dsp_autoinit_dma && cx->dsp_autoinit_command &&
2517 ((cx->dsp_adpcm > 0 && cx->enable_adpcm_autoinit) || cx->dsp_adpcm == 0) &&
2518 (cx->poll_ack_when_no_irq || cx->dsp_vmaj < 4) &&
2519 !(cx->vdmsound || cx->windows_xp_ntvdm || cx->windows_9x_me_sbemul_sys)) {
2522 /* we can do it if auto-init DMA and single-cycle DSP and we're nagging the DSP */
2523 else if (cx->dsp_nag_mode && sndsb_will_dsp_nag(cx)) {
2524 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_4xx) {
2527 else if ((cx->force_hispeed || (wav_sample_rate*(wav_stereo?2:1)) > (cx->dsp_record ? 13000UL : 23000UL)) && cx->hispeed_blocking) {
2529 MSG("No IRQ assigned & DSP nag mode is ineffective\nif the DSP will run in 2.0/Pro highspeed DSP mode.");
2537 /* anything else is iffy */
2538 MSG("No IRQ assigned, no known combinations are selected that\n"
2539 "allow DSP playback to work. Try DSP auto-init with Poll ack\n"
2540 "or DSP single-cycle with nag mode enabled.");
2545 if (cx->dsp_nag_mode) {
2546 /* nag mode can cause problems with DSP 4.xx commands? */
2547 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_4xx) {
2548 MSG("DSP nag mode on a SB16 in DSP 4.xx mode can cause problems.\n"
2549 "Halting, popping/cracking, stereo L/R swapping timing glitches.\n"
2550 "Use DSP auto-init and non-IRQ polling for more reliable DMA.");
2553 /* nag mode can cause lag from the idle command if hispeed mode is involved */
2554 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_201 && cx->hispeed_matters && cx->hispeed_blocking &&
2555 cx->dsp_nag_hispeed && (cx->force_hispeed || (wav_sample_rate*(wav_stereo?2:1)) > (cx->dsp_record ? 13000UL : 23000UL))) {
2556 MSG("DSP nag mode when hispeed DSP playback is involved can cause\n"
2557 "lagging and delay on this system because the DSP will block during playback");
2562 MSG("Target sample rate out of range");
2563 if (cx->dsp_adpcm > 0) {
2564 /* Neither VDMSOUND.EXE or NTVDM's SB emulation handle ADPCM well */
2565 if (cx->vdmsound || cx->windows_xp_ntvdm || cx->windows_9x_me_sbemul_sys) {
2566 MSG("You are attempting ADPCM within Windows\nemulation that will likely not support ADPCM playback");
2570 /* Gallant SC-6600 clones do not support auto-init ADPCM, though they support all modes */
2571 if (cx->is_gallant_sc6600 && cx->enable_adpcm_autoinit && cx->dsp_autoinit_command) {
2572 MSG("SC-6600 SB clones do not support auto-init ADPCM");
2576 /* NTS: If we could easily differentiate Creative SB 2.0 from clones, we could identify the
2577 * slightly out-of-spec ranges supported by the SB 2.0 that deviates from Creative
2579 if (cx->dsp_adpcm == ADPCM_4BIT) {
2580 if (wav_sample_rate > 12000UL) return 0;
2582 else if (cx->dsp_adpcm == ADPCM_2_6BIT) {
2583 if (wav_sample_rate > 13000UL) return 0;
2585 else if (cx->dsp_adpcm == ADPCM_2BIT) {
2586 if (wav_sample_rate > 11000UL) return 0; /* NTS: On actual Creative SB 2.0 hardware, this can apparently go up to 15KHz */
2592 else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_4xx) {
2593 /* based on Sound Blaster 16 PnP cards that max out at 48000Hz apparently */
2594 /* FIXME: Is there a way for us to distinguish a Sound Blaster 16 (max 44100Hz)
2595 * from later cards (max 48000Hz) *other* than whether or not it is Plug & Play?
2596 * Such as using the DSP version? At what DSP version did the card go from
2597 * a max 44100Hz to 48000Hz? */
2598 if (wav_sample_rate > cx->max_sample_rate_dsp4xx) return 0;
2600 else if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
2601 /* I've been able to drive ESS chips up to 48Khz and beyond (though beyond 48KHz 16-bit stereo
2602 * the ISA bus can't keep up well). But let's cap it at 48KHz anyway */
2603 if (wav_sample_rate > 48000) return 0;
2605 else if ((!cx->hispeed_matters && cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx) ||
2606 cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx || cx->dsp_play_method == SNDSB_DSPOUTMETHOD_201) {
2607 /* Because of the way Sound Blaster Pro stereo works and the way the time constant
2608 * is generated, the maximum sample rate is halved in stereo playback. On Pro and
2609 * old SB16 cards this means a max of 44100Hz mono 22050Hz stereo. On SB16 ViBRA
2610 * cards, this usually means a maximum of 48000Hz mono 24000Hz stereo.
2612 * For DSP 2.01+ support, we also use this calculation because hispeed mode is involved */
2613 if (wav_sample_rate > ((cx->dsp_record ? cx->max_sample_rate_sb_hispeed : cx->max_sample_rate_sb_hispeed) / (wav_stereo ? 2U : 1U))) return 0;
2615 else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_200 || cx->dsp_play_method == SNDSB_DSPOUTMETHOD_1xx) {
2616 if (wav_sample_rate > (cx->dsp_record ? cx->max_sample_rate_sb_rec : cx->max_sample_rate_sb_play)) return 0;
2618 else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) {
2619 if (wav_sample_rate > (cx->dsp_record ? cx->max_sample_rate_sb_rec_dac : cx->max_sample_rate_sb_play_dac)) return 0;
2622 /* Creative SB16 cards do not pay attention to the Sound Blaster Pro stereo bit.
2623 * Playing stereo using the 3xx method on 4.xx DSPs will not work. Most SB16 clones
2624 * will pay attention to that bit however, but it's best not to assume that will happen. */
2625 if (cx->dsp_vmaj >= 4 && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx && wav_stereo) {
2626 MSG("Sound Blaster Pro stereo playback on SB16 (DSP 4.xx)\nwill not play as stereo because Creative SB16\ncards ignore the mixer bit");
2629 /* SB16 cards seem to alias hispeed commands to normal DSP and let them set the time constant all the way up to the max supported by
2630 * the DSP, hispeed mode or not. */
2631 if (cx->dsp_vmaj >= 4 && (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_201 || cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) && cx->hispeed_matters) {
2632 MSG("Sound Blaster 2.0/Pro high-speed DSP modes not\nrecommended for use on your DSP (DSP 4.xx detected)");
2635 /* friendly reminder to the user that despite DSP autoinit enable 1.xx commands are not auto-init */
2636 if (cx->dsp_autoinit_command && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_1xx) {
2637 MSG("DSP 1.xx commands do not support auto-init. Playback\nis automatically using single-cycle commands instead.");
2638 return 1; /* we support it, but just to let you know... */
2640 /* playing DMA backwards with 16-bit audio is not advised.
2641 * it COULD theoretically work with a 16-bit DMA channel because of how it counts, but...
2642 * there's also the risk you use an 8-bit DMA channel which of course gets the byte order wrong! */
2643 if (cx->backwards && wav_16bit) {
2644 MSG("16-bit PCM played backwards is not recommended\nbyte order may not be correct to sound card");
2647 /* it's also a good bet Windows virtualization never even considers DMA in decrement mode because nobody really ever uses it */
2648 if (cx->backwards && cx->windows_emulation) {
2649 MSG("DMA played backwards is not recommended from\nwithin a Windows DOS box");
2652 /* EMM386.EXE seems to handle backwards DMA just fine, but we can't assume v86 monitors handle it well */
2653 #if TARGET_MSDOS == 32
2654 if (cx->backwards && dos_ltp_info.paging && dos_ltp_info.dma_dos_xlate) {
2656 if (cx->backwards && (cpu_flags&CPU_FLAG_V86_ACTIVE)) {
2658 MSG("DMA played backwards is not recommended from\nwithin a virtual 8086 mode monitor");
2662 /* NTS: Virtualbox supports backwards DMA, it's OK */
2664 # if !(TARGET_MSDOS == 16 && (defined(__SMALL__) || defined(__COMPACT__))) /* this is too much to cram into a small model EXE */
2665 cx->reason_not_supported = NULL;
2671 int sndsb_write_dsp_blocksize(struct sndsb_ctx *cx,uint16_t tc) {
2672 if (!sndsb_write_dsp(cx,0x48))
2674 if (!sndsb_write_dsp(cx,tc-1))
2676 if (!sndsb_write_dsp(cx,(tc-1)>>8))
2681 int sndsb_write_dsp_outrate(struct sndsb_ctx *cx,unsigned long rate) {
2682 if (!sndsb_write_dsp(cx,0x41))
2684 if (!sndsb_write_dsp(cx,rate>>8)) /* Ugh, Creative, be consistent! */
2686 if (!sndsb_write_dsp(cx,rate))
2691 uint32_t sndsb_read_dma_buffer_position(struct sndsb_ctx *cx) {
2694 /* the program is asking for DMA position. If we're doing the Windows springwait hack,
2695 * then NOW is the time to initialize DSP transfer! */
2696 if (cx->windows_emulation && cx->windows_springwait == 1 && cx->windows_xp_ntvdm) {
2697 sndsb_prepare_dsp_playback(cx,cx->buffer_rate,cx->buffer_stereo,cx->buffer_16bit);
2698 sndsb_setup_dma(cx);
2699 sndsb_begin_dsp_playback(cx);
2700 cx->windows_springwait = 2;
2703 /* "direct" and "goldplay" methods require the program to update the play point in some fashion,
2704 * usually by programming IRQ 0 to tick at the sample rate */
2705 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT || cx->goldplay_mode) {
2706 r = cx->direct_dsp_io;
2707 if (r >= cx->buffer_size) r = cx->buffer_size - 1;
2709 else if (cx->buffer_16bit) {
2710 if (cx->dma16 < 0) return 0;
2711 r = d8237_read_count(cx->dma16);
2712 if (cx->backwards) {
2716 if (r >= 0xFFFEUL) r = 0; /* FIXME: the 8237 library should have a "is terminal count" function */
2717 if (r >= cx->buffer_dma_started_length) r = cx->buffer_dma_started_length - 1;
2718 r = cx->buffer_dma_started_length - (r+1);
2719 r += cx->buffer_dma_started;
2723 if (cx->dma8 < 0) return 0;
2724 r = d8237_read_count(cx->dma8);
2725 if (cx->backwards) {
2726 if (r >= 0xFFFFUL) r = 0;
2727 if (r >= cx->buffer_dma_started_length) r = cx->buffer_dma_started_length - 1;
2728 r += cx->buffer_dma_started;
2731 if (r >= 0xFFFFUL) r = 0;
2732 if (r >= cx->buffer_dma_started_length) r = cx->buffer_dma_started_length - 1;
2733 r = cx->buffer_dma_started_length - (r+1);
2734 r += cx->buffer_dma_started;
2741 int sndsb_shutdown_dma(struct sndsb_ctx *cx) {
2742 unsigned char ch = cx->buffer_16bit ? cx->dma16 : cx->dma8;
2743 if ((signed char)ch == -1) return 0;
2744 /* set up the DMA channel */
2745 outp(d8237_ioport(ch,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(ch) | D8237_MASK_SET); /* mask */
2749 int sndsb_setup_dma(struct sndsb_ctx *cx) {
2750 unsigned char ch = cx->buffer_16bit ? cx->dma16 : cx->dma8;
2751 unsigned char dma_mode = D8237_MODER_MODESEL_SINGLE;
2753 /* ESS bugfix: except for goldplay mode, we tell the chipset to use demand mode fetching.
2754 * So then, setup the DMA controller for it too! */
2755 if (cx->ess_extensions && !cx->goldplay_mode)
2756 dma_mode = D8237_MODER_MODESEL_DEMAND;
2758 /* if we're doing the Windows "spring" buffer hack, then don't do anything.
2759 * later when the calling program queries the DMA position, we'll setup DSP playback and call this function again */
2760 if (cx->windows_emulation && cx->windows_springwait == 0 && cx->windows_xp_ntvdm)
2764 cx->direct_dsp_io = cx->buffer_size - 1;
2766 cx->direct_dsp_io = 0;
2768 if ((signed char)ch == -1) return 0;
2769 /* set up the DMA channel */
2770 outp(d8237_ioport(ch,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(ch) | D8237_MASK_SET); /* mask */
2772 outp(d8237_ioport(ch,D8237_REG_W_WRITE_MODE),
2773 (cx->chose_autoinit_dma ? D8237_MODER_AUTOINIT : 0) |
2774 (cx->backwards ? D8237_MODER_ADDR_DEC : 0) |
2775 D8237_MODER_CHANNEL(ch) |
2776 D8237_MODER_TRANSFER(cx->dsp_record ? D8237_MODER_XFER_WRITE : D8237_MODER_XFER_READ) |
2777 D8237_MODER_MODESEL(dma_mode));
2779 if (cx->goldplay_mode) {
2780 /* goldplay mode REQUIRES auto-init DMA */
2781 if (!cx->chose_autoinit_dma) return -1;
2783 cx->gold_memcpy = (cx->buffer_16bit?2:1)*(cx->buffer_stereo?2:1);
2785 #if TARGET_MSDOS == 32
2786 if (cx->goldplay_dma == NULL) {
2787 if ((cx->goldplay_dma=dma_8237_alloc_buffer(16)) == NULL)
2792 /* Goldplay mode: The size of ONE sample is given to the DMA controller.
2793 * This tricks the DMA controller into re-transmitting that sample continuously
2794 * to the sound card. Then the demo uses the timer interrupt to modify that byte
2795 * and make audio. This was apparently popular with Goldplay in the 1991-1993
2796 * demoscene time frame, and evidently worked fine, but on today's PCs with CPU
2797 * caches and buffers this crap would obviously never fly.
2799 * Note we allow the program to do this with 16-bit output, even though the
2800 * original Goldplay library was limited to 8 and nobody ever did this kind of
2801 * hackery by the time 16-bit SB output was the norm. But my test code shows
2802 * that you can pull that stunt with stereo and 16-bit audio modes too! */
2803 d8237_write_count(ch,(cx->buffer_stereo ? 2 : 1)*(cx->buffer_16bit ? 2 : 1));
2804 /* point it to our "goldplay_dma" */
2805 #if TARGET_MSDOS == 32
2806 d8237_write_base(ch,cx->goldplay_dma->phys + (cx->backwards ? (cx->gold_memcpy-1) : 0));
2808 if ((cx->buffer_16bit?1:0)^(cx->audio_data_flipped_sign?1:0))
2809 memset(cx->goldplay_dma->lin,0,4);
2811 memset(cx->goldplay_dma->lin,128,4);
2814 unsigned char far *p = (unsigned char far*)(cx->goldplay_dma);
2815 d8237_write_base(ch,((uint32_t)FP_SEG(p) << 4UL) + (uint32_t)FP_OFF(p) + (cx->backwards ? (cx->gold_memcpy-1) : 0));
2817 if ((cx->buffer_16bit?1:0)^(cx->audio_data_flipped_sign?1:0))
2825 d8237_write_count(ch,cx->buffer_dma_started_length);
2827 d8237_write_base(ch,cx->buffer_phys+cx->buffer_dma_started+cx->buffer_dma_started_length-1);
2829 d8237_write_base(ch,cx->buffer_phys+cx->buffer_dma_started); /* RAM location with not much around */
2832 outp(d8237_ioport(ch,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(ch)); /* unmask */
2836 unsigned long sndsb_real_sample_rate(struct sndsb_ctx *cx) {
2837 unsigned long total_rate;
2838 unsigned char timeconst;
2839 unsigned long real_rate;
2841 total_rate = (unsigned long)cx->buffer_rate * (cx->buffer_stereo ? 2UL : 1UL);
2842 if (total_rate < 4000UL) total_rate = 4000UL;
2843 timeconst = (unsigned char)((65536UL - (256000000UL / total_rate)) >> 8UL);
2844 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_4xx) return cx->buffer_rate;
2845 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) return cx->buffer_rate;
2847 /* 256 - (1000000 / rate) = const
2848 * -(1000000 / rate) = const - 256
2849 * 1000000 / rate = -(const - 256)
2850 * 1000000 / rate = -const + 256
2851 * 1000000 = (-const + 256) * rate
2852 * 1000000 / (-const + 256) = rate
2853 * 1000000 / (256 - const) = rate */
2854 real_rate = 1000000UL / (unsigned long)(256 - timeconst);
2855 if (cx->buffer_stereo) real_rate /= 2UL;
2859 unsigned char sndsb_rate_to_time_constant(struct sndsb_ctx *cx,unsigned long rate) {
2860 if (rate < 4000UL) rate = 4000UL;
2861 return (unsigned char)((65536UL - (256000000UL / rate)) >> 8);
2864 int sndsb_prepare_dsp_playback(struct sndsb_ctx *cx,unsigned long rate,unsigned char stereo,unsigned char bit16) {
2867 /* TODO: Don't play if already playing */
2869 cx->chose_use_dma = 0;
2870 cx->chose_autoinit_dma = 0;
2871 cx->chose_autoinit_dsp = 0;
2872 cx->direct_dac_sent_command = 0;
2873 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT && cx->windows_emulation)
2876 /* set up the params. if we already did (windows spring hack) then don't do it again, but proceed directly
2877 * to programming the hardware */
2878 if (cx->windows_springwait == 0) {
2879 cx->buffer_stereo = stereo;
2880 cx->buffer_16bit = bit16;
2881 cx->buffer_rate = rate;
2882 cx->buffer_hispeed = 0;
2883 cx->buffer_dma_started = 0;
2884 cx->buffer_last_io = 0;
2885 cx->dsp_stopping = 0;
2887 lm = cx->buffer_size;
2888 if (cx->dsp_adpcm == 0) {
2889 if (bit16) lm >>= 1UL;
2890 if (stereo) lm >>= 1UL;
2893 /* if IRQ interval is not assigned, give it the buffer length.
2894 we must also ensure the requested interval is less than the
2896 if (cx->buffer_irq_interval == 0 ||
2897 cx->buffer_irq_interval > lm)
2898 cx->buffer_irq_interval = lm;
2900 /* Windows XP SB emulation: Microsoft's shameful NTVDM.EXE Sound Blaster emulation
2901 * attempts to mimic the auto-init modes of DSP v2.0/v2.1 but has a very stupid bug:
2902 * if the interval (DSP block size) you specify is not precisely 1/1, 1/2, 1/4, etc.
2903 * of the total buffer size (DMA transfer length), their implementation will miss the
2904 * end of the DMA transfer and run off into the weeds.
2906 * Another bug: if the block size is too large (4KB or larger?!?) their implementation
2907 * will randomly drop portions of the audio and the audio will seem to play extra fast.
2909 * So we have to restrict the irq interval according to these stupid bugs in order to
2910 * produce anything close to glitch free audio when under Windows XP's DOS box.
2912 * Shame on you, Microsoft! */
2913 if (cx->windows_emulation && cx->windows_xp_ntvdm) {
2914 if (cx->buffer_irq_interval <= (lm / 16UL) || (cx->buffer_size/8) > 4096)
2915 cx->buffer_irq_interval = (lm / 16UL);
2916 else if (cx->buffer_irq_interval <= (lm / 8UL) || (cx->buffer_size/4) > 4096)
2917 cx->buffer_irq_interval = (lm / 8UL);
2918 else if (cx->buffer_irq_interval <= (lm / 4UL) || (cx->buffer_size/2) > 4096)
2919 cx->buffer_irq_interval = (lm / 4UL);
2920 /* Microsoft's shitty implementation also doesn't mesh well with our circular buffer
2921 * implementation when the interval is equal to the buffer size. Ther implementation
2922 * makes no effort to simulate a DMA transfer going along at the sample rate, it just
2923 * "jumps" forward on IRQ. Just as bad as Gravis's SBOS emulation and their shitty
2926 cx->buffer_irq_interval = (lm / 2UL);
2928 else if (cx->ess_extensions) {
2929 /* ESS 688/1869 chipsets: Unless using Goldplay mode we normally tell the chipset
2930 * to use 2 or 4 byte demand transfers to optimize ISA bandwidth. If not using
2931 * auto-init DMA, this method of transfer will fail if the interval is not a
2932 * multiple of 4 bytes.
2934 * I *think* that this might be responsible for why non-auto-init DSP+DMA playback
2935 * eventually stalls on one ESS 688-based laptop SB clone I test on. */
2936 if (!cx->goldplay_mode && !cx->dsp_autoinit_dma) {
2937 if (bit16) lm <<= 1UL;
2938 if (stereo) lm <<= 1UL;
2939 lm &= ~3; /* round down 4 bytes */
2940 if (lm == 0) lm = 4;
2941 if (bit16) lm >>= 1UL;
2942 if (stereo) lm >>= 1UL;
2946 /* don't let the API play 16-bit audio if less than DSP 4.xx because 16-bit audio played
2947 * as 8-bit sounds like very loud garbage, be kind to the user */
2949 if (cx->ess_extensions) {
2950 if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_3xx)
2953 else if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_4xx) {
2958 /* NTS: we use the "can do" function to reject obvious configurations that will never work
2959 * on the card, verses an unsupported configuration that we advise not using */
2960 if (!sndsb_dsp_out_method_can_do(cx,rate,stereo,bit16))
2964 /* if we're doing the Windows "spring" buffer hack, then don't do anything.
2965 * later when the calling program queries the DMA position, we'll setup DSP playback and call this function again */
2966 if (cx->windows_emulation && cx->windows_springwait == 0 && cx->windows_xp_ntvdm)
2969 /* clear any pending DSP events (DSP 4.xx) */
2970 if (cx->dsp_vmaj >= 4)
2971 sndsb_interrupt_ack(cx,3);
2973 /* NTS: I have an old CT1350 that requires the "speaker on" command
2974 * even for direct command (0x10) audio to work (or else, you get a
2975 * quiet staticky sound that resembles your audio). So while this
2976 * command is pointless for Sound Blaster 16 and later, it is vital
2977 * for older Sound Blasters.
2979 * CT1350 Detail: DSP v2.2, no mixer chip, does not support stereo,
2980 * maxes out at 44.1KHz, and on the Pentium MMX 200MHz
2981 * system I test it on the DSP has problems playing at
2982 * 22050Hz if the floppy drive is running (the audio
2983 * audibly warbles). The card is 8-bit ISA. I also
2984 * noticed modern computer mics don't work with it.
2985 * It was designed for unpowered mics, which were
2986 * common at the time and often used with tape recorders. */
2987 sndsb_write_dsp(cx,cx->dsp_record ? 0xD3 : 0xD1); /* turn off speaker if recording, else, turn on */
2989 /* these methods involve DMA */
2990 cx->chose_use_dma = 1;
2991 /* use auto-init DMA unless for some reason we can't */
2992 cx->chose_autoinit_dma = cx->dsp_autoinit_dma;
2993 cx->chose_autoinit_dsp = cx->dsp_autoinit_command;
2995 /* Gravis Ultrasound SBOS/MEGA-EM don't handle auto-init 1.xx very well.
2996 the only way to cooperate with their shitty emulation is to strictly
2997 limit DMA count to the IRQ interval and to NOT set the auto-init flag */
2998 if (cx->sbos || cx->mega_em)
2999 cx->chose_autoinit_dma = cx->chose_autoinit_dsp = 0;
3001 if (cx->dsp_adpcm > 0) {
3002 sndsb_write_dsp_timeconst(cx,sndsb_rate_to_time_constant(cx,rate));
3003 if (stereo || bit16 || cx->dsp_record || cx->goldplay_mode)
3004 return 0; /* ADPCM modes do not support stereo or 16 bit nor recording */
3006 /* if DSP 2.xx mode or higher and ADPCM auto-init enabled, enable autoinit */
3007 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_200 && cx->enable_adpcm_autoinit && cx->dsp_autoinit_command) {
3008 sndsb_write_dsp_blocksize(cx,cx->buffer_irq_interval);
3009 cx->chose_autoinit_dsp = 1;
3012 cx->chose_autoinit_dsp = 0;
3015 else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_1xx) {
3016 /* NTS: Apparently, issuing Pause & Resume commands at this stage hard-crashes DOSBox 0.74? */
3017 sndsb_write_dsp_timeconst(cx,sndsb_rate_to_time_constant(cx,rate * (cx->buffer_stereo ? 2UL : 1UL)));
3018 cx->chose_autoinit_dsp = 0; /* DSP 1.xx does not support auto-init DSP commands */
3020 else if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
3021 /* do nothing----using SBPro DSP commands then programming ESS registers serves only to
3022 * confuse the chip and cause it to stop responding. */
3024 else if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_200 && cx->dsp_play_method <= SNDSB_DSPOUTMETHOD_3xx) {
3025 /* DSP 2.00, 2.01+, and DSP 3.xx */
3026 unsigned long total_rate = rate * (cx->buffer_stereo ? 2UL : 1UL);
3028 /* NTS: Apparently, issuing Pause & Resume commands at this stage hard-crashes DOSBox 0.74? */
3029 sndsb_write_dsp_timeconst(cx,sndsb_rate_to_time_constant(cx,total_rate));
3031 /* DSP 2.01 and higher can do "high-speed" DMA transfers up to 44.1KHz */
3032 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_201) {
3033 /* NTS: I have a CT1350B card that has audible problems with the ISA bus when driven up to
3034 * 22050Hz in non-hispeed modes (if I have something else run, like reading the floppy
3035 * drive, the audio "warbles", changing speed periodically). So while Creative suggests
3036 * enabling hispeed mode for rates 23KHz and above, I think it would be wiser instead
3037 * to do hispeed mode for 16KHz or higher instead. [1]
3038 * [DSP v2.2 with no copyright string]
3039 * [Tested on Pentium MMX 200MHz system with ISA and PCI slots]
3040 * [Applying fix [1] indeed resolved the audible warbling]
3041 * [Is this fix needed for any other Sound Blaster products of that era?] */
3042 if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) /* ESS 688/1869 use of the extensions it doesn't matter */
3043 cx->buffer_hispeed = 0;
3044 else if (cx->force_hispeed)
3045 cx->buffer_hispeed = 1;
3046 else if (cx->dsp_vmaj == 2 && cx->dsp_vmin == 2 && !strcmp(cx->dsp_copyright,"")) /* [1] */
3047 cx->buffer_hispeed = (total_rate >= (cx->dsp_record ? 8000 : 16000));
3049 cx->buffer_hispeed = (total_rate >= (cx->dsp_record ? 13000 : 23000));
3051 /* DSP 3.xx stereo management */
3052 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
3053 /* Sound Blaster Pro requires the "set input mode to mono/stereo" commands if recording,
3054 * and sets mono/stereo mode with a bit defined in a specific mixer register */
3055 if (cx->dsp_record) sndsb_write_dsp(cx,cx->buffer_stereo ? 0xA8 : 0xA0);
3056 sndsb_write_mixer(cx,0x0E,0x20 | (cx->buffer_stereo ? 0x02 : 0x00));
3059 /* if we need to, transmit block length */
3060 if (cx->buffer_hispeed || cx->chose_autoinit_dsp)
3061 sndsb_write_dsp_blocksize(cx,cx->buffer_irq_interval * (stereo?2:1));
3064 cx->buffer_hispeed = 0;
3065 if (cx->chose_autoinit_dsp)
3066 sndsb_write_dsp_blocksize(cx,cx->buffer_irq_interval * (stereo?2:1));
3069 else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_4xx) {
3070 /* DSP 4.xx management is much simpler here */
3071 sndsb_write_dsp_outrate(cx,rate);
3074 /* auto-init DSP modes require auto-init DMA. if auto-init DMA
3075 * is not available, then don't use auto-init DSP commands. */
3076 if (!cx->chose_autoinit_dma) cx->chose_autoinit_dsp = 0;
3078 /* pick the DMA buffer length to be programmed.
3079 * if auto-init, then we can safely give the entire buffer size.
3080 * else, we must match the IRQ interval */
3081 if (cx->chose_autoinit_dma) {
3082 cx->buffer_dma_started_length = cx->buffer_size;
3085 cx->buffer_dma_started_length = cx->buffer_irq_interval;
3086 if (cx->dsp_adpcm == 0) {
3087 if (bit16) cx->buffer_dma_started_length <<= 1UL;
3088 if (stereo) cx->buffer_dma_started_length <<= 1UL;
3092 cx->buffer_dma_started = cx->buffer_size - cx->buffer_dma_started_length;
3098 int sndsb_begin_dsp_playback(struct sndsb_ctx *cx) {
3099 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) {
3100 cx->gold_memcpy = 0;
3102 cx->timer_tick_func = sndsb_timer_tick_directi_cmd;
3104 cx->timer_tick_func = sndsb_timer_tick_directo_cmd;
3106 else if (cx->goldplay_mode) {
3107 #if TARGET_MSDOS == 32
3108 if (cx->goldplay_dma == NULL)
3112 cx->gold_memcpy = (cx->buffer_16bit?2:1)*(cx->buffer_stereo?2:1);
3114 cx->timer_tick_func = sndsb_timer_tick_goldi_cpy;
3116 cx->timer_tick_func = sndsb_timer_tick_goldo_cpy;
3119 if (cx->dsp_nag_mode)
3120 cx->timer_tick_func = sndsb_timer_tick_gen;
3122 cx->timer_tick_func = NULL;
3124 cx->gold_memcpy = 0;
3127 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) /* do nothing */
3130 /* defer beginning playback until the program first asks for the DMA position */
3131 if (cx->windows_emulation && cx->windows_springwait == 0 && cx->windows_xp_ntvdm) {
3132 cx->windows_springwait = 1;
3136 if (cx->dsp_adpcm > 0) {
3137 if (cx->dsp_record || cx->goldplay_mode)
3140 if (cx->chose_autoinit_dsp) {
3141 if (cx->dsp_adpcm == ADPCM_4BIT)
3142 sndsb_write_dsp(cx,0x7D); /* with ref. byte */
3143 else if (cx->dsp_adpcm == ADPCM_2_6BIT)
3144 sndsb_write_dsp(cx,0x7F); /* with ref. byte */
3145 else if (cx->dsp_adpcm == ADPCM_2BIT)
3146 sndsb_write_dsp(cx,0x1F); /* with ref. byte */
3151 lv = cx->buffer_irq_interval - 1;
3152 if (cx->dsp_adpcm == ADPCM_4BIT)
3153 sndsb_write_dsp(cx,0x75); /* with ref. byte */
3154 else if (cx->dsp_adpcm == ADPCM_2_6BIT)
3155 sndsb_write_dsp(cx,0x77); /* with ref. byte */
3156 else if (cx->dsp_adpcm == ADPCM_2BIT)
3157 sndsb_write_dsp(cx,0x17); /* with ref. byte */
3158 sndsb_write_dsp(cx,lv);
3159 sndsb_write_dsp(cx,lv >> 8);
3162 else if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && cx->dsp_play_method <= SNDSB_DSPOUTMETHOD_3xx) {
3163 unsigned short lv = (cx->buffer_irq_interval * (cx->buffer_stereo?2:1) * (cx->buffer_16bit?2:1)) - 1;
3165 if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
3166 /* ESS 688/1869 chipset specific DSP playback.
3167 using this mode bypasses a lot of the Sound Blaster Pro emulation
3168 and restrictions and allows us to run up to 48KHz 16-bit stereo */
3175 sndsb_interrupt_ack(cx,3);
3177 b = 0x00; /* DMA disable */
3178 b |= (cx->chose_autoinit_dsp) ? 0x04 : 0x00;
3179 b |= (cx->dsp_record) ? 0x0A : 0x00; /* [3]=DMA converter in ADC mode [1]=DMA read for ADC */
3180 if (sndsb_ess_write_controller(cx,0xB8,b) == -1) {
3185 b = sndsb_ess_read_controller(cx,0xA8);
3190 b &= ~0xB; /* clear mono/stereo and record monitor (bits 3, 1, and 0) */
3191 b |= (cx->buffer_stereo?1:2); /* 10=mono 01=stereo */
3192 if (sndsb_ess_write_controller(cx,0xA8,b) == -1) {
3197 /* NTS: The meaning of bits 1:0 in register 0xB9
3199 * 00 single DMA transfer mode
3200 * 01 demand DMA transfer mode, 2 bytes/request
3201 * 10 demand DMA transfer mode, 4 bytes/request
3204 * NOTES on what happens if you set bits 1:0 (DMA transfer type) to the "reserved" 11 value:
3206 * ESS 688 (Sharp laptop) Nothing, apparently. Treated the same as 4 bytes/request
3208 * ESS 1887 (Compaq Presario) Triggers a hardware bug where the chip appears to fetch
3209 * 3 bytes per demand transfer but then only handle 1 byte,
3210 * which translates to audio playing at 3x the sample rate
3211 * it should be. NOT because the DAC is running any faster,
3212 * but because the chip is only playing back every 3rd sample!
3213 * This play only 3rds behavior is consistent across 8/16-bit
3214 * PCM and mono/stereo.
3217 /* TODO: This should be one of the options the user can tinker with for testing! */
3218 if (cx->goldplay_mode)
3219 b = cx->buffer_16bit ? 1 : 0; /* demand transfer DMA 2 bytes (16-bit) or single transfer DMA (8-bit) */
3221 b = 2; /* demand transfer DMA 4 bytes per request */
3223 if (sndsb_ess_write_controller(cx,0xB9,b) == -1) {
3228 if (cx->buffer_rate > 22050) {
3230 * bit 6:0: = sample rate divider
3232 * rate = 795.5KHz / (256 - x) */
3233 b = 256 - (795500UL / (unsigned long)cx->buffer_rate);
3234 if (b < 0x80) b = 0x80;
3238 * bit 6:0: = sample rate divider
3240 * rate = 397.7KHz / (128 - x) */
3241 b = 128 - (397700UL / (unsigned long)cx->buffer_rate);
3244 if (sndsb_ess_write_controller(cx,0xA1,b) == -1) {
3249 b = 256 - (7160000UL / ((unsigned long)cx->buffer_rate * 32UL)); /* 80% of rate/2 times 82 I think... */
3250 if (sndsb_ess_write_controller(cx,0xA2,b) == -1) {
3256 if (sndsb_ess_write_controller(cx,0xA4,t16) == -1 || /* DMA transfer count low */
3257 sndsb_ess_write_controller(cx,0xA5,t16>>8) == -1) { /* DMA transfer count high */
3262 b = sndsb_ess_read_controller(cx,0xB1);
3267 b &= ~0xA0; /* clear compat game IRQ, fifo half-empty IRQs */
3268 b |= 0x50; /* set overflow IRQ, and "no function" */
3269 if (sndsb_ess_write_controller(cx,0xB1,b) == -1) {
3274 b = sndsb_ess_read_controller(cx,0xB2);
3279 b &= ~0xA0; /* clear compat */
3280 b |= 0x50; /* set DRQ/DACKB inputs for DMA */
3281 if (sndsb_ess_write_controller(cx,0xB2,b) == -1) {
3286 b = 0x51; /* enable FIFO+DMA, reserved, load signal */
3287 b |= (cx->buffer_16bit ^ cx->audio_data_flipped_sign) ? 0x20 : 0x00; /* signed complement mode or not */
3288 if (sndsb_ess_write_controller(cx,0xB7,b) == -1) {
3293 b = 0x90; /* enable FIFO+DMA, reserved, load signal */
3294 b |= (cx->buffer_16bit ^ cx->audio_data_flipped_sign) ? 0x20 : 0x00; /* signed complement mode or not */
3295 b |= (cx->buffer_stereo) ? 0x08 : 0x40; /* [3]=stereo [6]=!stereo */
3296 b |= (cx->buffer_16bit) ? 0x04 : 0x00; /* [2]=16bit */
3297 if (sndsb_ess_write_controller(cx,0xB7,b) == -1) {
3302 b = sndsb_ess_read_controller(cx,0xB8);
3307 if (sndsb_ess_write_controller(cx,0xB8,b | 1) == -1) { /* enable DMA */
3313 if (cx->chose_autoinit_dsp) {
3314 /* preparation function has already transmitted block length, use autoinit commands */
3315 if (cx->buffer_hispeed)
3316 sndsb_write_dsp(cx,cx->dsp_record ? 0x98 : 0x90);
3318 sndsb_write_dsp(cx,cx->dsp_record ? 0x2C : 0x1C);
3321 /* send single-cycle command, then transmit length */
3322 if (cx->buffer_hispeed)
3323 sndsb_write_dsp(cx,cx->dsp_record ? 0x99 : 0x91);
3325 sndsb_write_dsp(cx,cx->dsp_record ? 0x24 : 0x14);
3326 sndsb_write_dsp(cx,lv);
3327 sndsb_write_dsp(cx,lv >> 8);
3332 else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_4xx) {
3333 unsigned long lv = (cx->buffer_irq_interval * (cx->buffer_stereo?2:1)) - 1;
3335 if (lv > 65535UL) lv = 65535UL;
3337 sndsb_write_dsp(cx,(cx->buffer_16bit ? 0xB0 : 0xC0) | (cx->chose_autoinit_dsp?0x04:0x00) |
3338 ((!cx->chose_autoinit_dsp && cx->dsp_4xx_fifo_single_cycle) ? 0x02 : 0x00) |
3339 ((cx->chose_autoinit_dsp && cx->dsp_4xx_fifo_autoinit) ? 0x02 : 0x00) |
3340 (cx->dsp_record ? 0x08 : 0x00)); /* bCommand FIFO on */
3341 sndsb_write_dsp(cx,(cx->audio_data_flipped_sign ? 0x10 : 0x00) ^
3342 ((cx->buffer_stereo ? 0x20 : 0x00) | (cx->buffer_16bit ? 0x10 : 0x00))); /* bMode */
3343 sndsb_write_dsp(cx,lv);
3344 sndsb_write_dsp(cx,lv>>8);
3347 cx->timer_tick_signal = 0;
3351 int sndsb_stop_dsp_playback(struct sndsb_ctx *cx) {
3352 cx->gold_memcpy = 0;
3353 cx->dsp_stopping = 1;
3354 cx->windows_springwait = 0;
3355 cx->timer_tick_func = NULL;
3356 if (cx->direct_dac_sent_command) {
3360 sndsb_write_dsp(cx,0x80);
3362 cx->direct_dac_sent_command = 0;
3365 /* NTS: As far as I can tell, the best way to stop the sound card is just reset the DSP.
3366 * The "Exit auto-init" commands don't seem to work */
3367 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx)
3368 sndsb_reset_dsp(cx);
3369 if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_3xx && cx->dsp_record)
3370 sndsb_write_dsp(cx,0xA0);
3372 if ((cx->buffer_16bit && cx->dma16 >= 0) || (!cx->buffer_16bit && cx->dma8 >= 0)) {
3374 unsigned int nonmove = 0;
3375 /* wait for the DMA channel to stop moving */
3376 if (cx->buffer_16bit) cr = d8237_read_count(cx->dma16);
3377 else cr = d8237_read_count(cx->dma8);
3379 t8254_wait(t8254_us2ticks(10000)); /* 10ms */
3381 if (cx->buffer_16bit) cr = d8237_read_count(cx->dma16);
3382 else cr = d8237_read_count(cx->dma8);
3383 if (pr == cr) nonmove++;
3385 } while (nonmove < 3);
3388 if (cx->dsp_play_method > SNDSB_DSPOUTMETHOD_DIRECT) {
3389 sndsb_shutdown_dma(cx);
3390 sndsb_write_mixer(cx,0x0E,0);
3393 cx->timer_tick_signal = 0;
3394 sndsb_write_dsp(cx,0xD3); /* turn off speaker */
3396 if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
3399 b = sndsb_ess_read_controller(cx,0xB8);
3401 b &= ~0x01; /* stop DMA */
3402 sndsb_ess_write_controller(cx,0xB8,b);
3409 void sndsb_send_buffer_again(struct sndsb_ctx *cx) {
3413 if (cx->dsp_stopping) return;
3414 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) return;
3415 ch = cx->buffer_16bit ? cx->dma16 : cx->dma8;
3417 if (!cx->chose_autoinit_dma)
3418 outp(d8237_ioport(ch,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(ch) | D8237_MASK_SET); /* mask */
3420 /* ESS chipsets: I believe the reason non-auto-init DMA+DSP is halting is because
3421 * we first needs to stop DMA on the chip THEN reprogram the DMA controller.
3422 * Perhaps the FIFO is hardwired to refill at all times and reprogramming the
3423 * DMA controller THEN twiddling the DMA enable opens a window of opportunity
3424 * for refill to happen at the wrong time? */
3425 if (!cx->chose_autoinit_dsp) {
3426 if (cx->dsp_adpcm > 0) {
3428 else if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
3432 b = sndsb_ess_read_controller(cx,0xB8);
3433 sndsb_ess_write_controller(cx,0xB8,b & ~1);
3437 /* if we're doing it the non-autoinit method, then we
3438 also need to update the DMA pointer */
3439 if (!cx->chose_autoinit_dma) {
3440 unsigned long npos = cx->buffer_dma_started;
3441 unsigned long rem = cx->buffer_dma_started;
3443 lv = cx->buffer_irq_interval;
3444 if (cx->dsp_adpcm == 0) {
3445 if (cx->buffer_16bit) lv <<= 1UL;
3446 if (cx->buffer_stereo) lv <<= 1UL;
3449 if (cx->backwards) {
3451 npos = cx->buffer_size - lv;
3452 rem = cx->buffer_size;
3455 if (npos >= lv) npos -= lv;
3460 npos += cx->buffer_dma_started_length;
3462 if (npos >= cx->buffer_size) {
3466 else if (rem > cx->buffer_size) {
3467 rem = cx->buffer_size;
3471 cx->buffer_dma_started = npos;
3472 cx->buffer_dma_started_length = lv = rem - npos;
3474 d8237_write_base(ch,cx->buffer_phys+cx->buffer_dma_started+cx->buffer_dma_started_length-1); /* RAM location with not much around */
3476 d8237_write_base(ch,cx->buffer_phys+cx->buffer_dma_started); /* RAM location with not much around */
3477 d8237_write_count(ch,cx->buffer_dma_started_length);
3478 outp(d8237_ioport(ch,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(ch)); /* unmask */
3482 lv = cx->buffer_irq_interval;
3483 if (cx->dsp_adpcm == 0) {
3484 if (cx->buffer_16bit) lv <<= 1UL;
3485 if (cx->buffer_stereo) lv <<= 1UL;
3490 /* if we're doing the one-block-at-a-time 1.xx method, then start another right now */
3491 if (!cx->chose_autoinit_dsp) {
3492 if (cx->dsp_adpcm > 0) {
3493 if (cx->dsp_adpcm == ADPCM_4BIT)
3494 sndsb_write_dsp(cx,0x74); /* without ref. byte */
3495 else if (cx->dsp_adpcm == ADPCM_2_6BIT)
3496 sndsb_write_dsp(cx,0x76); /* without ref. byte */
3497 else if (cx->dsp_adpcm == ADPCM_2BIT)
3498 sndsb_write_dsp(cx,0x16); /* without ref. byte */
3499 sndsb_write_dsp(cx,lv);
3500 sndsb_write_dsp(cx,lv >> 8);
3502 else if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_1xx && cx->dsp_play_method <= SNDSB_DSPOUTMETHOD_3xx) {
3503 /* send single-cycle command, then transmit length */
3504 if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
3509 sndsb_ess_write_controller(cx,0xA4,t16); /* DMA transfer count low */
3510 sndsb_ess_write_controller(cx,0xA5,t16>>8); /* DMA transfer count high */
3512 /* start DMA again */
3513 b = sndsb_ess_read_controller(cx,0xB8);
3514 sndsb_ess_write_controller(cx,0xB8,b | 1);
3517 if (cx->buffer_hispeed) {
3518 sndsb_write_dsp_blocksize(cx,lv+1);
3519 sndsb_write_dsp(cx,cx->dsp_record ? 0x99 : 0x91);
3522 sndsb_write_dsp(cx,cx->dsp_record ? 0x24 : 0x14);
3523 sndsb_write_dsp(cx,lv);
3524 sndsb_write_dsp(cx,lv >> 8);
3528 else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_4xx) {
3530 if (cx->buffer_16bit) lv >>= 1UL;
3532 sndsb_write_dsp(cx,(cx->buffer_16bit ? 0xB0 : 0xC0) | (cx->chose_autoinit_dsp?0x04:0x00) |
3533 ((!cx->chose_autoinit_dsp && cx->dsp_4xx_fifo_single_cycle) ? 0x02 : 0x00) |
3534 ((cx->chose_autoinit_dsp && cx->dsp_4xx_fifo_autoinit) ? 0x02 : 0x00) |
3535 (cx->dsp_record ? 0x08 : 0x00)); /* bCommand FIFO on */
3536 sndsb_write_dsp(cx,(cx->audio_data_flipped_sign ? 0x10 : 0x00) ^
3537 ((cx->buffer_stereo ? 0x20 : 0x00) | (cx->buffer_16bit ? 0x10 : 0x00))); /* bMode */
3538 sndsb_write_dsp(cx,lv);
3539 sndsb_write_dsp(cx,lv>>8);
3544 void sndsb_choose_mixer(struct sndsb_ctx *card,signed char override) {
3547 card->sb_mixer_items = 0;
3548 card->sb_mixer = NULL;
3549 idx = override >= 0 ? override : card->mixer_chip;
3551 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
3553 if (idx == SNDSB_MIXER_CT1335) {
3554 card->sb_mixer = sndsb_mixer_ct1335;
3555 card->sb_mixer_items = (signed short)(sizeof(sndsb_mixer_ct1335) / sizeof(struct sndsb_mixer_control));
3557 else if (idx == SNDSB_MIXER_CT1345) {
3558 card->sb_mixer = sndsb_mixer_ct1345;
3559 card->sb_mixer_items = (signed short)(sizeof(sndsb_mixer_ct1345) / sizeof(struct sndsb_mixer_control));
3561 else if (idx == SNDSB_MIXER_CT1745) {
3562 card->sb_mixer = sndsb_mixer_ct1745;
3563 card->sb_mixer_items = (signed short)(sizeof(sndsb_mixer_ct1745) / sizeof(struct sndsb_mixer_control));
3568 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
3569 /* CUT ADPCM encoding */
3571 /* NTS: This is the best documentation I could fine regarding the Sound Blaster ADPCM format.
3572 * Tables and method taken from DOSBox 0.74 SB emulation. The information on multimedia.cx's
3574 unsigned char sndsb_encode_adpcm_4bit(unsigned char samp) {
3575 static const signed char scaleMap[64] = {
3576 0, 1, 2, 3, 4, 5, 6, 7, 0, -1, -2, -3, -4, -5, -6, -7,
3577 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15,
3578 2, 6, 10, 14, 18, 22, 26, 30, -2, -6, -10, -14, -18, -22, -26, -30,
3579 4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
3581 static const signed char adjustMap[32] = {
3582 0, 0, 0, 0, 0, 1, 1, 1,
3583 -1, 0, 0, 0, 0, 1, 1, 1,
3584 -1, 0, 0, 0, 0, 1, 1, 1,
3585 -1, 0, 0, 0, 0, 0, 0, 0
3587 signed int sdelta = (signed int)((signed char)(samp - adpcm_pred));
3588 unsigned char sign = 0;
3590 sdelta = (sdelta * 2) + (adpcm_step < 3 ? adpcm_error : 0);
3591 adpcm_error = sdelta & ((1 << (adpcm_step + 1)) - 1);
3592 sdelta >>= adpcm_step+1;
3597 if (sdelta > 7) sdelta = 7;
3598 adpcm_pred += scaleMap[(adpcm_step*16)+sign+sdelta];
3599 if (adpcm_pred < 0) adpcm_pred = 0;
3600 else if (adpcm_pred > 0xFF) adpcm_pred = 0xFF;
3601 adpcm_step += adjustMap[(adpcm_step*8)+sdelta];
3602 if ((signed char)adpcm_step < 0) adpcm_step = 0;
3603 if (adpcm_step > 3) adpcm_step = 3;
3604 return (unsigned char)sdelta | sign;
3607 /* NTS: This is the best documentation I could fine regarding the Sound Blaster ADPCM format.
3608 * Tables and method taken from DOSBox 0.74 SB emulation. The information on multimedia.cx's
3610 unsigned char sndsb_encode_adpcm_2bit(unsigned char samp) {
3611 static const signed char scaleMap[24] = {
3612 0, 1, 0, -1, 1, 3, -1, -3,
3613 2, 6, -2, -6, 4, 12, -4, -12,
3614 8, 24, -8, -24, 16, 48, -16, -48
3615 /* NTS: This table is correct as tested against real Creative SB
3616 hardware. DOSBox's version has a typo on the last row
3617 that will make the 2-bit playback sound WORSE in it. */
3619 static const signed char adjustMap[12] = {
3624 signed int sdelta = (signed int)((signed char)(samp - adpcm_pred));
3625 unsigned char sign = 0;
3627 sdelta = (sdelta * 2) + (adpcm_step == 0 ? adpcm_error : 0);
3628 adpcm_error = sdelta & ((1 << adpcm_step) - 1);
3629 sdelta >>= adpcm_step+1;
3636 /* "ring" suppression */
3637 if (adpcm_step == 5 && sdelta == 1 && adpcm_last == 3 && sign == 0)
3640 if (sdelta > 1) sdelta = 1;
3641 adpcm_last = sdelta + sign;
3642 adpcm_pred += scaleMap[(adpcm_step*4)+sign+sdelta];
3643 if (adpcm_pred < 0) adpcm_pred = 0;
3644 else if (adpcm_pred > 0xFF) adpcm_pred = 0xFF;
3645 adpcm_step += adjustMap[(adpcm_step*2)+sdelta];
3646 if ((signed char)adpcm_step < 0) adpcm_step = 0;
3647 if (adpcm_step > 5) adpcm_step = 5;
3648 return (unsigned char)sdelta | sign;
3651 /* NTS: This is the best documentation I could fine regarding the Sound Blaster ADPCM format.
3652 * Tables and method taken from DOSBox 0.74 SB emulation. The information on multimedia.cx's
3654 unsigned char sndsb_encode_adpcm_2_6bit(unsigned char samp,unsigned char b2) {
3655 static const signed char scaleMap[40] = {
3656 0, 1, 2, 3, 0, -1, -2, -3,
3657 1, 3, 5, 7, -1, -3, -5, -7,
3658 2, 6, 10, 14, -2, -6, -10, -14,
3659 4, 12, 20, 28, -4, -12, -20, -28,
3660 5, 15, 25, 35, -5, -15, -25, -35
3662 static const signed char adjustMap[20] = {
3669 signed int sdelta = (signed int)((signed char)(samp - adpcm_pred));
3670 unsigned char sign = 0;
3672 sdelta = (sdelta * 2) + (adpcm_step < 2 ? adpcm_error : 0);
3673 adpcm_error = sdelta & ((1 << (adpcm_step + (b2 ? 2 : 1))) - 1);
3674 sdelta >>= adpcm_step+1;
3681 if (sdelta > 3) sdelta = 3;
3683 if (b2) sdelta &= 0x6;
3684 adpcm_pred += scaleMap[(adpcm_step*8)+sdelta];
3685 if (adpcm_pred < 0) adpcm_pred = 0;
3686 else if (adpcm_pred > 0xFF) adpcm_pred = 0xFF;
3687 adpcm_step += adjustMap[(adpcm_step*4)+(sdelta&3)];
3688 if ((signed char)adpcm_step < 0) adpcm_step = 0;
3689 if (adpcm_step > 5) adpcm_step = 5;
3690 return (unsigned char)sdelta;
3693 void sndsb_encode_adpcm_set_reference(unsigned char c,unsigned char mode) {
3696 if (mode == ADPCM_4BIT)
3698 else if (mode == ADPCM_2_6BIT)
3700 else if (mode == ADPCM_2BIT)
3704 /* undocumented and not properly emulated by DOSBox either:
3705 when Creative said the non-reference ADPCM commands "continue
3706 using accumulated reference byte" they apparently meant that
3707 it resets the step value to max. Yes, even in auto-init
3708 ADPCM mode. Failure to follow this results in audible
3709 "fluttering" once per IRQ. */
3710 void sndsb_encode_adpcm_reset_wo_ref(unsigned char mode) {
3711 if (mode == ADPCM_4BIT)
3713 else if (mode == ADPCM_2_6BIT)
3716 adpcm_step = 5; /* FIXME: Testing by ear seems to favor this one. Is this correct? */
3720 void sndsb_write_mixer_entry(struct sndsb_ctx *sb,struct sndsb_mixer_control *mc,unsigned char nb) {
3722 if (mc->length == 0) return;
3723 else if (mc->length == 8) {
3724 sndsb_write_mixer(sb,mc->index,nb);
3727 b = sndsb_read_mixer(sb,mc->index);
3728 b &= ~(((1 << mc->length) - 1) << mc->offset);
3729 b |= (nb & ((1 << mc->length) - 1)) << mc->offset;
3730 sndsb_write_mixer(sb,mc->index,b);
3734 unsigned char sndsb_read_mixer_entry(struct sndsb_ctx *sb,struct sndsb_mixer_control *mc) {
3736 if (mc->length == 0) return 0;
3737 b = sndsb_read_mixer(sb,mc->index);
3738 return (b >> mc->offset) & ((1 << mc->length) - 1);
3741 int sndsb_assign_dma_buffer(struct sndsb_ctx *cx,struct dma_8237_allocation *dma) {
3742 cx->buffer_size = dma->length;
3743 cx->buffer_phys = dma->phys;
3744 cx->buffer_lin = dma->lin;
3748 uint32_t sndsb_recommended_dma_buffer_size(struct sndsb_ctx *ctx,uint32_t limit) {
3749 uint32_t ret = 60UL * 1024UL;
3750 if (limit != 0UL && ret > limit) ret = limit;
3752 /* Known constraint: Windows 3.1 Creative SB16 drivers don't like it when DOS apps
3753 * use too large a DMA buffer. It causes Windows to complain about
3754 * "a DOS program violating the integrity of the operating system".
3756 * FIXME: Even with small buffers, it "violates the integrity" anyway.
3757 * So what the fuck is wrong then? */
3758 if (windows_mode == WINDOWS_ENHANCED && windows_version < 0x35F && /* Windows 3.1 and Creative SB16 drivers v3.57 */
3759 ctx->windows_creative_sb16_drivers && ctx->windows_creative_sb16_drivers_ver == (0x300 + 57)) {
3760 if (ret > (4UL * 1024UL)) ret = 4UL * 1024UL;