]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/sndsb/sndsb.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / sndsb / sndsb.c
1 /* FIXME: This code is failing to detect that it's running under the latest (4.3) VirtualBox. Why? */
2
3 /* TODO: Add a flag to the sound blaster context to track whether or not DSP playback/record is active. */
4
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
7  *       do full duplex. */
8
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. */
13
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. */
18
19 /* FIXME: There might be a way to deal with some troubles you've been having with this code:
20  *
21  *        Troubles:
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.
30  *
31  *        Things to do:
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?] */
42
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 */
47
48 #include <stdio.h>
49 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
50 #include <stdlib.h>
51 #include <string.h>
52 #include <unistd.h>
53 #include <malloc.h>
54 #include <assert.h>
55 #include <fcntl.h>
56 #include <dos.h>
57
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>
67
68 /* Windows 9x VxD enumeration */
69 #include <windows/w9xvmm/vxd_enum.h>
70
71 /* uncomment this to enable debugging messages */
72 //#define DBG
73
74 #if defined(DBG)
75 # define DEBUG(x) (x)
76 #else
77 # define DEBUG(x)
78 #endif
79
80 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
81 /* cut */
82 #else
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;
88 #endif
89
90 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
91 /* cut */
92 #else
93 /* CT1335 */
94 struct sndsb_mixer_control sndsb_mixer_ct1335[] = {
95 /*      index, of,ln,name */
96         {0x02, 1, 3, "Master"},
97         {0x06, 1, 3, "MIDI"},
98         {0x08, 1, 3, "CD"},
99         {0x0A, 1, 2, "Voice"}
100 };
101
102 /* CT1345 */
103 struct sndsb_mixer_control sndsb_mixer_ct1345[] = {
104 /*      index, of,ln,name */
105         {0x04, 1, 3, "Voice R"},                {0x04, 5, 3, "Voice L"},
106         {0x0A, 1, 2, "Mic"},
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"}
113 };
114
115 /* CT1745 */
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"},
123         {0x3A, 3, 5, "Mic"},
124         {0x3B, 6, 2, "PC speaker"},
125
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"},
131
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"},
139
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"},
147
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"},
152         {0x43, 0, 1, "AGC"},
153         {0x44, 4, 4, "Treble L"},
154         {0x45, 4, 4, "Treble R"},
155         {0x46, 4, 4, "Bass L"},
156         {0x47, 4, 4, "Bass R"}
157 };
158 #endif
159
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};
162
163 const char* sndsb_adpcm_mode_str[4] = {
164         "none",
165         "ADPCM 4-bit",
166         "ADPCM 2.6-bit",
167         "ADPCM 2-bit"
168 };
169
170 const char *sndsb_mixer_chip_name[SNDSB_MIXER_MAX] = {
171         "none",
172         "CT1335",
173         "CT1345",
174         "CT1745"
175 };
176
177 const char *sndsb_dspoutmethod_str[SNDSB_DSPOUTMETHOD_MAX] = {
178         "direct",
179         "1.xx",
180         "2.00",
181         "2.01",
182         "3.xx",
183         "4.xx"
184 };
185
186 const char *sndsb_ess_chipsets_str[SNDSB_ESS_MAX] = {
187         "none",
188         "ESS688",
189         "ESS1869"
190 };
191
192 #if TARGET_MSDOS == 32
193 signed char                     sndsb_nmi_32_hook = -1;
194 #endif
195
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;
200
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];
204 }
205
206 void sndsb_timer_tick_gen(struct sndsb_ctx *cx) {
207         cx->timer_tick_signal = 1;
208 }
209
210 static inline void sndsb_timer_tick_directio_post_read(unsigned short port,unsigned short count) {
211         while (count-- != 0) inp(port);
212 }
213
214 static inline unsigned char sndsb_timer_tick_directio_poll_ready(unsigned short port,unsigned short count) {
215         unsigned char r = 0;
216
217         do { r = inp(port);
218         } while ((r&0x80) && count-- != 0);
219
220         return !(r&0x80);
221 }
222
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);
226                 if (cx->backwards) {
227                         if (cx->direct_dsp_io == 0) cx->direct_dsp_io = cx->buffer_size - 1;
228                         else cx->direct_dsp_io--;
229                 }
230                 else {
231                         if ((++cx->direct_dsp_io) >= cx->buffer_size) cx->direct_dsp_io = 0;
232                 }
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);
236         }
237 }
238
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);
245         }
246 }
247
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]);
251                 if (cx->backwards) {
252                         if (cx->direct_dsp_io == 0) cx->direct_dsp_io = cx->buffer_size - 1;
253                         else cx->direct_dsp_io--;
254                 }
255                 else {
256                         if ((++cx->direct_dsp_io) >= cx->buffer_size) cx->direct_dsp_io = 0;
257                 }
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);
261         }
262 }
263
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);
270         }
271 }
272
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);
277 #else
278         _fmemcpy(cx->buffer_lin+cx->direct_dsp_io,cx->goldplay_dma,cx->gold_memcpy);
279 #endif
280         if (cx->backwards) {
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;
283         }
284         else {
285                 if ((cx->direct_dsp_io += cx->gold_memcpy) >= cx->buffer_size) cx->direct_dsp_io = 0;
286         }
287 }
288
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);
293 #else
294         _fmemcpy(cx->goldplay_dma,cx->buffer_lin+cx->direct_dsp_io,cx->gold_memcpy);
295 #endif
296         if (cx->backwards) {
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;
299         }
300         else {
301                 if ((cx->direct_dsp_io += cx->gold_memcpy) >= cx->buffer_size) cx->direct_dsp_io = 0;
302         }
303 }
304
305 struct sndsb_ctx *sndsb_by_base(uint16_t x) {
306         int i;
307
308         for (i=0;i < SNDSB_MAX_CARDS;i++) {
309                 if (sndsb_card[i].baseio == x)
310                         return sndsb_card+i;
311         }
312
313         return 0;
314 }
315
316 struct sndsb_ctx *sndsb_by_mpu(uint16_t x) {
317         int i;
318
319         for (i=0;i < SNDSB_MAX_CARDS;i++) {
320                 if (sndsb_card[i].mpuio == x)
321                         return sndsb_card+i;
322         }
323
324         return 0;
325 }
326
327 struct sndsb_ctx *sndsb_by_irq(int8_t x) {
328         int i;
329
330         for (i=0;i < SNDSB_MAX_CARDS;i++) {
331                 if (sndsb_card[i].irq == x)
332                         return sndsb_card+i;
333         }
334
335         return 0;
336 }
337
338 struct sndsb_ctx *sndsb_by_dma(uint16_t x) {
339         int i;
340
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))
343                         return sndsb_card+i;
344         }
345
346         return 0;
347 }
348
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;
353
354         /* auto-detect SBOS/MEGA-EM and enable nmi reflection if present */
355         if (gravis_mega_em_detect(&megaem_info) || gravis_sbos_detect() >= 0)
356                 return 1;
357
358         return 0;
359 }
360 #endif
361
362 void free_sndsb() {
363 #if TARGET_MSDOS == 32
364         if (sndsb_nmi_32_hook) do_nmi_32_unhook();
365 #endif
366 }
367
368 int init_sndsb() {
369         int i;
370
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;
374
375         sndsb_card_blaster = NULL;
376         sndsb_card_next = 0;
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();
380 #endif
381         return 1;
382 }
383
384 struct sndsb_ctx *sndsb_alloc_card() {
385         int i;
386
387         for (i=0;i < SNDSB_MAX_CARDS;i++) {
388                 if (sndsb_card[i].baseio == 0 && sndsb_card[i].mpuio == 0)
389                         return sndsb_card+i;
390         }
391
392         return NULL;
393 }
394
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;
400         }
401 #endif
402         memset(c,0,sizeof(*c));
403         c->pnp_bios_node = 0xFF;
404         if (c == sndsb_card_blaster) sndsb_card_blaster = NULL;
405 }
406
407 struct sndsb_ctx *sndsb_try_blaster_var() {
408         int A=-1,I=-1,D=-1,H=-1,P=-1;
409         struct sndsb_ctx *e;
410         char *s;
411
412         if (sndsb_card_blaster != NULL)
413                 return sndsb_card_blaster;
414
415         /* some of our detection relies on knowing what OS we're running under */
416         cpu_probe();
417         probe_dos();
418         detect_windows();
419
420         s = getenv("BLASTER");
421         if (s == NULL) return NULL;
422
423         while (*s != 0) {
424                 if (*s == ' ') {
425                         s++;
426                         continue;
427                 }
428
429                 if (*s == 'A') {
430                         s++;
431                         A = strtol(s,&s,16);
432                 }
433                 else if (*s == 'P') {
434                         s++;
435                         P = strtol(s,&s,16);
436                 }
437                 else if (*s == 'I') {
438                         s++;
439                         I = strtol(s,&s,10);
440                 }
441                 else if (*s == 'D') {
442                         s++;
443                         D = strtol(s,&s,10);
444                 }
445                 else if (*s == 'H') {
446                         s++;
447                         H = strtol(s,&s,10);
448                 }
449                 else {
450                         while (*s && *s != ' ') s++;
451                         while (*s == ' ') s++;
452                 }
453         }
454
455         if (A < 0 || I < 0 || D < 0 || I > 15 || D > 7)
456                 return NULL;
457
458         if (sndsb_by_base(A) != NULL)
459                 return 0;
460
461         e = sndsb_alloc_card();
462         if (e == NULL) return NULL;
463 #if TARGET_MSDOS == 32
464         e->goldplay_dma = NULL;
465 #endif
466         e->is_gallant_sc6600 = 0;
467         e->baseio = (uint16_t)A;
468         e->mpuio = (uint16_t)(P > 0 ? P : 0);
469         e->dma8 = (int8_t)D;
470         e->dma16 = (int8_t)H;
471         e->irq = (int8_t)I;
472         e->dsp_vmaj = 0;
473         e->dsp_vmin = 0;
474         e->mixer_ok = 0;
475         e->mpu_ok = 0;
476         e->dsp_ok = 0;
477         return (sndsb_card_blaster=e);
478 }
479
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];
483 }
484
485 /* NTS: this function enforces a timeout of 250ms */
486 int sndsb_read_dsp(struct sndsb_ctx *cx) {
487         unsigned int patience = 25000;
488         int c = -1;
489
490         do {
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);
493                         break;
494                 }
495
496                 t8254_wait(t8254_us2ticks(10));
497                 if (--patience == 0) {
498                         DEBUG(fprintf(stdout,"sndsb_read_dsp() read timeout\n"));
499                         return -1;
500                 }
501         } while (1);
502
503         DEBUG(fprintf(stdout,"sndsb_read_dsp() == 0x%02X\n",c));
504         return c;
505 }
506
507 int sndsb_read_dsp_timeout(struct sndsb_ctx *cx,unsigned long timeout_ms) {
508         unsigned int patience = (unsigned int)(timeout_ms / 10UL);
509         int c = -1;
510
511         do {
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);
514                         break;
515                 }
516
517                 t8254_wait(t8254_us2ticks(10));
518                 if (--patience == 0) {
519                         DEBUG(fprintf(stdout,"sndsb_read_dsp() read timeout\n"));
520                         return -1;
521                 }
522         } while (1);
523
524         DEBUG(fprintf(stdout,"sndsb_read_dsp() == 0x%02X\n",c));
525         return c;
526 }
527
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;
532
533         if (!sndsb_write_dsp(cx,enable?0xC6:0xC7))
534                 return 0;
535
536         cx->ess_extended_mode = !!enable;
537         return 1;
538 }
539
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);
549 }
550
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;
556         return 0;
557 }
558
559 int sndsb_reset_dsp(struct sndsb_ctx *cx) {
560         if (cx->baseio == 0) {
561                 DEBUG(fprintf(stdout,"BUG: sndsb baseio == 0\n"));
562                 return 0;
563         }
564
565         /* DSP reset takes the ESS out of extended mode */
566         if (cx->ess_chipset != 0)
567                 cx->ess_extended_mode = 0;
568
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 */
574         else
575                 outp(cx->baseio+SNDSB_BIO_DSP_RESET,1); /* normal reset */
576
577         t8254_wait(t8254_us2ticks(1000));       /* be safe and wait 1ms */
578         outp(cx->baseio+SNDSB_BIO_DSP_RESET,0);
579
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"));
585                         return 0;
586                 }
587         }
588
589         return 1;
590 }
591
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);
595 }
596
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);
600 }
601
602 unsigned char sndsb_test_write_mixer(struct sndsb_ctx *cx,uint8_t i,uint8_t d) {
603         unsigned char o,c;
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);
606         return c;
607 }
608
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) {
613         cx->mixer_chip = 0;
614
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;
621         }
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;
626         }
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;
631         }
632
633         sndsb_choose_mixer(cx,-1);
634         return (cx->mixer_chip != 0);
635 }
636
637 int sndsb_mpu_command(struct sndsb_ctx *cx,uint8_t d) {
638         unsigned int patience = 100;
639
640         do {
641                 if (inp(cx->mpuio+SNDSB_MPUIO_STATUS) & 0x40) /* if not ready for cmd, wait and try again */
642                         t8254_wait(t8254_us2ticks(100));
643                 else {
644                         outp(cx->mpuio+SNDSB_MPUIO_COMMAND,d);
645                         return 1;
646                 }
647         } while (--patience != 0);
648         return 0;
649 }
650
651 int sndsb_mpu_write(struct sndsb_ctx *cx,uint8_t d) {
652         unsigned int patience = 100;
653
654         do {
655                 if (inp(cx->mpuio+SNDSB_MPUIO_STATUS) & 0x40) /* if not ready for cmd, wait and try again */
656                         t8254_wait(t8254_us2ticks(100));
657                 else {
658                         outp(cx->mpuio+SNDSB_MPUIO_DATA,d);
659                         return 1;
660                 }
661         } while (--patience != 0);
662         return 0;
663 }
664
665 int sndsb_mpu_read(struct sndsb_ctx *cx) {
666         unsigned int patience = 100;
667
668         do {
669                 if (inp(cx->mpuio+SNDSB_MPUIO_STATUS) & 0x80) /* if data ready not ready, wait and try again */
670                         t8254_wait(t8254_us2ticks(100));
671                 else {
672                         return inp(cx->mpuio+SNDSB_MPUIO_DATA);
673                 }
674         } while (--patience != 0);
675
676         return -1;
677 }
678
679 /* this code makes sure the MPU exists */
680 int sndsb_probe_mpu401(struct sndsb_ctx *cx) {
681         unsigned int patience = 10;
682         int c;
683
684         if (cx->mpuio == 0) return 0;
685
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)
693                                 break;
694
695                         if (--patience == 0) return 0;
696                         t8254_wait(t8254_us2ticks(100)); /* 100us */
697                 } while(1);
698         }
699
700         patience=3;
701         do {
702                 /* OK we got the status register to return something other than 0xFF.
703                  * Issue a reset */
704                 if (sndsb_mpu_command(cx,0xFF)) {
705                         if ((c=sndsb_mpu_read(cx)) == 0xFE) {
706                                 break;
707                         }
708                 }
709
710                 if (--patience == 0)
711                         return 0;
712
713                 t8254_wait(t8254_us2ticks(10)); /* 10us */
714         } while (1);
715
716         return 1;
717 }
718
719 int sndsb_write_dsp(struct sndsb_ctx *cx,uint8_t d) {
720         unsigned int patience = 25000;
721
722         DEBUG(fprintf(stdout,"sndsb_write_dsp(0x%02X)\n",d));
723         do {
724                 if (inp(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0)) & 0x80)
725                         t8254_wait(t8254_us2ticks(10));
726                 else {
727                         outp(cx->baseio+SNDSB_BIO_DSP_WRITE_DATA+(cx->dsp_alias_port?1:0),d);
728                         return 1;
729                 }
730         } while (--patience != 0);
731         DEBUG(fprintf(stdout,"sndsb_write_dsp() timeout\n"));
732         return 0;
733 }
734
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);
737
738         DEBUG(fprintf(stdout,"sndsb_write_dsp(0x%02X)\n",d));
739         do {
740                 if (inp(cx->baseio+SNDSB_BIO_DSP_WRITE_STATUS+(cx->dsp_alias_port?1:0)) & 0x80)
741                         t8254_wait(t8254_us2ticks(10));
742                 else {
743                         outp(cx->baseio+SNDSB_BIO_DSP_WRITE_DATA+(cx->dsp_alias_port?1:0),d);
744                         return 1;
745                 }
746         } while (--patience != 0);
747         DEBUG(fprintf(stdout,"sndsb_write_dsp() timeout\n"));
748         return 0;
749 }
750
751 int sndsb_write_dsp_timeconst(struct sndsb_ctx *cx,uint8_t tc) {
752         if (!sndsb_write_dsp(cx,0x40))
753                 return 0;
754         if (!sndsb_write_dsp(cx,tc))
755                 return 0;
756         return 1;
757 }
758
759 int sndsb_query_dsp_version(struct sndsb_ctx *cx) {
760         int a,b;
761
762         if (!sndsb_write_dsp(cx,SNDSB_DSPCMD_GET_VERSION))
763                 return 0;
764
765         if ((a=sndsb_read_dsp(cx)) < 0)
766                 return 0;
767         if ((b=sndsb_read_dsp(cx)) < 0)
768                 return 0;
769         if (a == 0xFF || b == 0xFF)
770                 return 0;
771
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));
775         return 1;
776 }
777
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 */
784         cpu_probe();
785         probe_dos();
786         detect_windows();
787
788 #if TARGET_MSDOS == 32
789         cx->goldplay_dma = NULL;
790 #endif
791         cx->backwards = 0;
792         cx->ess_chipset = 0;
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;
831         cx->vdmsound = 0;
832         cx->mega_em = 0;
833         cx->sbos = 0;
834         cx->mpu_ok = 0;
835         cx->dsp_ok = 0;
836         cx->mixer_ok = 0;
837         cx->dsp_vmaj = 0;
838         cx->dsp_vmin = 0;
839         cx->buffer_phys = 0;
840         cx->buffer_lin = NULL;
841         cx->buffer_rate = 22050;
842         cx->enable_adpcm_autoinit = 0;
843         cx->dsp_adpcm = 0;
844         cx->dsp_record = 0;
845         cx->sb_mixer_items = 0;
846         cx->sb_mixer = NULL;
847         cx->max_sample_rate_sb_play_dac = 23000;
848         cx->max_sample_rate_sb_rec_dac = 13000;
849
850         if (!sndsb_reset_dsp(cx)) return 0;
851         cx->dsp_ok = 1;
852
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))
858                         cx->dsp_ok = 0;
859         }
860
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! */
868
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!
872
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
878                 by MEGA-EM. */
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. */
887                         cx->mega_em = 1;
888                         cx->dsp_autoinit_dma = 0;
889                         strcpy(cx->dsp_copyright,"Gravis MEGA-EM");
890                 }
891         }
892
893         /* if the DSP is recent enough, it might have a copyright string.
894
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,
900            etc. */
901         if (!cx->mega_em && cx->dsp_vmaj >= 2) {
902                 int i,c;
903
904                 sndsb_write_dsp(cx,0xE3);
905                 for (i=0;i < (sizeof(cx->dsp_copyright)-1);i++) {
906                         c = sndsb_read_dsp(cx);
907                         if (c < 0) break;
908                         cx->dsp_copyright[i] = (char)c;
909                         if (c == 0) break;
910                 }
911                 cx->dsp_copyright[i] = (char)0;
912                 DEBUG(fprintf(stdout,"sndsb_init_card() copyright == '%s'\n",cx->dsp_copyright));
913
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)
920                                         c++;
921                                 else
922                                         break;
923                         }
924
925                         if (c == i) {
926                                 if (gravis_sbos_detect() >= 0) { /* is that you, SBOS? */
927                                         strcpy(cx->dsp_copyright,"Gravis SBOS");
928                                         cx->dsp_autoinit_dma = 0;
929                                         cx->sbos = 1;
930                                 }
931                         }
932                 }
933         }
934
935         if (sndsb_probe_mixer(cx)) /* NTS: Don't reset the mixer, just probe it */
936                 cx->mixer_ok = 1;
937
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;
948
949                         cx->do_not_probe_irq = 1;
950                 }
951                 if (dmam != 0xFF && dmam != 0x00) {
952                         if (cx->dma8 < 0) {
953                                 if (dmam & 8)           cx->dma8 = 3;
954                                 else if (dmam & 2)      cx->dma8 = 1;
955                                 else if (dmam & 1)      cx->dma8 = 0;
956                         }
957
958                         if (cx->dma16 < 0) {
959                                 if (dmam & 0x80)        cx->dma16 = 7;
960                                 else if (dmam & 0x40)   cx->dma16 = 6;
961                                 else if (dmam & 0x20)   cx->dma16 = 5;
962                         }
963
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" */
968                         if (cx->dma16 == -1)
969                                 cx->dma16 = cx->dma8;
970
971                         cx->do_not_probe_dma = 1;
972                 }
973         }
974
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.
985          *
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)) {
993                         unsigned char a,b,c;
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 */
1006                                         if (cx->dma8 < 0)
1007                                                 cx->dma8 = gallant_sc6600_map_to_dma[c&3];
1008                                         if (cx->dma16 < 0)
1009                                                 cx->dma16 = cx->dma8;
1010                                         if (cx->irq < 0)
1011                                                 cx->irq = gallant_sc6600_map_to_irq[(c>>3)&7];
1012
1013                                         cx->do_not_probe_irq = 1;
1014                                         cx->do_not_probe_dma = 1;
1015                                 }
1016                         }
1017                 }
1018         }
1019
1020 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
1021         /* trimmed to keep total code <= 64KB */
1022 #else
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. */
1027
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");
1033                 }
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? */
1036                 else {
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]";
1041
1042                         cx->vdmsound = 1;
1043                         cx->windows_emulation = 1;
1044                         if (x != cx->dsp_copyright) {
1045                                 while (x < f && *add) *x++ = *add++;
1046                                 *x = 0;
1047                         }
1048                         else {
1049                                 strcpy(cx->dsp_copyright,"VDMSOUND");
1050                         }
1051                 }
1052         }
1053         else if (windows_mode == WINDOWS_ENHANCED) { /* Windows 9x/ME Sound Blaster */
1054                 struct w9x_vmm_DDB_scan vxdscan;
1055                 unsigned char vxdscanned = 0;
1056
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.
1065                  *
1066                  *       That scenario is typical of:
1067                  *
1068                  *          - Microsoft Windows 95 with Microsoft stock Sound Blaster 16 drivers
1069                  *
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.
1076                  *
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.
1081                  *
1082                  *       That scenario is typical of:
1083                  *
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.
1087                  *
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.
1092                  *
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
1096                  *       are resident.
1097                  *
1098                  *    c) The Sound Blaster is actual hardware, and Windows is not blocking
1099                  *       or virtualizing any I/O ports.
1100                  *
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!
1107                  *
1108                  *       Whatever you do in this scenario: Don't let multiple DOS boxes talk
1109                  *       to the same Sound Blaster card!!!
1110                  *
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
1114                  * Windows 9x. */
1115                 cx->windows_emulation = 1; /* NTS: The "pass thru" scenario counts as emulation */
1116
1117                 if (!sndsb_probe_options.disable_windows_vxd_checks && w9x_vmm_first_vxd(&vxdscan)) {
1118                         vxdscanned = 1;
1119                         do {
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;
1123                                 }
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);
1129                                 }
1130                         } while (w9x_vmm_next_vxd(&vxdscan));
1131                         w9x_vmm_last_vxd(&vxdscan);
1132                 }
1133
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");
1142                 }
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);
1149                 }
1150         }
1151
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]";
1160
1161                 cx->dosbox_emulation = 1;
1162                 if (x != cx->dsp_copyright) {
1163                         while (x < f && *add) *x++ = *add++;
1164                         *x = 0;
1165                 }
1166                 else {
1167                         strcpy(cx->dsp_copyright,"DOSBox emulator");
1168                 }
1169         }
1170
1171         if (!cx->windows_emulation && detect_virtualbox_emu())
1172                 cx->virtualbox_emulation = 1;
1173
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;
1181                         int in;
1182
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 */
1186                                 c2 &= 0xF;
1187                                 if (c2 != 0) {
1188                                         cx->ess_chipset = (c2 & 8) ? SNDSB_ESS_1869 : SNDSB_ESS_688;
1189
1190                                         if (cx->ess_chipset == SNDSB_ESS_688) { /* ESS 688? I know how to program that! */
1191                                                 cx->ess_extensions = 1;
1192
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 */
1195                                                         switch (in&0xF) {
1196                                                                 case 0x5:
1197                                                                         cx->irq = 5;
1198                                                                         break;
1199                                                                 case 0xA:
1200                                                                         cx->irq = 7;
1201                                                                         break;
1202                                                                 case 0xF:
1203                                                                         cx->irq = 10;
1204                                                                         break;
1205                                                                 case 0x0: /* "2,9,all others" */
1206                                                                         cx->irq = 9;
1207                                                                         break;
1208                                                                 default:
1209                                                                         break;
1210                                                         }
1211                                                 }
1212                                                 if ((in=sndsb_ess_read_controller(cx,0xB2)) != -1) { /* 0xB2 DRQ Control */
1213                                                         switch (in&0xF) {
1214                                                                 case 0x0:
1215                                                                         cx->dma8 = cx->dma16 = -1;
1216                                                                         break;
1217                                                                 case 0x5:
1218                                                                         cx->dma8 = cx->dma16 = 0;
1219                                                                         break;
1220                                                                 case 0xA:
1221                                                                         cx->dma8 = cx->dma16 = 1;
1222                                                                         break;
1223                                                                 case 0xF:
1224                                                                         cx->dma8 = cx->dma16 = 3;
1225                                                                         break;
1226                                                                 default:
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;
1231                                                                         break;
1232                                                         }
1233                                                 }
1234                                         }
1235                                         else if (cx->ess_chipset == SNDSB_ESS_1869) { /* ESS 1869? I know how to program that! */
1236                                                 cx->ess_extensions = 1;
1237
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. */
1242
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
1245                                                  * duplex?) */
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;
1250                                         }
1251
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. */
1257                                 }
1258                         }
1259                 }
1260         }
1261 #endif
1262
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);
1266         }
1267
1268         /* check DMA against the DMA controller presence.
1269          * If there is no 16-bit DMA (channels 4-7) then we cannot use
1270          * those channels */
1271         if (!(d8237_flags&D8237_DMA_SECONDARY)) {
1272                 if (cx->dma16 >= 4) cx->dma16 = -1;
1273                 if (cx->dma8 >= 4) cx->dma8 = -1;
1274         }
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;
1278         }
1279
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))
1284                                 cx->mpu_ok = 1;
1285                         else {
1286                                 if (sndsb_by_mpu(0x300) == NULL) {
1287                                         cx->mpuio = 0x300; /* less common */
1288                                         if (sndsb_probe_mpu401(cx))
1289                                                 cx->mpu_ok = 1;
1290                                         else {
1291                                                 cx->mpuio = 0;
1292                                         }
1293                                 }
1294                         }
1295                 }
1296         }
1297         else {
1298                 if (sndsb_probe_mpu401(cx))
1299                         cx->mpu_ok = 1;
1300         }
1301
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;
1313                 else
1314                         cx->max_sample_rate_dsp4xx = 44100;
1315
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? */
1324                 }
1325         }
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 */
1340                 }
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 */
1353                 }
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) */
1360                 }
1361         }
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;
1369                 }
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;
1374                 }
1375         }
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;
1380         }
1381
1382         /* if any of our tests left the SB IRQ hanging, clear it now */
1383         if (cx->irq >= 0) {
1384                 sndsb_interrupt_ack(cx,3);
1385                 sndsb_interrupt_ack(cx,3);
1386         }
1387
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;
1391         if (cx->irq < 0) {
1392                 if (cx->dsp_autoinit_command)
1393                         cx->dsp_nag_mode = 0;
1394                 else
1395                         cx->dsp_nag_mode = 1;
1396         }
1397
1398         sndsb_determine_ideal_dsp_play_method(cx);
1399
1400         return 1;
1401 }
1402
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;
1417                 else
1418                         cx->dsp_play_method = SNDSB_DSPOUTMETHOD_201;
1419         }
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;
1424         else
1425                 cx->dsp_play_method = SNDSB_DSPOUTMETHOD_DIRECT;
1426
1427         return 1;
1428 }
1429
1430 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
1431 #else
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() {
1435         sb_test_irq_flag++;
1436         if (sb_test_irq_number >= 8) p8259_OCW2(8,P8259_OCW2_NON_SPECIFIC_EOI);
1437         p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
1438 }
1439 #endif
1440
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.
1444  *
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__))
1450         /* too much code */
1451 #else
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"));
1462
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;
1466
1467         dma = dma_8237_alloc_buffer(testlen);
1468         if (dma == NULL) return;
1469
1470 #if TARGET_MSDOS == 32
1471         memset(dma->lin,128,testlen);
1472 #else
1473         _fmemset(dma->lin,128,testlen);
1474 #endif
1475
1476         /* save the IRQ mask */
1477         _cli();
1478         ml = p8259_read_mask(0);        /* IRQ0-7 */
1479         mh = p8259_read_mask(8);        /* IRQ8-15 */
1480         
1481         round = 0;
1482         do {
1483                 if (++round >= 8)
1484                         break;
1485
1486                 possible = 0;
1487                 /* go through the remaining ones, one at a time */
1488                 for (tri=0;tri < sizeof(tries);tri++) {
1489                         if (eliminated & (1U << tries[tri]))
1490                                 continue;
1491                         if (!sndsb_reset_dsp(cx)) {
1492                                 DEBUG(fprintf(stdout,"WARNING: DSP reset failed, aborting IRQ probe\n"));
1493                                 break;
1494                         }
1495
1496                         DEBUG(fprintf(stdout,"  Now testing IRQ %u\n",tries[tri]));
1497
1498                         /* clear SoundBlaster's previous interrupt */
1499                         inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
1500
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]);
1508
1509                         /* wait for IRQ to show response (prior to triggering one) */
1510                         _sti();
1511                         maybe = 0;
1512                         patience = 140;
1513                         tolerance = 0;
1514                         do {
1515                                 if (sb_test_irq_flag) {
1516                                         _cli();
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;
1523                                                 tolerance++;
1524                                                 patience = 250;
1525                                                 _sti();
1526                                         }
1527                                         else {
1528                                                 break;
1529                                         }
1530                                 }
1531                                 t8254_wait(t8254_us2ticks(1000));
1532                         } while (--patience != 0);
1533
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);
1540                                 continue;
1541                         }
1542
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 */
1552
1553                         /* Time Constant */
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);
1559                                 continue;
1560                         }
1561
1562                         /* wait for IRQ to show response */
1563                         _sti();
1564                         maybe = 0;
1565                         patience = 140;
1566                         do {
1567                                 if (sb_test_irq_flag) {
1568                                         DEBUG(fprintf(stdout,"Flag with %ums to go for IRQ %d\n",patience,tries[tri]));
1569                                         _cli();
1570                                         sb_test_irq_flag = 0; /* immediately clear it */
1571                                         maybe = 1;
1572                                         break;
1573                                 }
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 */
1577
1578                         DEBUG(fprintf(stdout,"    maybe=%u\n",maybe));
1579                         if (maybe == 0) {
1580                                 p8259_mask(tries[tri]);
1581                                 _dos_setvect(irq2int(tries[tri]),old_irq);
1582                                 continue;
1583                         }
1584
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);
1589                                 break;
1590                         }
1591
1592                         /* wait for IRQ to show response (prior to triggering one) */
1593                         _cli();
1594                         sb_test_irq_flag = 0;
1595                         _sti();
1596                         maybe = 0;
1597                         patience = 140;
1598                         do {
1599                                 if (sb_test_irq_flag) break;
1600                                 t8254_wait(t8254_us2ticks(1000));
1601                         } while (--patience != 0);
1602
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);
1609                                 continue;
1610                         }
1611
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 */
1621
1622                         /* Time Constant */
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);
1628                                 continue;
1629                         }
1630
1631                         /* wait for IRQ to show response */
1632                         _sti();
1633                         maybe = 0;
1634                         patience = 140;
1635                         do {
1636                                 if (sb_test_irq_flag) {
1637                                         DEBUG(fprintf(stdout,"Flag with %ums to go on IRQ %d\n",patience,tries[tri]));
1638                                         _cli();
1639                                         sb_test_irq_flag = 0; /* immediately clear it */
1640                                         maybe = 1;
1641                                         break;
1642                                 }
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 */
1646
1647                         DEBUG(fprintf(stdout,"    maybe2=%u\n",maybe));
1648                         if (maybe == 0) {
1649                                 p8259_mask(tries[tri]);
1650                                 _dos_setvect(irq2int(tries[tri]),old_irq);
1651                                 continue;
1652                         }
1653
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);
1658                                 break;
1659                         }
1660
1661                         /* OK cleanup */
1662                         p8259_mask(tries[tri]);
1663                         _dos_setvect(irq2int(tries[tri]),old_irq);
1664
1665                         possible |= 1U << tries[tri];
1666                         DEBUG(fprintf(stdout,"Possible=0x%04X\n",possible));
1667                 }
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);
1671
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];
1676                                 break;
1677                         }
1678                 }
1679         }
1680
1681         /* release DMA buffer */
1682         dma_8237_free_buffer(dma);
1683
1684         /* restore interrupt mask */
1685         _cli();
1686         p8259_write_mask(0,ml);
1687         p8259_write_mask(8,mh);
1688         _sti();
1689 #endif
1690 }
1691
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__))
1704         /* too much code */
1705 #else
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"));
1712
1713         _cli();
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);
1718
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 */
1722         patience = 250;
1723         do {
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];
1730                         }
1731                 }
1732         } while (--patience != 0);
1733         DEBUG(fprintf(stdout,"Pre-test IRQ elimination: 0x%04X\n",eliminated));
1734
1735         /* restore interrupt mask */
1736         p8259_write_mask(0,ml);
1737         p8259_write_mask(8,mh);
1738         _sti();
1739
1740         round = 0;
1741         do {
1742                 if (++round >= 8)
1743                         break;
1744
1745                 /* go through the remaining ones, one at a time */
1746                 possible = 0;
1747                 for (tri=0;tri < sizeof(tries);tri++) {
1748                         if (eliminated & (1U << tries[tri]))
1749                                 continue;
1750                         if (!sndsb_reset_dsp(cx)) {
1751                                 DEBUG(fprintf(stdout,"WARNING: DSP reset failed, aborting IRQ probe\n"));
1752                                 break;
1753                         }
1754
1755                         DEBUG(fprintf(stdout,"  Now testing IRQ %u\n",tries[tri]));
1756
1757                         /* clear SoundBlaster's previous interrupt */
1758                         inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
1759
1760                         _cli();
1761                         p8259_write_mask(0,0xFF);       /* mask off all interrupts */
1762                         p8259_write_mask(8,0xFF);
1763
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));
1769                                 continue;
1770                         }
1771
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"));
1776                                         break;
1777                                 }
1778                         }
1779
1780                         /* wait for IRQ to show response */
1781                         maybe = 0;
1782                         patience = 10;
1783                         do {
1784                                 irr = (unsigned short)p8259_read_IRR(tries[tri]);
1785                                 if (irr & (1 << (tries[tri] & 7))) {
1786                                         maybe = 1;
1787                                         break;
1788                                 }
1789                                 t8254_wait(t8254_us2ticks(1000));
1790                         } while (--patience != 0);
1791
1792                         DEBUG(fprintf(stdout,"    maybe=%u\n",maybe));
1793                         if (maybe == 0)
1794                                 continue;
1795
1796                         /* restore interrupt mask */
1797                         p8259_write_mask(0,ml);
1798                         p8259_write_mask(8,mh);
1799                         _sti();
1800
1801                         if (!sndsb_reset_dsp(cx)) {
1802                                 DEBUG(fprintf(stdout,"WARNING: DSP reset failed, aborting IRQ probe\n"));
1803                                 break;
1804                         }
1805
1806                         /* clear SoundBlaster's previous interrupt */
1807                         inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
1808
1809                         _cli();
1810                         p8259_write_mask(0,0xFF);       /* mask off all interrupts */
1811                         p8259_write_mask(8,0xFF);
1812
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));
1818                                 continue;
1819                         }
1820
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"));
1825                                         break;
1826                                 }
1827                         }
1828
1829                         /* wait for IRQ to show response */
1830                         maybe = 0;
1831                         patience = 10;
1832                         do {
1833                                 irr = (unsigned short)p8259_read_IRR(tries[tri]);
1834                                 if (irr & (1 << (tries[tri] & 7))) {
1835                                         maybe = 1;
1836                                         break;
1837                                 }
1838                                 t8254_wait(t8254_us2ticks(1000));
1839                         } while (--patience != 0);
1840
1841                         DEBUG(fprintf(stdout,"    maybe2=%u\n",maybe));
1842                         if (maybe == 0)
1843                                 continue;
1844
1845                         possible |= 1U << tries[tri];
1846                 }
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);
1850
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];
1855                                 break;
1856                         }
1857                 }
1858         }
1859
1860         /* restore interrupt mask */
1861         p8259_write_mask(0,ml);
1862         p8259_write_mask(8,mh);
1863         _sti();
1864 #endif
1865 }
1866
1867 void sndsb_manual_probe_high_dma(struct sndsb_ctx *cx) {
1868 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
1869         /* too much code */
1870 #else
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"));
1886
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"));
1896                         testlen = 22050/5;
1897                 }
1898         }
1899
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 */
1904         _cli();
1905         for (tri=0;tri < sizeof(tries);tri++) prev[tri] = d8237_read_count_lo16(tries[tri]);
1906         patience = 500;
1907         do {
1908                 for (tri=0;tri < sizeof(tries);tri++) {
1909                         if (eliminated & (1U << tries[tri]))
1910                                 continue;
1911                         if (prev[tri] != d8237_read_count_lo16(tries[tri]))
1912                                 eliminated |= 1U << tries[tri];
1913                 }
1914         } while (--patience != 0);
1915         DEBUG(fprintf(stdout,"Pre-test DMA elimination 0x%02x\n",eliminated));
1916
1917         dma = dma_8237_alloc_buffer(testlen);
1918         if (dma != NULL) {
1919 #if TARGET_MSDOS == 32
1920                 memset(dma->lin,0,testlen);
1921 #else
1922                 _fmemset(dma->lin,0,testlen);
1923 #endif
1924
1925                 for (tri=0;tri < sizeof(tries);tri++) {
1926                         if (eliminated & (1U << tries[tri]))
1927                                 continue;
1928                         if (!sndsb_reset_dsp(cx))
1929                                 break;
1930
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);
1936
1937                         DEBUG(fprintf(stdout,"     Testing DMA channel %u\n",tries[tri]));
1938
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 */
1950
1951                         /* Time Constant */
1952                         if (!sndsb_write_dsp_outrate(cx,srate))
1953                                 continue;
1954
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]));
1961
1962                         /* wait */
1963                         dma_count_began = 0;
1964                         patience = (unsigned int)(((unsigned long)testlen * 1500UL) / (unsigned long)srate);
1965                         do {
1966                                 rem = d8237_read_count(tries[tri]);
1967                                 if (rem <= 2 || rem >= 0xFFFF) break; /* if below 2 or at terminal count */
1968
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
1973                                  * original value.
1974                                  *
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"));
1982                                                 rem = 0;
1983                                                 break;
1984                                         }
1985                                 }
1986                                 else {
1987                                         if (rem != testlen)
1988                                                 dma_count_began = 1;
1989                                 }
1990
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);
1997
1998                         /* clear SoundBlaster's previous interrupt */
1999                         inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS);
2000                         inp(cx->baseio+SNDSB_BIO_DSP_READ_STATUS16);
2001
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];
2005                                 break;
2006                         }
2007                 }
2008
2009                 dma_8237_free_buffer(dma);
2010         }
2011
2012         _sti();
2013 #endif
2014 }
2015
2016 void sndsb_manual_probe_dma(struct sndsb_ctx *cx) {
2017 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
2018         /* too much code */
2019 #else
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"));
2036
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"));
2046                         testlen = 22050/5;
2047                 }
2048         }
2049
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 */
2054         _cli();
2055         for (tri=0;tri < sizeof(tries);tri++) prev[tri] = d8237_read_count_lo16(tries[tri]);
2056         patience = 500;
2057         do {
2058                 for (tri=0;tri < sizeof(tries);tri++) {
2059                         if (eliminated & (1U << tries[tri]))
2060                                 continue;
2061                         if (prev[tri] != d8237_read_count_lo16(tries[tri]))
2062                                 eliminated |= 1U << tries[tri];
2063                 }
2064         } while (--patience != 0);
2065         DEBUG(fprintf(stdout,"Pre-test DMA elimination 0x%02x\n",eliminated));
2066
2067         dma = dma_8237_alloc_buffer(testlen);
2068         if (dma != NULL) {
2069 #if TARGET_MSDOS == 32
2070                 memset(dma->lin,128,testlen);
2071 #else
2072                 _fmemset(dma->lin,128,testlen);
2073 #endif
2074
2075                 /* then, initiate short playback tests to figure out which one */
2076                 /* EMULATOR NOTES:
2077                  *      - Microsoft Virtual PC:              works
2078                  *      - DOSBox:                            works
2079                  *      - Sun/Oracle VirtualBox:             works
2080                  *
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]))
2087                                 continue;
2088                         if (!(d8237_flags&D8237_DMA_SECONDARY) && tries[tri] >= 4)
2089                                 continue;
2090                         if (!(d8237_flags&D8237_DMA_PRIMARY) && tries[tri] < 4)
2091                                 continue;
2092                         if (!sndsb_reset_dsp(cx))
2093                                 break;
2094
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);
2099
2100                         DEBUG(fprintf(stdout,"     Testing DMA channel %u\n",tries[tri]));
2101
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 */
2111
2112                         /* Time Constant */
2113                         if (!sndsb_write_dsp_timeconst(cx,timeconst))
2114                                 continue;
2115
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]));
2121
2122                         /* wait */
2123                         dma_count_began = 0;
2124                         patience = (unsigned int)(((unsigned long)testlen * 1500UL) / (unsigned long)srate);
2125                         do {
2126                                 rem = d8237_read_count(tries[tri]);
2127                                 if (rem <= 2 || rem >= 0xFFFF) break; /* if below 2 or at terminal count */
2128
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
2133                                  * original value.
2134                                  *
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"));
2142                                                 rem = 0;
2143                                                 break;
2144                                         }
2145                                 }
2146                                 else {
2147                                         if (rem != testlen)
2148                                                 dma_count_began = 1;
2149                                 }
2150
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);
2156
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];
2160                                 break;
2161                         }
2162                 }
2163
2164                 dma_8237_free_buffer(dma);
2165         }
2166
2167         _sti();
2168 #endif
2169 }
2170
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;
2176
2177         if ((iobase&0xF) != 0)
2178                 return 0;
2179         if (iobase < 0x210 || iobase > 0x270)
2180                 return 0;
2181         if (sndsb_by_base(iobase) != NULL)
2182                 return 0;
2183
2184         /* some of our detection relies on knowing what OS we're running under */
2185         cpu_probe();
2186         probe_dos();
2187         detect_windows();
2188
2189         cx = sndsb_alloc_card();
2190         if (cx == NULL) return 0;
2191
2192         DEBUG(fprintf(stdout,"sndsb_try_base(0x%03X)\n",iobase));
2193
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);
2199                 return 0;
2200         }
2201
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);
2206
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);
2215
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);
2220
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;
2224
2225         sndsb_determine_ideal_dsp_play_method(cx);
2226         return 1;
2227 }
2228
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;
2236         }
2237         else if (cx->ess_extensions) {
2238                 return cx->buffer_16bit ? 2 : 1;
2239         }
2240
2241         /* DSP 3.xx and earlier: just assume the interrupt happened because of the DSP */
2242         return 1;
2243 }
2244
2245 int sndsb_reset_mixer(struct sndsb_ctx *cx) {
2246         if (cx->baseio == 0)
2247                 return 0;
2248
2249         sndsb_write_mixer(cx,0x00,0x00);        /* "write any 8-bit value to reset the chip" */
2250         return 1;
2251 }
2252
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;
2257
2258         oflags = get_cpu_flags();
2259         _cli();
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.
2266                  *
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.
2281                  *
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);
2289
2290                 cx->timer_tick_signal = 0;
2291         }
2292         if (oflags & 0x200/* if interrupts were enabled */) _sti();
2293
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);
2298 }
2299
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
2305 #else
2306 # define MSG(x)
2307         cx->reason_not_supported = "";
2308 #endif
2309
2310         if (!cx->dsp_ok) {
2311                 MSG("DSP not detected");
2312                 return 0; /* No DSP, no playback */
2313         }
2314         if (cx->dsp_play_method >= SNDSB_DSPOUTMETHOD_MAX) {
2315                 MSG("play method out of range");
2316                 return 0; /* invalid DSP output method */
2317         }
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)");
2320                 return 0;
2321         }
2322
2323         if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx && cx->ess_extensions) {
2324                 /* OK. we can use ESS extensions with flipped sign */
2325         }
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");
2328                 return 0;
2329         }
2330
2331         if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx && cx->ess_extensions) {
2332                 /* OK. we can use ESS extensions to do 16-bit playback */
2333         }
2334         else if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_4xx && wav_16bit) {
2335                 MSG("16-bit PCM playback requires DSP 4.xx mode");
2336                 return 0;
2337         }
2338
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)");
2341                 return 0;
2342         }
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");
2345                 return 0;
2346         }
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");
2349                 return 0;
2350         }
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");
2353                 return 0;
2354         }
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");
2357                 return 0;
2358         }
2359
2360         if (cx->dsp_adpcm > 0) {
2361                 if (cx->dsp_record) {
2362                         MSG("No such thing as ADPCM recording");
2363                         return 0;
2364                 }
2365                 if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) {
2366                         MSG("No such thing as direct DAC ADPCM playback");
2367                         return 0;
2368                 }
2369                 if (wav_16bit) {
2370                         MSG("No such thing as 16-bit ADPCM playback");
2371                         return 0;
2372                 }
2373                 if (wav_stereo) {
2374                         MSG("No such thing as stereo ADPCM playback");
2375                         return 0;
2376                 }
2377                 if (cx->audio_data_flipped_sign) {
2378                         MSG("No such thing as flipped sign ADPCM playback");
2379                         return 0;
2380                 }
2381                 if (cx->goldplay_mode) {
2382                         MSG("Goldplay ADPCM playback not supported");
2383                         return 0;
2384                 }
2385         }
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.");
2392                         return 0;
2393                 }
2394 #endif
2395         }
2396
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;
2399 # endif
2400         return 1;
2401 #undef MSG
2402 }
2403
2404 unsigned int sndsb_will_dsp_nag(struct sndsb_ctx *cx) {
2405         if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT)
2406                 return 0;
2407
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)
2414                         return 0;
2415         }
2416
2417         return 1;
2418 }
2419
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;
2425         }
2426
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);
2433 }
2434
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
2439 #else
2440 # define MSG(x)
2441         cx->reason_not_supported = "";
2442 #endif
2443
2444         if (!sndsb_dsp_out_method_can_do(cx,wav_sample_rate,wav_stereo,wav_16bit))
2445                 return 0;
2446
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");
2449                 return 0;
2450         }
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");
2453                 return 0;
2454         }
2455
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]");
2460                                 return 0;
2461                         }
2462                 }
2463                 else {
2464                         if (cx->dsp_vmaj < 4) {
2465                                 MSG("DSP 4.xx playback requires SB16");
2466                                 return 0;
2467                         }
2468                 }
2469         }
2470
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");
2473                 return 0;
2474         }
2475         if (cx->dsp_autoinit_command && cx->dsp_vmaj < 2) {
2476                 MSG("Auto-init DSP command support requires DSP 2.0 or higher");
2477                 return 0;
2478         }
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");
2481                 return 0;
2482         }
2483
2484         if (wav_stereo && cx->dsp_vmaj < 3) {
2485                 MSG("You are playing stereo audio on a DSP that doesn't support stereo");
2486                 return 0;
2487         }
2488
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");
2491                 return 0;
2492         }
2493         if (wav_stereo && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) {
2494                 MSG("Direct DAC mode does not support stereo");
2495                 return 0;
2496         }
2497
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");
2501                 return 0;
2502         }
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");
2505                 return 0;
2506         }
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");
2509                 return 0;
2510         }
2511
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)) {
2520                         /* yes */
2521                 }
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) {
2525                                 /* yes */
2526                         }
2527                         else if ((cx->force_hispeed || (wav_sample_rate*(wav_stereo?2:1)) > (cx->dsp_record ? 13000UL : 23000UL)) && cx->hispeed_blocking) {
2528                                 /* no */
2529                                 MSG("No IRQ assigned & DSP nag mode is ineffective\nif the DSP will run in 2.0/Pro highspeed DSP mode.");
2530                                 return 0;
2531                         }
2532                         else {
2533                                 /* yes */
2534                         }
2535                 }
2536                 else {
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.");
2541                         return 0;
2542                 }
2543         }
2544
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.");
2551                         return 0;
2552                 }
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");
2558                         return 0;
2559                 }
2560         }
2561
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");
2567                         return 0;
2568                 }
2569
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");
2573                         return 0;
2574                 }
2575
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
2578                  *      documentation */
2579                 if (cx->dsp_adpcm == ADPCM_4BIT) {
2580                         if (wav_sample_rate > 12000UL) return 0;
2581                 }
2582                 else if (cx->dsp_adpcm == ADPCM_2_6BIT) {
2583                         if (wav_sample_rate > 13000UL) return 0;
2584                 }
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 */
2587                 }
2588                 else {
2589                         return 0;
2590                 }
2591         }
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;
2599         }
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;
2604         }
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.
2611                  *
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;
2614         }
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;
2617         }
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;
2620         }
2621         MSG(NULL);
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");
2627                 return 0;
2628         }
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)");
2633                 return 0;
2634         }
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... */
2639         }
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");
2645                 return 0;
2646         }
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");
2650                 return 0;
2651         }
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) {
2655 #else
2656         if (cx->backwards && (cpu_flags&CPU_FLAG_V86_ACTIVE)) {
2657 #endif
2658                 MSG("DMA played backwards is not recommended from\nwithin a virtual 8086 mode monitor");
2659                 return 0;
2660         }
2661
2662         /* NTS: Virtualbox supports backwards DMA, it's OK */
2663
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;
2666 # endif
2667         return 1;
2668 #undef MSG
2669 }
2670
2671 int sndsb_write_dsp_blocksize(struct sndsb_ctx *cx,uint16_t tc) {
2672         if (!sndsb_write_dsp(cx,0x48))
2673                 return 0;
2674         if (!sndsb_write_dsp(cx,tc-1))
2675                 return 0;
2676         if (!sndsb_write_dsp(cx,(tc-1)>>8))
2677                 return 0;
2678         return 1;
2679 }
2680
2681 int sndsb_write_dsp_outrate(struct sndsb_ctx *cx,unsigned long rate) {
2682         if (!sndsb_write_dsp(cx,0x41))
2683                 return 0;
2684         if (!sndsb_write_dsp(cx,rate>>8)) /* Ugh, Creative, be consistent! */
2685                 return 0;
2686         if (!sndsb_write_dsp(cx,rate))
2687                 return 0;
2688         return 1;
2689 }
2690
2691 uint32_t sndsb_read_dma_buffer_position(struct sndsb_ctx *cx) {
2692         uint32_t r;
2693
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;
2701         }
2702
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;
2708         }
2709         else if (cx->buffer_16bit) {
2710                 if (cx->dma16 < 0) return 0;
2711                 r = d8237_read_count(cx->dma16);
2712                 if (cx->backwards) {
2713                         /* TODO */
2714                 }
2715                 else {
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;
2720                 }
2721         }
2722         else {
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;
2729                 }
2730                 else {
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;
2735                 }
2736         }
2737
2738         return r;
2739 }
2740
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 */
2746         return 1;
2747 }
2748
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;
2752
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;
2757
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)
2761                 return 1;
2762
2763         if (cx->backwards)
2764                 cx->direct_dsp_io = cx->buffer_size - 1;
2765         else
2766                 cx->direct_dsp_io = 0;
2767
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 */
2771
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));
2778
2779         if (cx->goldplay_mode) {
2780                 /* goldplay mode REQUIRES auto-init DMA */
2781                 if (!cx->chose_autoinit_dma) return -1;
2782
2783                 cx->gold_memcpy = (cx->buffer_16bit?2:1)*(cx->buffer_stereo?2:1);
2784
2785 #if TARGET_MSDOS == 32
2786                 if (cx->goldplay_dma == NULL) {
2787                         if ((cx->goldplay_dma=dma_8237_alloc_buffer(16)) == NULL)
2788                                 return 0;
2789                 }
2790 #endif
2791
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.
2798                  *
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));
2807
2808                 if ((cx->buffer_16bit?1:0)^(cx->audio_data_flipped_sign?1:0))
2809                         memset(cx->goldplay_dma->lin,0,4);
2810                 else
2811                         memset(cx->goldplay_dma->lin,128,4);
2812 #else
2813                 {
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));
2816
2817                         if ((cx->buffer_16bit?1:0)^(cx->audio_data_flipped_sign?1:0))
2818                                 _fmemset(p,0,4);
2819                         else
2820                                 _fmemset(p,128,4);
2821                 }
2822 #endif
2823         }
2824         else {
2825                 d8237_write_count(ch,cx->buffer_dma_started_length);
2826                 if (cx->backwards)
2827                         d8237_write_base(ch,cx->buffer_phys+cx->buffer_dma_started+cx->buffer_dma_started_length-1);
2828                 else
2829                         d8237_write_base(ch,cx->buffer_phys+cx->buffer_dma_started); /* RAM location with not much around */
2830         }
2831
2832         outp(d8237_ioport(ch,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(ch)); /* unmask */
2833         return 1;
2834 }
2835
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;
2840
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;
2846
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;
2856         return real_rate;
2857 }
2858
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);
2862 }
2863
2864 int sndsb_prepare_dsp_playback(struct sndsb_ctx *cx,unsigned long rate,unsigned char stereo,unsigned char bit16) {
2865         unsigned long lm;
2866
2867         /* TODO: Don't play if already playing */
2868
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)
2874                 return 0;
2875
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;
2886
2887                 lm = cx->buffer_size;
2888                 if (cx->dsp_adpcm == 0) {
2889                         if (bit16) lm >>= 1UL;
2890                         if (stereo) lm >>= 1UL;
2891                 }
2892
2893                 /* if IRQ interval is not assigned, give it the buffer length.
2894                    we must also ensure the requested interval is less than the
2895                    buffer length. */
2896                 if (cx->buffer_irq_interval == 0 ||
2897                         cx->buffer_irq_interval > lm)
2898                         cx->buffer_irq_interval = lm;
2899
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.
2905                  *
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.
2908                  *
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.
2911                  *
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
2924                          * DMA timing. */
2925                         else
2926                                 cx->buffer_irq_interval = (lm / 2UL);
2927                 }
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.
2933                          *
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;
2943                         }
2944                 }
2945
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 */
2948                 if (bit16) {
2949                         if (cx->ess_extensions) {
2950                                 if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_3xx)
2951                                         return 0;
2952                         }
2953                         else if (cx->dsp_play_method < SNDSB_DSPOUTMETHOD_4xx) {
2954                                 return 0;
2955                         }
2956                 }
2957
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))
2961                         return 0;
2962         }
2963
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)
2967                 return 1;
2968
2969         /* clear any pending DSP events (DSP 4.xx) */
2970         if (cx->dsp_vmaj >= 4)
2971                 sndsb_interrupt_ack(cx,3);
2972
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.
2978          *
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 */
2988
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;
2994
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;
3000
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 */
3005
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;
3010                 }
3011                 else {
3012                         cx->chose_autoinit_dsp = 0;
3013                 }
3014         }
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 */
3019         }
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. */
3023         }
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);
3027
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));
3030
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));
3048                         else
3049                                 cx->buffer_hispeed = (total_rate >= (cx->dsp_record ? 13000 : 23000));
3050
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));
3057                         }
3058
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));
3062                 }
3063                 else {
3064                         cx->buffer_hispeed = 0;
3065                         if (cx->chose_autoinit_dsp)
3066                                 sndsb_write_dsp_blocksize(cx,cx->buffer_irq_interval * (stereo?2:1));
3067                 }
3068         }
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);
3072         }
3073
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;
3077
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;
3083         }
3084         else {
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;
3089                 }
3090
3091                 if (cx->backwards)
3092                         cx->buffer_dma_started = cx->buffer_size - cx->buffer_dma_started_length;
3093         }
3094
3095         return 1;
3096 }
3097
3098 int sndsb_begin_dsp_playback(struct sndsb_ctx *cx) {
3099         if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) {
3100                 cx->gold_memcpy = 0;
3101                 if (cx->dsp_record)
3102                         cx->timer_tick_func = sndsb_timer_tick_directi_cmd;
3103                 else
3104                         cx->timer_tick_func = sndsb_timer_tick_directo_cmd;
3105         }
3106         else if (cx->goldplay_mode) {
3107 #if TARGET_MSDOS == 32
3108                 if (cx->goldplay_dma == NULL)
3109                         return 0;
3110 #endif
3111
3112                 cx->gold_memcpy = (cx->buffer_16bit?2:1)*(cx->buffer_stereo?2:1);
3113                 if (cx->dsp_record)
3114                         cx->timer_tick_func = sndsb_timer_tick_goldi_cpy;
3115                 else
3116                         cx->timer_tick_func = sndsb_timer_tick_goldo_cpy;
3117         }
3118         else {
3119                 if (cx->dsp_nag_mode)
3120                         cx->timer_tick_func = sndsb_timer_tick_gen;
3121                 else
3122                         cx->timer_tick_func = NULL;
3123
3124                 cx->gold_memcpy = 0;
3125         }
3126
3127         if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_DIRECT) /* do nothing */
3128                 return 1;
3129
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;
3133                 return 1;
3134         }
3135
3136         if (cx->dsp_adpcm > 0) {
3137                 if (cx->dsp_record || cx->goldplay_mode)
3138                         return 0;
3139
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 */
3147                 }
3148                 else {
3149                         unsigned short lv;
3150
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);
3160                 }
3161         }
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;
3164
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 */
3169                         unsigned short t16;
3170                         int b;
3171
3172                         _cli();
3173
3174                         /* clear IRQ */
3175                         sndsb_interrupt_ack(cx,3);
3176
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) {
3181                                 _sti();
3182                                 return 0;
3183                         }
3184
3185                         b = sndsb_ess_read_controller(cx,0xA8);
3186                         if (b == -1) {
3187                                 _sti();
3188                                 return 0;
3189                         }
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) {
3193                                 _sti();
3194                                 return 0;
3195                         }
3196
3197                         /* NTS: The meaning of bits 1:0 in register 0xB9
3198                          *
3199                          *      00 single DMA transfer mode
3200                          *      01 demand DMA transfer mode, 2 bytes/request
3201                          *      10 demand DMA transfer mode, 4 bytes/request
3202                          *      11 reserved
3203                          *
3204                          * NOTES on what happens if you set bits 1:0 (DMA transfer type) to the "reserved" 11 value:
3205                          *
3206                          *      ESS 688 (Sharp laptop)          Nothing, apparently. Treated the same as 4 bytes/request
3207                          *
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.
3215                          */
3216
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) */
3220                         else
3221                                 b = 2;  /* demand transfer DMA 4 bytes per request */
3222
3223                         if (sndsb_ess_write_controller(cx,0xB9,b) == -1) {
3224                                 _sti();
3225                                 return 0;
3226                         }
3227
3228                         if (cx->buffer_rate > 22050) {
3229                                 /* bit 7: = 1
3230                                  * bit 6:0: = sample rate divider
3231                                  *
3232                                  * rate = 795.5KHz / (256 - x) */
3233                                 b = 256 - (795500UL / (unsigned long)cx->buffer_rate);
3234                                 if (b < 0x80) b = 0x80;
3235                         }
3236                         else {
3237                                 /* bit 7: = 0
3238                                  * bit 6:0: = sample rate divider
3239                                  *
3240                                  * rate = 397.7KHz / (128 - x) */
3241                                 b = 128 - (397700UL / (unsigned long)cx->buffer_rate);
3242                                 if (b < 0) b = 0;
3243                         }
3244                         if (sndsb_ess_write_controller(cx,0xA1,b) == -1) {
3245                                 _sti();
3246                                 return 0;
3247                         }
3248
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) {
3251                                 _sti();
3252                                 return 0;
3253                         }
3254
3255                         t16 = -(lv+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 */
3258                                 _sti();
3259                                 return 0;
3260                         }
3261
3262                         b = sndsb_ess_read_controller(cx,0xB1);
3263                         if (b == -1) {
3264                                 _sti();
3265                                 return 0;
3266                         }
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) {
3270                                 _sti();
3271                                 return 0;
3272                         }
3273
3274                         b = sndsb_ess_read_controller(cx,0xB2);
3275                         if (b == -1) {
3276                                 _sti();
3277                                 return 0;
3278                         }
3279                         b &= ~0xA0; /* clear compat */
3280                         b |= 0x50; /* set DRQ/DACKB inputs for DMA */
3281                         if (sndsb_ess_write_controller(cx,0xB2,b) == -1) {
3282                                 _sti();
3283                                 return 0;
3284                         }
3285
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) {
3289                                 _sti();
3290                                 return 0;
3291                         }
3292
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) {
3298                                 _sti();
3299                                 return 0;
3300                         }
3301
3302                         b = sndsb_ess_read_controller(cx,0xB8);
3303                         if (b == -1) {
3304                                 _sti();
3305                                 return 0;
3306                         }
3307                         if (sndsb_ess_write_controller(cx,0xB8,b | 1) == -1) { /* enable DMA */
3308                                 _sti();
3309                                 return 0;
3310                         }
3311                 }
3312                 else {
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);
3317                                 else
3318                                         sndsb_write_dsp(cx,cx->dsp_record ? 0x2C : 0x1C);
3319                         }
3320                         else {
3321                                 /* send single-cycle command, then transmit length */
3322                                 if (cx->buffer_hispeed)
3323                                         sndsb_write_dsp(cx,cx->dsp_record ? 0x99 : 0x91);
3324                                 else {
3325                                         sndsb_write_dsp(cx,cx->dsp_record ? 0x24 : 0x14);
3326                                         sndsb_write_dsp(cx,lv);
3327                                         sndsb_write_dsp(cx,lv >> 8);
3328                                 }
3329                         }
3330                 }
3331         }
3332         else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_4xx) {
3333                 unsigned long lv = (cx->buffer_irq_interval * (cx->buffer_stereo?2:1)) - 1;
3334
3335                 if (lv > 65535UL) lv = 65535UL;
3336
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);
3345         }
3346
3347         cx->timer_tick_signal = 0;
3348         return 1;
3349 }
3350
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) {
3357                 if (cx->dsp_record)
3358                         sndsb_read_dsp(cx);
3359                 else
3360                         sndsb_write_dsp(cx,0x80);
3361
3362                 cx->direct_dac_sent_command = 0;
3363         }
3364
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);
3371
3372         if ((cx->buffer_16bit && cx->dma16 >= 0) || (!cx->buffer_16bit && cx->dma8 >= 0)) {
3373                 uint16_t pr,cr;
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);
3378                 do {
3379                         t8254_wait(t8254_us2ticks(10000)); /* 10ms */
3380                         pr = cr;
3381                         if (cx->buffer_16bit)   cr = d8237_read_count(cx->dma16);
3382                         else                    cr = d8237_read_count(cx->dma8);
3383                         if (pr == cr) nonmove++;
3384                         else nonmove = 0;
3385                 } while (nonmove < 3);
3386         }
3387
3388         if (cx->dsp_play_method > SNDSB_DSPOUTMETHOD_DIRECT) {
3389                 sndsb_shutdown_dma(cx);
3390                 sndsb_write_mixer(cx,0x0E,0);
3391         }
3392
3393         cx->timer_tick_signal = 0;
3394         sndsb_write_dsp(cx,0xD3); /* turn off speaker */
3395
3396         if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
3397                 int b;
3398
3399                 b = sndsb_ess_read_controller(cx,0xB8);
3400                 if (b != -1) {
3401                         b &= ~0x01; /* stop DMA */
3402                         sndsb_ess_write_controller(cx,0xB8,b);
3403                 }
3404         }
3405
3406         return 1;
3407 }
3408
3409 void sndsb_send_buffer_again(struct sndsb_ctx *cx) {
3410         unsigned long lv;
3411         unsigned char ch;
3412
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;
3416
3417         if (!cx->chose_autoinit_dma)
3418                 outp(d8237_ioport(ch,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(ch) | D8237_MASK_SET); /* mask */
3419
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) {
3427                 }
3428                 else if (cx->ess_extensions && cx->dsp_play_method == SNDSB_DSPOUTMETHOD_3xx) {
3429                         unsigned char b;
3430
3431                         /* stop DMA */
3432                         b = sndsb_ess_read_controller(cx,0xB8);
3433                         sndsb_ess_write_controller(cx,0xB8,b & ~1);
3434                 }
3435         }
3436
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;
3442
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;
3447                 }
3448
3449                 if (cx->backwards) {
3450                         if (rem == 0) {
3451                                 npos = cx->buffer_size - lv;
3452                                 rem = cx->buffer_size;
3453                         }
3454                         else {
3455                                 if (npos >= lv) npos -= lv;
3456                                 else npos = 0;
3457                         }
3458                 }
3459                 else {
3460                         npos += cx->buffer_dma_started_length;
3461                         rem = npos + lv;
3462                         if (npos >= cx->buffer_size) {
3463                                 npos = 0;
3464                                 rem = lv;
3465                         }
3466                         else if (rem > cx->buffer_size) {
3467                                 rem = cx->buffer_size;
3468                         }
3469                 }
3470
3471                 cx->buffer_dma_started = npos;
3472                 cx->buffer_dma_started_length = lv = rem - npos;
3473                 if (cx->backwards)
3474                         d8237_write_base(ch,cx->buffer_phys+cx->buffer_dma_started+cx->buffer_dma_started_length-1); /* RAM location with not much around */
3475                 else
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 */
3479                 if (lv != 0) lv--;
3480         }
3481         else {
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;
3486                 }
3487                 if (lv != 0) lv--;
3488         }
3489
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);
3501                 }
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) {
3505                                 unsigned short t16;
3506                                 unsigned char b;
3507
3508                                 t16 = -(lv+1);
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 */
3511
3512                                 /* start DMA again */
3513                                 b = sndsb_ess_read_controller(cx,0xB8);
3514                                 sndsb_ess_write_controller(cx,0xB8,b | 1);
3515                         }
3516                         else {
3517                                 if (cx->buffer_hispeed) {
3518                                         sndsb_write_dsp_blocksize(cx,lv+1);
3519                                         sndsb_write_dsp(cx,cx->dsp_record ? 0x99 : 0x91);
3520                                 }
3521                                 else {
3522                                         sndsb_write_dsp(cx,cx->dsp_record ? 0x24 : 0x14);
3523                                         sndsb_write_dsp(cx,lv);
3524                                         sndsb_write_dsp(cx,lv >> 8);
3525                                 }
3526                         }
3527                 }
3528                 else if (cx->dsp_play_method == SNDSB_DSPOUTMETHOD_4xx) {
3529                         lv++;
3530                         if (cx->buffer_16bit) lv >>= 1UL;
3531                         lv--;
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);
3540                 }
3541         }
3542 }
3543
3544 void sndsb_choose_mixer(struct sndsb_ctx *card,signed char override) {
3545         signed char idx;
3546
3547         card->sb_mixer_items = 0;
3548         card->sb_mixer = NULL;
3549         idx = override >= 0 ? override : card->mixer_chip;
3550
3551 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
3552 #else
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));
3556         }
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));
3560         }
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));
3564         }
3565 #endif
3566 }
3567
3568 #if TARGET_MSDOS == 16 && (defined(__COMPACT__) || defined(__SMALL__))
3569 /* CUT ADPCM encoding */
3570 #else
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
3573  *      Wiki is wrong. */
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
3580         };
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
3586         };
3587         signed int sdelta = (signed int)((signed char)(samp - adpcm_pred));
3588         unsigned char sign = 0;
3589
3590         sdelta = (sdelta * 2) + (adpcm_step < 3 ? adpcm_error : 0);
3591         adpcm_error = sdelta & ((1 << (adpcm_step + 1)) - 1);
3592         sdelta >>= adpcm_step+1;
3593         if (sdelta < 0) {
3594                 sdelta = -sdelta;
3595                 sign = 8;
3596         }
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;
3605 }
3606
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
3609  *      Wiki is wrong. */
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. */
3618         };
3619         static const signed char adjustMap[12] = {
3620                  0, 1, -1, 1,
3621                 -1, 1, -1, 1,
3622                 -1, 1, -1, 0
3623         };
3624         signed int sdelta = (signed int)((signed char)(samp - adpcm_pred));
3625         unsigned char sign = 0;
3626
3627         sdelta = (sdelta * 2) + (adpcm_step == 0 ? adpcm_error : 0);
3628         adpcm_error = sdelta & ((1 << adpcm_step) - 1);
3629         sdelta >>= adpcm_step+1;
3630
3631         if (sdelta < 0) {
3632                 sdelta = -sdelta;
3633                 sign = 2;
3634         }
3635
3636         /* "ring" suppression */
3637         if (adpcm_step == 5 && sdelta == 1 && adpcm_last == 3 && sign == 0)
3638                 sdelta = 0;
3639
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;
3649 }
3650
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
3653  *      Wiki is wrong. */
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
3661         };
3662         static const signed char adjustMap[20] = {
3663                  0, 0, 0, 1,
3664                 -1, 0, 0, 1,
3665                 -1, 0, 0, 1,
3666                 -1, 0, 0, 1,
3667                 -1, 0, 0, 0
3668         };
3669         signed int sdelta = (signed int)((signed char)(samp - adpcm_pred));
3670         unsigned char sign = 0;
3671
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;
3675
3676         if (sdelta < 0) {
3677                 sdelta = -sdelta;
3678                 sign = 4;
3679         }
3680
3681         if (sdelta > 3) sdelta = 3;
3682         sdelta += sign;
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;
3691 }
3692
3693 void sndsb_encode_adpcm_set_reference(unsigned char c,unsigned char mode) {
3694         adpcm_pred = c;
3695         adpcm_step = 0;
3696         if (mode == ADPCM_4BIT)
3697                 adpcm_lim = 5;
3698         else if (mode == ADPCM_2_6BIT)
3699                 adpcm_lim = 3;
3700         else if (mode == ADPCM_2BIT)
3701                 adpcm_lim = 1;
3702 }
3703
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)
3712                 adpcm_step = 3;
3713         else if (mode == ADPCM_2_6BIT)
3714                 adpcm_step = 4;
3715         else
3716                 adpcm_step = 5; /* FIXME: Testing by ear seems to favor this one. Is this correct? */
3717 }
3718 #endif
3719
3720 void sndsb_write_mixer_entry(struct sndsb_ctx *sb,struct sndsb_mixer_control *mc,unsigned char nb) {
3721         unsigned char b;
3722         if (mc->length == 0) return;
3723         else if (mc->length == 8) {
3724                 sndsb_write_mixer(sb,mc->index,nb);
3725         }
3726         else {
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);
3731         }
3732 }
3733
3734 unsigned char sndsb_read_mixer_entry(struct sndsb_ctx *sb,struct sndsb_mixer_control *mc) {
3735         unsigned char b;
3736         if (mc->length == 0) return 0;
3737         b = sndsb_read_mixer(sb,mc->index);
3738         return (b >> mc->offset) & ((1 << mc->length) - 1);
3739 }
3740
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;
3745         return 1;
3746 }
3747
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;
3751
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".
3755          *
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;
3761         }
3762
3763         return ret;
3764 }
3765