]> 4ch.mooo.com Git - 16.git/blob - src/lib/doslib/hw/ultrasnd/ultrasnd.c
added a bunch of things~ and midi stuff~
[16.git] / src / lib / doslib / hw / ultrasnd / ultrasnd.c
1 /* NOTES:
2
3    2011/10/28: Ah-ha! This code was having difficulty using 16-bit
4       DMA channels because I somehow missed in Gravis documentation
5       that the DMA start address is subject to 16-bit address translation,
6       just like anything else related to 16-bit audio on the Gravis
7       chipsets. The GF1 test/init routine is now able to use full
8       GF1 capabilities and DMA properly when the card uses DMA channels
9       5, 6, and 7
10
11    Gravis Ultrasound Max:
12
13        - I ran into an annoying H/W glitch while writing this code
14          that is related to starting/stopping DMA transfers.
15          Apparently, if you first unmask the AT DMA channel, then
16          program the GUS DRAM addr and program in the settings
17          RIGHT OFF THE BAT, you will mostly get good transfers
18          but some transfers will have audible static (as if for
19          some odd reason the GUS is getting the DMA data but
20          NOT writing every 100th byte to it's RAM or something).
21
22          The workaround apparently is to cautiously start the DMA:
23            - Write 0x00 to DMA control to stop, THEN read to ack
24            - Program AT DMA controller, but do not unmask channel yet
25            - Write configuration to GUS DMA control, but do not yet
26              set the enable bit (bit 0)
27            - Write DRAM address to GUS DMA control
28            - Then, write DMA control again with "enable DMA" bit set
29            - Then, instruct the AT DMA controller to unmask the channel.
30
31          Following this sequence of steps resolves the staticy crackly
32          audio observed with a GUS Max on an ancient Pentium/100MHz
33          system of mine.
34
35             -- Jonathan C.
36
37
38    Bidirectional looping misconception:
39
40       - Each voice has a "current" position, a start, and an end.
41         When the current position hits the end, the voice stops.
42         Unless the voice is said to loop, then it goes back to start.
43         A voice can also be marked as "bi-directional" which means
44         that instead the voice's "backwards" bit is set and the
45         current position heads back towards the start from the end.
46
47         DOSBox 0.74 GUS emulation:
48            - When the current position passes start, go forward again.
49              Thus, setting start == 0 and end == len-1 makes the sample
50              loop properly.
51         GUS MAX:
52            - When the current position was start, and less than the
53              previous position, go forward again. Note this makes it
54              impossible to ping-pong loop a sample starting at 0
55              (or 1 if 16-bit) because when start == 0 the GF1 goes right
56              past the point and into 0xFFF.. without changing
57              direction. To make it work, set start to 2 samples in.
58
59
60     Proper voice programming sequence:
61
62        The SDK doesn't say anything about this, but it seems that the
63        best way to get the voice programmed the way you want without
64        weird side effects, is to stop the voice, program the parameters,
65        and then set the mode as the LAST STEP. If you set the mode, then
66        set the positions and such, you risk the voice immediately going
67        off backwards, or other side effects.
68
69        Unfortuantely because of the way this code is written, you will
70        need to set the mode twice. Once prior to programming, and then
71        as the final step.
72
73
74     Pre-initialized state and "stuck" IRQ: [BUG: FIXME]
75
76        Apparently, if a previous program was using the GUS and left the
77        timers active, or failed to clean up IRQ flags, our test routine
78        will fail to trigger the IRQ with timers and fail the GUS. This
79        can happen if you first run certain demoscene programs like "Dope"
80        or "2nd Reality" then attempt to use this program.
81
82        Someday when you have time, hunt down every possible way to
83        a) forcibly stop the timers b) forcibly clear all pending IRQs
84        and then have the code do just that before the timer test.
85
86        Commenting out the timer test is not an option, since it would
87        then be trivial for some other device to pass the RAM test.
88
89        Note the Interwave SDK and Gravis documents mention a register
90        with a bit you set to clear all pending IRQs at bootup. Maybe
91        that would be of use?
92
93        In the meantime, the solution is to either
94          a) Run ULTRINIT from the ULTRASND directory
95          b) Run this program with no IRQ and DMA, play some audio,
96             then quit, and run again.
97
98
99     DMA transfer programming:
100
101        The GUS SDK shows that you can set a bit to get a DMA terminal
102        count interrupt, meaning an IRQ when the DMA finishes. The
103        actual GUS will set bit 6 (but not fire an IRQ) when the DMA
104        transfer is complete. DOSBox will NOT set bit 6 when DMA TC
105        complete, unless you asked for the IRQ. This is why this code
106        checks both and terminates either then bit 6 is set, or the
107        DMA controller indicates terminal count.
108
109
110     DMA problem on real hardware with DMA channels 5, 6, and 7.  [BUG: FIXME]
111
112        If your ultrasound is configured for high DMA channels, this
113        code fails the DMA test and does not succeed in transferring
114        the test message to GUS DRAM. Yet, high DMA channels work fine
115        in DOSBox.
116
117     Card identification [TODO: FIXME]
118
119        The Gravis SDK mentions several registers that can be used to
120        identify the card (if it is a GUS 3.7 or MAX or later). The
121        GUS MAX has the ability to remove the legacy GUS Classic
122        sample rate limits, which might be of use to you here.
123
124        Also refer to the Linux driver source code on how to go about this process:
125
126        http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/sound/isa/gus/gus_dma.c
127
128
129     SBOS initialization check [TODO: FIXME add to Sound Blaster library]
130
131        Add code where if the DSP version comes back as 0xAA,0xAA, then
132        do a quick check to see if the card is actually a GUS, and if so,
133        fiddle with the "Sound Blaster emulation" registers to turn them
134        off and reset the return value to 0x00 so that future SB testing
135        does not see the GUS as SB.
136
137  */
138
139 #include <stdio.h>
140 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
141 #include <ctype.h>
142 #include <stddef.h>
143 #include <stdlib.h>
144 #include <string.h>
145 #include <unistd.h>
146 #include <malloc.h>
147 #include <assert.h>
148 #include <fcntl.h>
149 #include <math.h>
150 #include <dos.h>
151
152 #include <hw/cpu/cpu.h>
153 #include <hw/dos/dos.h>
154 #include <hw/vga/vga.h>
155 #include <hw/8237/8237.h>               /* 8237 DMA */
156 #include <hw/8254/8254.h>               /* 8254 timer */
157 #include <hw/8259/8259.h>               /* 8259 PIC interrupts */
158 #include <hw/ultrasnd/ultrasnd.h>
159
160 static int debug_on = 0;
161 static int ultrasnd_test_irq_fired = 0;
162 static int ultrasnd_test_irq_n = 0;
163
164 /* actual sample rate table (based on total voices) */
165 const uint16_t ultrasnd_rate_per_voices[33] = {
166     44100, 44100, 44100, 44100,  44100, 44100, 44100, 44100,    /* 0-7 */
167     44100, 44100, 44100, 44100,  44100, 44100, 44100, 41160,    /* 8-15 */
168     38587, 36317, 34300, 32494,  30870, 29400, 28063, 26843,    /* 16-23 */
169     25725, 24696, 23746, 22866,  22050, 21289, 20580, 19916,    /* 24-31 */
170     19293 };                                                    /* 32 */
171
172 struct ultrasnd_ctx ultrasnd_card[MAX_ULTRASND];
173 struct ultrasnd_ctx *ultrasnd_env = NULL;
174 int ultrasnd_inited = 0;
175
176 void ultrasnd_debug(int on) {
177         debug_on = on;
178 }
179
180 uint32_t ultrasnd_dram_16bit_xlate(uint32_t a) {
181         /* Ewwww... */
182         return (a & 0x000C0000) | ((a & 0x3FFFF) >> 1UL);
183 }
184
185 uint32_t ultrasnd_dram_16bit_xlate_from(uint32_t a) {
186         /* Ewwww... */
187         return (a & 0xFFFC0000) | ((a & 0x1FFFF) << 1UL);
188 }
189
190 static void gus_delay(struct ultrasnd_ctx *u) {
191         inp(u->port+0x102);
192         inp(u->port+0x102);
193         inp(u->port+0x102);
194         inp(u->port+0x102);
195         inp(u->port+0x102);
196         inp(u->port+0x102);
197         inp(u->port+0x102);
198         inp(u->port+0x102);
199         inp(u->port+0x102);
200         inp(u->port+0x102);
201         inp(u->port+0x102);
202         inp(u->port+0x102);
203 }
204
205 void ultrasnd_select_voice(struct ultrasnd_ctx *u,uint8_t reg) {
206         outp(u->port+0x102,reg);
207         outp(u->port+0x102,reg); /* NTS: the "gravis ultrasound encyclopedia" recommends doing this... why? */
208         outp(u->port+0x102,reg);
209 }
210
211 void ultrasnd_select_write(struct ultrasnd_ctx *u,uint8_t reg,uint8_t data) {
212         outp(u->port+0x103,reg);
213         outp(u->port+0x105,data);
214         gus_delay(u);
215         outp(u->port+0x105,data);
216 }
217
218 uint16_t ultrasnd_select_read16(struct ultrasnd_ctx *u,uint8_t reg) {
219         outp(u->port+0x103,reg);
220         return inpw(u->port+0x104);
221 }
222
223 void ultrasnd_select_write16(struct ultrasnd_ctx *u,uint8_t reg,uint16_t data) {
224         outp(u->port+0x103,reg);
225         outpw(u->port+0x104,data);
226         gus_delay(u);
227         outpw(u->port+0x104,data);
228 }
229
230 uint8_t ultrasnd_select_read(struct ultrasnd_ctx *u,uint8_t reg) {
231         outp(u->port+0x103,reg);
232         gus_delay(u);
233         return inp(u->port+0x105);
234 }
235
236 uint8_t ultrasnd_selected_read(struct ultrasnd_ctx *u) {
237         return inp(u->port+0x105);
238 }
239
240 unsigned char ultrasnd_peek(struct ultrasnd_ctx *u,uint32_t ofs) {
241         if (u == NULL) return 0xFF;
242         if (ofs & 0xFF000000UL) return 0xFF; /* The GUS only has 24-bit addressing */
243
244         ultrasnd_select_write16(u,0x43,(uint16_t)ofs); /* 0x43: DRAM address low 16 bits */
245         ultrasnd_select_write(u,0x44,(uint8_t)(ofs >> 16UL)); /* 0x44: DRAM address upper 8 bits */
246         return inp(u->port+0x107);
247 }
248
249 void ultrasnd_poke(struct ultrasnd_ctx *u,uint32_t ofs,uint8_t b) {
250         if (u == NULL) return;
251         if (ofs & 0xFF000000UL) return; /* The GUS only has 24-bit addressing */
252
253         ultrasnd_select_write16(u,0x43,(uint16_t)ofs); /* 0x43: DRAM address low 16 bits */
254         ultrasnd_select_write(u,0x44,(uint8_t)(ofs >> 16UL)); /* 0x44: DRAM address upper 8 bits */
255         outp(u->port+0x107,b);
256 }
257
258 int ultrasnd_valid_dma(struct ultrasnd_ctx *u,int8_t i) {
259         switch (i) {
260                 case 1: return 1;
261                 case 3: return 2;
262                 case 5: return 3;
263                 case 6: return 4;
264                 case 7: return 5;
265         };
266         return 0;
267 }
268
269 int ultrasnd_valid_irq(struct ultrasnd_ctx *u,int8_t i) {
270         switch (i) {
271                 case 2: return 1;
272                 case 3: return 3;
273                 case 5: return 2;
274                 case 7: return 4;
275                 case 11: return 5;
276                 case 12: return 6;
277                 case 15: return 7;
278         };
279         return 0;
280 }
281
282 static void interrupt far ultrasnd_test_irq() {
283         ultrasnd_test_irq_fired++;
284
285         /* ack PIC */
286         if (ultrasnd_test_irq_n >= 8) p8259_OCW2(8,P8259_OCW2_NON_SPECIFIC_EOI);
287         p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
288 }
289
290 void ultrasnd_set_active_voices(struct ultrasnd_ctx *u,unsigned char voices) {
291         if (voices < 14) u->active_voices = 14;
292         else if (voices > 32) u->active_voices = 32;
293         else u->active_voices = voices;
294         u->output_rate = ultrasnd_rate_per_voices[u->active_voices];
295         ultrasnd_select_write(u,0x0E,0xC0 | (u->active_voices - 1));
296 }
297
298 /* NOTE: If possible, you are supposed to provide both IRQs and both DMA channels provided by ULTRASND,
299  *       or given by a probing function. However this function also supports basic probing without any
300  *       knowledge of what IRQ is involved. To do that, pass in the context with port number nonzero
301  *       and IRQ and DMA channels set to -1 (unknown).
302  *
303  *       if program_cfg is nonzero, this routine will write the IRQ and DMA configuration registers. */
304 int ultrasnd_probe(struct ultrasnd_ctx *u,int program_cfg) {
305         void (interrupt far *old_irq)() = NULL;
306         unsigned char c1,c2,c2i,c;
307         unsigned int i,patience;
308
309         /* The "Gravis Ultrasound Programmers Encyclopedia" describes a probe function that only
310          * checks whether the onboard RAM can be peek'd and poke'd. Lame. Our test here goes
311          * further to ensure that it looks and acts like a Gravis Ultrasound */
312         if (u == NULL) return 1;
313         if (u->port < 0) return 1;
314         if ((u->port&0xF) != 0) return 1;
315
316         /* this card can only work with certain IRQs */
317         if (u->irq1 >= 0 && ultrasnd_valid_irq(u,u->irq1) == 0) {
318                 if (debug_on) fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ %u is not a valid GUS IRQ.\n",u->port);
319                 return 1;
320         }
321         if (u->irq2 >= 0 && ultrasnd_valid_irq(u,u->irq2) == 0) {
322                 if (debug_on) fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ %u is not a valid GUS IRQ.\n",u->port,u->irq2);
323                 return 1;
324         }
325
326         /* reset the GF1 */
327         ultrasnd_select_write(u,0x4C,0x00); /* 0x4C: reset register -> master reset (bit 0=0) disable DAC (bit 1=0) master IRQ disable (bit 2=0) */
328         t8254_wait(t8254_us2ticks(20000)); /* wait 20ms for good measure, most docs imply 14 CPU cycles via IN statements but I don't think that's enough */
329         c1 = ultrasnd_selected_read(u); /* FIXME: Reading the reg back immediately works correctly, but writing the selector register and reading back returns incorrect data? Is that DOSBox being weird or does the GUS actually do that? */
330
331         /* FIXME: DOSBox's emulation implies that the timers fire the IRQ anyway even if we don't set bit 2. Is that what the actual GUS does or is DOSBox full of it on that matter? */
332         c2i = 0x03 | (u->irq1 >= 0 ? 0x4 : 0x0); /* don't set bit 2 unless we intend to actually service the IRQ interrupt */
333         ultrasnd_select_write(u,0x4C,c2i); /* 0x4C: reset register -> end reset (bit 0=1) enable DAC (bit 1=1) master IRQ enable (bit 2) */
334         t8254_wait(t8254_us2ticks(20000)); /* wait 20ms for good measure, most docs imply 14 CPU cycles via IN statements but I don't think that's enough */
335         c2 = ultrasnd_selected_read(u); /* FIXME: Reading the reg back immediately works correctly, but writing the selector register and reading back returns incorrect data? Is that DOSBox being weird or does the GUS actually do that? */
336
337         if (c1 == 0xFF && c2 == 0xFF) {
338                 if (debug_on) fprintf(stderr,"Gravis Ultrasound[0x%03x]: Read back 0xFF during reset, so it's probably not there\n",u->port);
339                 return 1;
340         }
341
342         /* FIXME: The ultrasound SDK documentation never says anything about being able to read the registers.
343          *        The programmer's encyclopedia though implies you can. So then, can we hit the reset register
344          *        and read it back to know it's there? [DOSBox emulation: yes, we can!] */
345         /* Did we really write Ultrasound register 0x4C or is it something else? */
346         if ((c1&7) != 0 || (c2&7) != c2i) {
347                 /* HACK: DOSBox 0.74 emulates a GUS that happily leaves your bits set after reset.
348                          The Real Thing however resets your bits as part of the reset. So what you
349                          will likely read back is only one of the bits set, and you will need to
350                          turn on the DAC by reading and writing again. */
351                 if (c1 == 0 && c2 == 1) {
352                         ultrasnd_select_write(u,0x4C,c2i); /* 0x4C: reset register -> end reset (bit 0=1) enable DAC (bit 1=1) master IRQ enable (bit 2) */
353                         t8254_wait(t8254_us2ticks(20000)); /* wait 20ms for good measure, most docs imply 14 CPU cycles via IN statements but I don't think that's enough */
354                         c2 = ultrasnd_selected_read(u); /* FIXME: Reading the reg back immediately works correctly, but writing the selector register and reading back returns incorrect data? Is that DOSBox being weird or does the GUS actually do that? */
355                         if ((c2&7) != c2i) {
356                                 fprintf(stderr,"Gravis Ultrasound[0x%03x]: Reset register OK but DAC enable bit is stuck off, which means that your GUS is probably not going to output the audio we are playing. If UltraInit has been showing error messages you may want to check that the line/speaker output amplifier is OK. c1=0x%02x c2=%02x\n",u->port,c1,c2);
357                         }
358                 }
359                 else {
360                         if (debug_on) fprintf(stderr,"Gravis Ultrasound[0x%03x]: Reset register is supposed to be read/write. This is probably not a GUS. c1=0x%02x c2=%02x\n",u->port,c1,c2);
361                         return 1;
362                 }
363         }
364
365         /* the tests below can cause interrupts. so hook the IRQ */
366         if (u->irq1 >= 0) {
367                 ultrasnd_test_irq_fired = 0;
368                 ultrasnd_test_irq_n = u->irq1;
369                 old_irq = _dos_getvect(irq2int(u->irq1));
370                 _dos_setvect(irq2int(u->irq1),ultrasnd_test_irq);
371                 /* perhaps a probing test prior to this call fired off the IRQ, but we failed to hook it because we didn't know. */
372                 _cli();
373                 p8259_OCW2(u->irq1,P8259_OCW2_SPECIFIC_EOI | (u->irq1&7));
374                 if (u->irq1 >= 8) p8259_OCW2(2,P8259_OCW2_SPECIFIC_EOI | 2); /* IRQ 8-15 -> IRQ 2 chaining */
375                 _sti();
376                 p8259_unmask(u->irq1);
377                 t8254_wait(t8254_us2ticks(1000)); /* 1ms */
378                 /* in case we did unmask an IRQ, it probably fired about now and bumped up our IRQ counter */
379                 _cli();
380                 if (ultrasnd_test_irq_fired != 0 && debug_on)
381                         fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ %d was apparently stuck prior to this probe function, and I just got it un-stuck\n",u->port,u->irq1);
382                 ultrasnd_test_irq_fired = 0;
383                 _sti();
384         }
385
386         if (u->irq1 >= 0 && program_cfg) {
387                 /* now use the Mixer register to enable line out, and to select the IRQ control register.
388                  * we can't actually read back the current configuration, because the registers are of
389                  * course write only. but we can program them to match what we know about IRQ and DMA
390                  * settings */
391                 outp(u->port+0x000,0x40 | 0x08);        /* bit 1: 0=enable line out, bit 0: 0=enable line in, bit 3: 1=enable latches  bit 6: 1=next I/O goes to IRQ latches */
392                 c1 = ultrasnd_valid_irq(u,u->irq1);
393                 if (u->irq2 == u->irq1) c1 |= 0x40; /* same IRQ */
394                 else c1 |= ultrasnd_valid_irq(u,u->irq2) << 3;
395                 outp(u->port+0x00B,c1);
396
397                 outp(u->port+0x000,0x00 | 0x08);        /* bit 1: 0=enable line out, bit 0: 0=enable line in, bit 3: 1=enable latches  bit 6: 0=next I/O goes to DMA latches */
398                 c1 = ultrasnd_valid_dma(u,u->dma1);
399                 if (u->dma2 == u->dma1) c1 |= 0x40; /* same IRQ */
400                 else c1 |= ultrasnd_valid_dma(u,u->dma2) << 3;
401                 outp(u->port+0x00B,c1);
402         }
403         else {
404                 /* just enable line out, do not program the IRQ and DMA settings */
405                 outp(u->port+0x000,0x00 | 0x08);        /* bit 1: 0=enable line out, bit 0: 0=enable line in, bit 3: 1=enable latches  bit 6: 1=next I/O goes to DMA latches */
406         }
407
408         /* clear pending or active DMA, in case the reset didn't do anything with it */
409         ultrasnd_select_write(u,0x41,0x00);     /* disable any DMA */
410         ultrasnd_select_read(u,0x41); /* read to clear DMA terminal count---even though we didn't ask for TC IRQ */
411
412         /* stop all voices, in case the last program left them running
413            and firing off IRQs (like most MS-DOS GUS demos, apparently) */
414         for (i=0;i < 32;i++) {
415                 ultrasnd_select_voice(u,i);
416                 ultrasnd_select_write(u,0x06,0);
417                 ultrasnd_select_write(u,0x07,0);
418                 ultrasnd_select_write(u,0x08,0);
419                 ultrasnd_select_write16(u,0x09,0);
420                 ultrasnd_select_write(u,0x00,3);
421                 ultrasnd_select_write(u,0x0D,0);
422                 ultrasnd_select_read(u,0x8D);
423         }
424
425         /* clear all IRQ events */
426         patience = 5000;
427         ultrasnd_select_voice(u,0);
428         do {
429                 if (--patience == 0) {
430                         if (debug_on) fprintf(stderr,"GUS: Ran out of patience attempting to clear interrupt events\n");
431                         break;
432                 }
433
434                 _cli();
435                 if ((c1 = (ultrasnd_select_read(u,0x8F) & 0xC0)) != 0xC0) {
436                         ultrasnd_select_voice(u,c1&0x1F);
437                         ultrasnd_select_read(u,0x8D);
438                         ultrasnd_select_write(u,0x00,3);
439                         _sti();
440                 }
441         } while (c1 != 0xC0);
442         c1 = inp(u->port+0x006);
443         _sti();
444
445         /* any IRQs that did happen, ignore them */
446         ultrasnd_test_irq_fired = 0;
447
448         /* Gravis SDK also shows there are two timer registers. When loaded by the application they count up to 0xFF then generate an IRQ.
449          * So if we load them and no counting happens, it's not a GUS. */
450         outp(u->port+0x008,0x04); /* select "timer stuff" */
451         outp(u->port+0x009,0xE0); /* clear timer IRQ, mask off timer 1 & 2 */
452         ultrasnd_select_write(u,0x45,0x00); /* disable timer 1 & 2 IRQ */
453         ultrasnd_select_write(u,0x46,0x80); /* load timer 1 */
454         ultrasnd_select_write(u,0x47,0x80); /* load timer 2 */
455         ultrasnd_select_write(u,0x45,0x0C); /* enable timer 1 & 2 IRQ */
456         outp(u->port+0x008,0x04); /* select "timer stuff" */
457         outp(u->port+0x009,0x03); /* unmask timer IRQs, clear reset, start timers */
458
459         if ((inp(u->port+0x006)&0xC) != 0)
460                 fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ status register still shows pending IRQ for timers despite clearing and resetting them\n",u->port);
461         if (u->irq1 >= 0 && ultrasnd_test_irq_fired != 0)
462                 fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ fired at or before the timer was enabled. Did something else happen?\n",u->port,ultrasnd_test_irq_fired);
463
464         /* wait 500ms, more than enough time for the timers to count up to 0xFF and signal IRQ */
465         /* NTS: The SDK doc doesn't say, but apparently the timer will hit 0xFF, fire the IRQ, then reset to 0 and count up again (or else DOSBox is mis-emulating the GUS) */
466         for (i=0,c1=0;i < 500 && (c1&0xC) != 0xC;i++) {
467                 t8254_wait(t8254_us2ticks(1000)); /* 1ms */
468                 c1 = inp(u->port+0x006); /* IRQ status */
469         }
470         ultrasnd_select_write(u,0x45,0x00); /* disable timer 1 & 2 IRQ */
471         outp(u->port+0x008,0x04); /* select "timer stuff" */
472         outp(u->port+0x009,0xE0); /* clear timer IRQ, mask off timer 1 & 2 */
473         if ((c1&0xC) != 0xC) {
474                 if (debug_on) fprintf(stderr,"Gravis Ultrasound[0x%03x]: Timer readback fail 0x%02x\n",c1);
475                 goto timerfail;
476         }
477         if (u->irq1 >= 0 && ultrasnd_test_irq_fired == 0) {
478                 if (debug_on) fprintf(stderr,"Gravis Ultrasound[0x%03x]: Timer never signalled IRQ\n");
479                 goto irqfail;
480         }
481
482         /* wait for the timer to stop */
483         patience = 100;
484         do {
485                 t8254_wait(t8254_us2ticks(1000)); /* 1ms */
486                 c = inp(u->port+0x008);
487                 if (--patience == 0) {
488                         fprintf(stderr,"Gravis Ultrasound[0x%03x]: Timeout waiting for timers to stop\n",u->port);
489                         break;
490                 }
491         } while ((c&0x60) == 0x00);
492
493         /* check the RAM. is there at least a 4KB region we can peek and poke? */
494         /* FIXME: According to Wikipedia there are versions of the card that don't have RAM at all (just ROM). How do we work with those? */
495         for (i=0;i < 0x1000U;i++) ultrasnd_poke(u,i,(uint8_t)(i^0x55));
496         for (i=0;i < 0x1000U;i++) if (ultrasnd_peek(u,i) != ((uint8_t)i^0x55)) goto ramfail;
497
498         /* unless we know otherwise, samples cannot straddle a 256KB boundary */
499         u->boundary256k = 1;
500
501         /* initial versions came stock with 256KB with support for additional RAM in 256KB increments */
502         u->total_ram = 256UL << 10UL; /* 256KB */
503         for (i=1;i < ((8UL << 20UL) >> 18UL);i++) { /* test up to 8MB (8MB / 256KB banks) */
504                 uint32_t ofs = (uint32_t)i << (uint32_t)18UL;
505
506                 /* put sentry value at base to detect address wrapping */
507                 ultrasnd_poke(u,0,0x55);
508                 ultrasnd_poke(u,1,0xAA);
509
510                 /* now write a test value to the base of the 256KB bank */
511                 ultrasnd_poke(u,ofs,0x33);
512                 ultrasnd_poke(u,ofs+1,0x99);
513
514                 /* if the value at base changed, then address wrapping occurred
515                  * and the test immediately after would falsely detect RAM there */
516                 if (ultrasnd_peek(u,0) != 0x55 || ultrasnd_peek(u,1) != 0xAA)
517                         break;
518
519                 /* if the value at the bank is not what we wrote, then RAM isn't there */
520                 if (ultrasnd_peek(u,ofs) != 0x33 || ultrasnd_peek(u,ofs+1) != 0x99)
521                         break;
522
523                 /* final test: write to the bytes at the end of the bank and see if they made it */
524                 ultrasnd_poke(u,ofs+0x3FFFE,0x11);
525                 ultrasnd_poke(u,ofs+0x3FFFF,0x55);
526                 if (ultrasnd_peek(u,ofs+0x3FFFE) != 0x11 || ultrasnd_peek(u,ofs+0x3FFFF) != 0x55)
527                         break;
528
529                 /* it's RAM. count it. move on */
530                 u->total_ram = ofs + 0x40000UL;
531         }
532
533         /* Next: the DMA test */
534         if (u->dma1 >= 0) {
535                 static const char *testing = "Test message 1234 ABCD AaaababbabaCcocococo. If you can read this the DMA transfer worked.";
536                 unsigned char FAR *buffer,FAR *str;
537                 const unsigned int testlen = 512;
538
539                 if ((str=buffer=ultrasnd_dram_buffer_alloc(u,testlen)) != NULL) {
540                         char c;
541                         int i,len;
542                         unsigned int patience,rem;
543                         uint32_t phys = u->dram_xfer_a->phys;
544                         uint32_t lin = (uint32_t)u->dram_xfer_a->lin;
545
546 #if TARGET_MSDOS == 32
547                         memset(buffer,128,testlen);
548 #else
549                         _fmemset(buffer,128,testlen);
550 #endif
551
552                         _cli();
553
554                         /* Stop GUS DMA */
555                         ultrasnd_select_write(u,0x41,0x00);     /* disable any DMA */
556                         ultrasnd_select_read(u,0x41); /* read to clear DMA terminal count---even though we didn't ask for TC IRQ */
557
558                         /* clear GUS DRAM so that we're not comparing stale data */
559                         for (i=0;i < 0x2000;i++) ultrasnd_poke(u,i,0x00);
560
561                         /* Fill the buffer with a chosen phrase */
562                         len = strlen(testing)+1;
563                         for (i=0;i < len;i++) str[i] = testing[i];
564
565                         /* Now initiate a DMA transfer (host) */
566                         outp(d8237_ioport(u->dma1,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(u->dma1) | D8237_MASK_SET); /* mask */
567                         outp(d8237_ioport(u->dma1,D8237_REG_W_WRITE_MODE),
568                                         D8237_MODER_CHANNEL(u->dma1) |
569                                         D8237_MODER_TRANSFER(D8237_MODER_XFER_READ) | /* "READ" from system memory */
570                                         D8237_MODER_MODESEL(D8237_MODER_MODESEL_DEMAND));
571                         d8237_write_base(u->dma1,u->dram_xfer_a->phys); /* RAM location with not much around */
572                         d8237_write_count(u->dma1,testlen);
573
574                         /* Now initiate a DMA transfer (GUS DRAM) */
575                         ultrasnd_select_write(u,0x41,(u->dma1 >= 4 ? 4 : 0)); /* data size in bit 2, writing to DRAM, enable DMA */
576                         if (u->dma1 >= 4) /* Ugh, even DMA is subject to Gravis 16-bit translation */
577                                 ultrasnd_select_write16(u,0x42,ultrasnd_dram_16bit_xlate(0x1000)>>4);
578                         else
579                                 ultrasnd_select_write16(u,0x42,0x1000>>4);
580                         ultrasnd_select_write(u,0x41,(u->dma1 >= 4 ? 4 : 0) | 0x1); /* data size in bit 2, writing to DRAM, enable DMA */
581
582                         /* GO! */
583                         outp(d8237_ioport(u->dma1,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(u->dma1)); /* unmask */
584
585                         /* wait for the GUS to indicate DMA terminal count */
586                         /* Note that DOSBox's emulation of a GUS does not indicate DMA TC, since we didn't ask for it, but the actual GF1 chipset
587                          * will return with bit 6 set whether we asked for TC IRQ or not. */
588                         patience = 1000;
589                         do {
590                                 rem = d8237_read_count(u->dma1);
591                                 if (rem == 0 || rem >= 0xFFFE)
592                                         break;
593
594                                 t8254_wait(t8254_us2ticks(1000));
595                         } while (--patience != 0);
596                         if (rem >= 0xFFFE) rem = 0; /* the DMA counter might return 0xFFFF when terminal count reached */
597
598                         /* mask DMA channel again */
599                         outp(d8237_ioport(u->dma1,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(u->dma1) | D8237_MASK_SET); /* mask */
600
601                         /* stop DMA */
602                         ultrasnd_select_write(u,0x41,0x00);
603                         ultrasnd_select_read(u,0x41); /* read to clear DMA terminal count---even though we didn't ask for TC IRQ */
604
605                         _sti();
606                         ultrasnd_dram_buffer_free(u);
607
608                         if ((unsigned int)rem >= testlen) goto dmafail;
609                         else if (rem != 0) {
610                                 fprintf(stderr,"Gravis Ultrasound[0x%03x]: DMA transfer is incomplete (%u/%u), probably stalled out during transfer. You should choose another DMA channel.\n",u->port,rem,testlen);
611                                 goto dmafail;
612                         }
613
614                         /* OK then, did our message make it into DRAM? */
615                         for (i=0;i < len;i++) {
616                                 c = ultrasnd_peek(u,i+0x1000);
617                                 if (c != testing[i]) {
618                                         fprintf(stderr,"Gravis Ultrasound[0x%03x]: DMA transfer corrupted test data (phys=%8lx lin=%8lx)\n",u->port,(unsigned long)phys,(unsigned long)lin);
619                                         fprintf(stderr,"  I wrote: '%s'\n",testing);
620                                         fprintf(stderr," Got back: '");
621                                         for (i=0;i < len;i++) fprintf(stderr,"%c",ultrasnd_peek(u,i+0x1000));
622                                         fprintf(stderr,"'\n");
623                                         goto dmafail;
624                                 }
625                         }
626                 }
627                 else {
628                         fprintf(stderr,"Gravis Ultrasound[0x%03x]: Unable to allocate buffer for DMA testing\n",u->port);
629                 }
630         }
631
632         /* read IRQ status register. failure to clear IRQ conditions is something to be concerned about */
633         c1 = inp(u->port+0x006);
634         if (c1 != 0x00) fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ status register nonzero after init. The probe function missed something.\n",u->port);
635
636         if (u->irq1 >= 0) {
637                 _dos_setvect(irq2int(u->irq1),old_irq);
638                 p8259_mask(u->irq1);
639         }
640
641         if (u->dma1 >= 0)
642                 u->use_dma = 1;
643         else
644                 u->use_dma = 0;
645
646         for (i=0;i < 32;i++) u->voicemode[i] = 0;
647         ultrasnd_set_active_voices(u,14);
648         return 0;
649 dmafail:
650         fprintf(stderr,"Gravis Ultrasound[0x%03x]: DMA test failed, nothing was transferred\n",u->port);
651         goto commoncleanup;
652 irqfail:
653         fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ test failed, timers did not signal IRQ handler\n",u->port);
654         goto commoncleanup;
655 ramfail:
656         fprintf(stderr,"Gravis Ultrasound[0x%03x]: RAM test failed\n",u->port);
657         goto commoncleanup;
658 timerfail:
659         fprintf(stderr,"Gravis Ultrasound[0x%03x]: Timer test failed (IRQstatus=0x%02X)\n",u->port,inp(u->port+0x006));
660         goto commoncleanup;
661 commoncleanup:
662         if (u->irq1 >= 0) {
663                 unsigned char irr,i;
664
665                 _dos_setvect(irq2int(u->irq1),old_irq);
666                 p8259_mask(u->irq1);
667
668                 /* problem: the GUS's IRQ acts like a level-triggered interrupt. if we don't
669                  * take pains to clear it, it remains "stuck" and nobody else can signal that IRQ */
670
671                 ultrasnd_select_write(u,0x4C,0x00); /* 0x4C: reset register -> master reset (bit 0=0) disable DAC (bit 1=0) master IRQ disable (bit 2=0) */
672                 t8254_wait(t8254_us2ticks(20000)); /* wait 20ms for good measure, most docs imply 14 CPU cycles via IN statements but I don't think that's enough */
673                 ultrasnd_select_write(u,0x4C,0x01); /* 0x4C: reset register -> end reset (bit 0=1) enable DAC (bit 1=1) master IRQ enable (bit 2) */
674                 t8254_wait(t8254_us2ticks(20000)); /* wait 20ms for good measure, most docs imply 14 CPU cycles via IN statements but I don't think that's enough */
675
676                 /* clear pending or active DMA, in case the reset didn't do anything with it */
677                 ultrasnd_select_write(u,0x41,0x00);     /* disable any DMA */
678                 ultrasnd_select_read(u,0x41); /* read to clear DMA terminal count---even though we didn't ask for TC IRQ */
679
680                 /* Gravis SDK also shows there are two timer registers. When loaded by the application they count up to 0xFF then generate an IRQ.
681                  * So if we load them and no counting happens, it's not a GUS. */
682                 outp(u->port+0x008,0x04); /* select "timer stuff" */
683                 outp(u->port+0x009,0xE0); /* clear timer IRQ, mask off timer 1 & 2 */
684                 ultrasnd_select_write(u,0x45,0x00); /* disable timer 1 & 2 IRQ */
685                 outp(u->port+0x008,0x04); /* select "timer stuff" */
686                 outp(u->port+0x009,0xE0); /* clear timer IRQ, mask off timer 1 & 2 */
687
688                 /* stop all voices, in case the last program left them running
689                    and firing off IRQs (like most MS-DOS GUS demos, apparently) */
690                 for (i=0;i < 32;i++) {
691                         ultrasnd_select_voice(u,i);
692                         ultrasnd_select_write(u,0x06,0);
693                         ultrasnd_select_write(u,0x07,0);
694                         ultrasnd_select_write(u,0x08,0);
695                         ultrasnd_select_write16(u,0x09,0);
696                         ultrasnd_select_write(u,0x00,3);
697                         ultrasnd_select_write(u,0x0D,0);
698                         ultrasnd_select_read(u,0x8D);
699                 }
700
701                 /* clear all IRQ events */
702                 patience = 5000;
703                 ultrasnd_select_voice(u,0);
704                 do {
705                         if (--patience == 0) {
706                                 if (debug_on) fprintf(stderr,"GUS: Ran out of patience attempting to clear interrupt events\n");
707                                 break;
708                         }
709
710                         _cli();
711                         if ((c1 = (ultrasnd_select_read(u,0x8F) & 0xC0)) != 0xC0) {
712                                 ultrasnd_select_voice(u,c1&0x1F);
713                                 ultrasnd_select_read(u,0x8D);
714                                 ultrasnd_select_write(u,0x00,3);
715                                 _sti();
716                         }
717                 } while (c1 != 0xC0);
718
719                 /* suck up all possible IRQ events */
720                 for (i=0;i < 255;i++) c1 = inp(u->port+0x006); /* IRQ status */
721
722                 _sti();
723
724                 /* the IRQ might actually be waiting to be ACKed.
725                  * if we don't take care of this, conflicts can happen, like the PLAYMP3
726                  * program probing for Ultrasnd then SoundBlaster, and the un-acked IRQ
727                  * prevents the Sound Blaster (on the same IRQ) from getting it's IRQ signal.
728                  * This is more likely than you think considering DOSBox's default configuration */
729                 irr = (unsigned short)p8259_read_IRR(u->irq1);
730                 if (irr & (1 << (u->irq1 & 7))) {
731                         fprintf(stderr,"Gravis Ultrasound[0x%03x]: Stray IRQ signal\n",u->port);
732                         p8259_OCW2(u->irq1,P8259_OCW2_SPECIFIC_EOI|(u->irq1&7));
733                 }
734
735                 irr = (unsigned short)p8259_read_IRR(u->irq1);
736                 if (irr & (1 << (u->irq1 & 7))) {
737                         fprintf(stderr,"Gravis Ultrasound[0x%03x]: Stray IRQ signal...again!\n",u->port);
738                         p8259_OCW2(u->irq1,P8259_OCW2_SPECIFIC_EOI|(u->irq1&7));
739                 }
740         }
741         return 1;
742 }
743
744 int ultrasnd_irq_taken(int irq) {
745         int i;
746
747         for (i=0;i < MAX_ULTRASND;i++) {
748                 struct ultrasnd_ctx *u = &ultrasnd_card[i];
749                 if (u->irq1 == irq || u->irq2 == irq)
750                         return 1;
751         }
752
753         return 0;
754 }
755
756 int ultrasnd_dma_taken(int dma) {
757         int i;
758
759         for (i=0;i < MAX_ULTRASND;i++) {
760                 struct ultrasnd_ctx *u = &ultrasnd_card[i];
761                 if (u->dma1 == dma || u->dma2 == dma)
762                         return 1;
763         }
764
765         return 0;
766 }
767
768 int ultrasnd_port_taken(int port) {
769         int i;
770
771         for (i=0;i < MAX_ULTRASND;i++) {
772                 struct ultrasnd_ctx *u = &ultrasnd_card[i];
773                 if (u->port == port)
774                         return 1;
775         }
776
777         return 0;
778 }
779
780 void ultrasnd_init_ctx(struct ultrasnd_ctx *u) {
781         u->port = -1;
782         u->use_dma = 0;
783         u->dma1 = u->dma2 = -1;
784         u->irq1 = u->irq2 = -1;
785         u->dram_xfer_a = NULL;
786 }
787
788 void ultrasnd_free_card(struct ultrasnd_ctx *u) {
789         ultrasnd_dram_buffer_free(u);
790         ultrasnd_init_ctx(u);
791         if (u == ultrasnd_env) ultrasnd_env = NULL;
792 }
793
794 int ultrasnd_card_taken(struct ultrasnd_ctx *u) {
795         return (u->port >= 0);
796 }
797
798 int init_ultrasnd() {
799         int i;
800
801         if (!ultrasnd_inited) {
802                 ultrasnd_inited = 1;
803                 for (i=0;i < MAX_ULTRASND;i++)
804                         ultrasnd_init_ctx(&ultrasnd_card[i]);
805         }
806
807         return 1;
808 }
809
810 struct ultrasnd_ctx *ultrasnd_alloc_card() {
811         int i;
812
813         for (i=0;i < MAX_ULTRASND;i++) {
814                 if (!ultrasnd_card_taken(&ultrasnd_card[i]))
815                         return &ultrasnd_card[i];
816         }
817
818         return NULL;
819 }
820
821 static void interrupt far dummy_irq_hi() {
822         p8259_OCW2(8,P8259_OCW2_NON_SPECIFIC_EOI);
823         p8259_OCW2(2,P8259_OCW2_NON_SPECIFIC_EOI);
824 }
825
826 static void interrupt far dummy_irq() {
827         p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
828 }
829
830 /* updates a bitmask on what IRQs have fired on their own (and therefore are not fired by the GUS).
831  * also returns a bitmask of "stuck" interrupts, which is important given my comments below on
832  * DOSBox and the GUS's persistent IRQ signal once timers have been triggered */
833 static unsigned short ultrasnd_irq_watch(unsigned short *eirq) {
834         void far *oldvec[16] = {NULL}; /* Apparently some systems including DOSBox have masked IRQs pointing to NULL interrupt vectors. So to properly test we have to put a dummy there. Ewwwww... */
835         unsigned short irr,stuck = 0,irq,intv;
836         unsigned int patience = 0;
837         unsigned char ml,mh;
838 #if TARGET_MSDOS == 32
839         uint32_t *intvec = (uint32_t*)0x00000000;
840 #else
841         uint32_t far *intvec = (uint32_t far *)MK_FP(0x0000,0x000);
842 #endif
843
844         for (irq=0;irq < 16;irq++) {
845                 intv = irq2int(irq);
846                 /* read the interrupt table directly. assume the DOS extender (if 32-bit) would translate getvect() and cause problems */
847                 if (intvec[intv] == 0x00000000UL) {
848                         oldvec[irq] = _dos_getvect(intv);
849                         if (irq >= 8) _dos_setvect(intv,dummy_irq_hi);
850                         else _dos_setvect(intv,dummy_irq);
851                 }
852                 else {
853                         oldvec[irq] = NULL;
854                 }
855         }
856
857         /* BUG: DOSBox's emulation (and possibly the real thing) fire the IRQ
858          *      for the timer even if we don't set Master IRQ enable. This
859          *      results in the IRQ being stuck active but masked off. So what
860          *      we have to do is unmask the IRQ long enough for it to fire,
861          *      then re-mask it for the activity test. Doing this also means that
862          *      if the IRQ was active for something else, then that something
863          *      else will have it's interrupt serviced properly. Else, if it
864          *      was the GUS, then this lets the PIC get the IRQ signal out of
865          *      it's way to allow the GUS to fire again. */
866
867         _cli();
868         ml = p8259_read_mask(0);        /* IRQ0-7 */
869         mh = p8259_read_mask(8);        /* IRQ8-15 */
870         p8259_write_mask(0,0x00);       /* unmask all interrupts, give the IRQ a chance to fire. keep a record of any IRQs that remain stuck */
871         p8259_write_mask(8,0x00);
872         _sti();
873         stuck = 0xFFFF;
874         for (patience=0;patience < 250;patience++) {
875                 t8254_wait(t8254_us2ticks(1000));
876                 _cli();
877                 irr  = (unsigned short)p8259_read_IRR(0);
878                 irr |= (unsigned short)p8259_read_IRR(8) << 8U;
879                 _sti();
880                 stuck &= irr;
881         }
882         /* issue a specific EOI for any interrupt that remains stuck and unserviced */
883         for (irq=2;irq <= 15;irq++) {
884                 if (irq == 2 || irq == 9) {
885                         /* do not disturb the IRQ 8-15 -> IRQ 2 chain or IRQ 9 weirdness. GUS cards don't use IRQ 9 anyway. */
886                 }
887                 else if (stuck & (1U << irq)) {
888                         _cli();
889                         p8259_OCW2(irq,P8259_OCW2_SPECIFIC_EOI | (irq&7));
890                         if (irq >= 8) p8259_OCW2(2,P8259_OCW2_SPECIFIC_EOI | 2); /* IRQ 8-15 -> IRQ 2 chaining */
891                         _sti(); /* then give the EOI'd IRQ a chance to clear */
892                 }
893         }
894         if (eirq != NULL) {
895                 _cli();
896                 /* now carry out the test and note interrupts as they happen */
897                 p8259_write_mask(0,0xFF);       /* mask off all interrupts */
898                 p8259_write_mask(8,0xFF);
899                 patience = 250;
900                 do {
901                         t8254_wait(t8254_us2ticks(1000));
902
903                         irr  = (unsigned short)p8259_read_IRR(0);
904                         irr |= (unsigned short)p8259_read_IRR(8) << 8U;
905                         for (irq=0;irq < 16;irq++) {
906                                 if (stuck & (1U << irq)) {
907                                 }
908                                 else if (irr & (1U << irq)) {
909                                         *eirq |= 1U << irq;
910                                 }
911                         }
912                 } while (--patience != 0);
913         }
914 //      fprintf(stdout,"Pre-test IRQ elimination: 0x%04X irr=0x%04x stuck=0x%04x\n",*eirq,irr,stuck);
915
916         /* restore interrupt mask */
917         p8259_write_mask(0,ml);
918         p8259_write_mask(8,mh);
919         _sti();
920
921         for (irq=0;irq < 16;irq++) {
922                 if (oldvec[irq] != NULL) {
923                         intv = irq2int(irq);
924                         intvec[intv] = 0x00000000UL;
925                 }
926         }
927
928         return stuck;
929 }
930
931 int ultrasnd_test_irq_timer(struct ultrasnd_ctx *u,int irq) {
932         unsigned char c1;
933         unsigned int i;
934
935         i  = (unsigned short)p8259_read_IRR(0);
936         i |= (unsigned short)p8259_read_IRR(8) << 8U;
937         if (i & (1 << irq)) {
938                 if (debug_on) fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ timer test cannot work, IRQ %u already fired\n",u->port,irq);
939                 return 0;
940         }
941
942         _cli();
943         p8259_mask(irq);
944
945         /* Gravis SDK also shows there are two timer registers. When loaded by the application they count up to 0xFF then generate an IRQ.
946          * So if we load them and no counting happens, it's not a GUS. */
947         outp(u->port+0x008,0x04); /* select "timer stuff" */
948         outp(u->port+0x009,0xE0); /* clear timer IRQ, mask off timer 1 & 2 */
949         ultrasnd_select_write(u,0x45,0x00); /* disable timer 1 & 2 IRQ */
950         ultrasnd_select_write(u,0x46,0xFE); /* load timer 1 */
951         ultrasnd_select_write(u,0x47,0xFE); /* load timer 2 */
952         ultrasnd_select_write(u,0x45,0x0C); /* enable timer 1 & 2 IRQ */
953         outp(u->port+0x008,0x04); /* select "timer stuff" */
954         outp(u->port+0x009,0x03); /* unmask timer IRQs, clear reset, start timers */
955
956         /* wait 50ms, more than enough time for the timers to count up to 0xFF and signal IRQ */
957         for (i=0;i < 500 && (c1&0xC) != 0xC;i++) {
958                 t8254_wait(t8254_us2ticks(1000)); /* 1ms */
959                 c1 = inp(u->port+0x006); /* IRQ status */
960         }
961         ultrasnd_select_write(u,0x45,0x00); /* disable timer 1 & 2 IRQ */
962         outp(u->port+0x008,0x04); /* select "timer stuff" */
963         outp(u->port+0x009,0xE0); /* clear timer IRQ, mask off timer 1 & 2 */
964         if ((c1&0xC) != 0xC) {
965                 if (debug_on) fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ timer test failed, timers did not complete (0x%02x)\n",u->port,c1);
966                 return 0;
967         }
968
969         i  = (unsigned short)p8259_read_IRR(0);
970         i |= (unsigned short)p8259_read_IRR(8) << 8U;
971         if (!(i & (1 << irq))) {
972 //              fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ timer test failed, IRQ %d did not fire\n",u->port,irq);
973                 return 0;
974         }
975
976         return 1;
977 }
978
979 struct ultrasnd_ctx *ultrasnd_try_base(uint16_t base) {
980         unsigned char irq_tries[] = {2,3,5,7,11,12,15},tri;
981         unsigned short eliminated_irq = 0U,stuck,iv,i,cc;
982         struct ultrasnd_ctx *u;
983
984         if (ultrasnd_port_taken(base))
985                 return NULL;
986         if ((u = ultrasnd_alloc_card()) == NULL)
987                 return NULL;
988
989         ultrasnd_init_ctx(u);
990         u->port = base;
991
992         if (u->irq1 < 0) {
993                 /* prior to probing, take note of IRQs that fire without help from the GUS.
994                  * ignore return value (stuck IRQs) */
995                 ultrasnd_irq_watch(&eliminated_irq);
996         }
997
998         if (ultrasnd_probe(u,0)) {
999                 ultrasnd_free_card(u);
1000                 return NULL;
1001         }
1002
1003         if (u->irq1 < 0) {
1004                 /* FIXME: DOSBox 0.74: This code hangs somewhere in here if auto-detecting a GUS configured on IRQ 11, or 15.
1005                  *        Update: The vector patching code in the watch function fixes it for the most part---but if you run
1006                  *        the real-mode version and then the protected mode version, the IRQ hang will occur again. */
1007                 for (cc=0;u->irq1 < 0 && cc < 2;cc++) {
1008                         /* probe again, updating the eliminated mask but also noting which IRQs are stuck.
1009                          * if DOSBox's emulation is correct, the GUS will persist in it's IRQ signalling
1010                          * because of our timer testing and the stuck IRQ might be the one we're looking for. */
1011                         stuck = ultrasnd_irq_watch(NULL);
1012                         if (stuck == 0)
1013                                 break;
1014                         else if ((stuck & (stuck - 1)) == 0) { /* if only 1 bit set */
1015                                 i=0;
1016                                 for (iv=0;iv < 16;iv++) {
1017                                         if (stuck & (1 << iv)) {
1018                                                 i = iv;
1019                                                 break;
1020                                         }
1021                                 }
1022
1023                                 if ((eliminated_irq & (1 << iv)) == 0) {
1024                                         if (ultrasnd_valid_irq(u,i) != 0 && ultrasnd_test_irq_timer(u,i))
1025                                                 u->irq1 = i;
1026                                         else
1027                                                 eliminated_irq |= 1 << iv;
1028
1029                                         stuck = ultrasnd_irq_watch(NULL);
1030                                 }
1031                         }
1032                         else {
1033                                 break; /* we'll have to try another way */
1034                         }
1035                 }
1036
1037                 for (tri=0;u->irq1 < 0 && tri < sizeof(irq_tries);tri++) {
1038                         if (eliminated_irq & (1 << irq_tries[tri]))
1039                                 continue;
1040
1041                         if (ultrasnd_valid_irq(u,irq_tries[tri]) != 0 && ultrasnd_test_irq_timer(u,irq_tries[tri]))
1042                                 u->irq1 = irq_tries[tri];
1043                         else
1044                                 eliminated_irq |= 1 << irq_tries[tri];
1045
1046                         ultrasnd_irq_watch(NULL);
1047                 }
1048                 ultrasnd_irq_watch(NULL);
1049         }
1050
1051         if (u->dma1 < 0) {
1052                 /* TODO: DMA channel probing code */
1053         }
1054
1055         return u;
1056 }
1057
1058 /* try initializing a card based on the ULTRASND env variable */
1059 struct ultrasnd_ctx *ultrasnd_try_ultrasnd_env() {
1060         struct ultrasnd_ctx *u;
1061         int val[6],par=0;
1062         char *p;
1063
1064         if ((p = getenv("ULTRASND")) == NULL)
1065                 return NULL;
1066         if ((u = ultrasnd_alloc_card()) == NULL)
1067                 return NULL;
1068
1069         ultrasnd_init_ctx(u);
1070         for (par=0;par < 6;par++) val[par] = -1;
1071         /* ULTRASND=<port>,<play DMA>,<rec DMA>,<GUS IRQ>,<SB MIDI IRQ> */
1072         par = 0;
1073         while (*p) {
1074                 if (*p == ' ') {
1075                         p++;
1076                         continue;
1077                 }
1078
1079                 if (isdigit(*p)) {
1080                         if (par == 0) { /* port num, hex */
1081                                 val[par] = (int)strtol(p,NULL,16); /* hexadecimal */
1082                         }
1083                         else {
1084                                 val[par] = (int)strtol(p,NULL,0); /* decimal */
1085                         }
1086                 }
1087                 else {
1088                         val[par] = -1;
1089                 }
1090
1091                 while (*p && *p != ',') p++;
1092                 if (*p == ',') p++;
1093                 if (++par >= 6) break;
1094         }
1095
1096         if (ultrasnd_port_taken(val[0]))
1097                 return NULL;
1098
1099         if (val[0] >= 0x200)
1100                 u->port = val[0];
1101         else
1102                 return NULL;
1103
1104         if (val[1] >= 0)
1105                 u->dma1 = val[1];
1106         if (val[2] >= 0)
1107                 u->dma2 = val[2];
1108         if (val[3] >= 0)
1109                 u->irq1 = val[3];
1110         if (val[4] >= 0)
1111                 u->irq2 = val[4];
1112
1113         return (ultrasnd_env=u);
1114 }
1115
1116 uint16_t ultrasnd_sample_rate_to_fc(struct ultrasnd_ctx *u,unsigned int r) {
1117         uint32_t m;
1118
1119         /* "frequency counter" is 6.8 fixed point */
1120         m = ((1UL << 9UL) * (unsigned long)r) / (unsigned long)u->output_rate;
1121         return (uint16_t)m << 1U;
1122 }
1123
1124 unsigned char ultrasnd_read_voice_mode(struct ultrasnd_ctx *u,unsigned char voice) {
1125         ultrasnd_select_voice(u,voice);
1126         return ultrasnd_select_read(u,0x80);
1127 }
1128
1129 void ultrasnd_set_voice_mode(struct ultrasnd_ctx *u,unsigned char voice,uint8_t mode) {
1130         ultrasnd_select_voice(u,voice); mode &= ~3;
1131         mode |= ultrasnd_select_read(u,0x00) & 3;
1132
1133         ultrasnd_select_voice(u,voice);
1134         ultrasnd_select_write(u,0x00,mode);
1135
1136         t8254_wait(t8254_us2ticks(100)); /* 100us */
1137
1138         ultrasnd_select_voice(u,voice);
1139         ultrasnd_select_write(u,0x00,mode);
1140         u->voicemode[voice] = mode;
1141 }
1142
1143 void ultrasnd_set_voice_fc(struct ultrasnd_ctx *u,unsigned char voice,uint16_t fc) {
1144         ultrasnd_select_voice(u,voice);
1145         ultrasnd_select_write16(u,0x01,fc);
1146 }
1147
1148 void ultrasnd_set_voice_start(struct ultrasnd_ctx *u,unsigned char voice,uint32_t ofs) {
1149         if (u->voicemode[voice] & ULTRASND_VOICE_MODE_16BIT) ofs = ultrasnd_dram_16bit_xlate(ofs);
1150         ultrasnd_select_voice(u,voice);
1151         ultrasnd_select_write16(u,0x02,ofs >> 7UL);
1152         ultrasnd_select_write16(u,0x03,ofs << 9UL);
1153 }
1154
1155 void ultrasnd_set_voice_end(struct ultrasnd_ctx *u,unsigned char voice,uint32_t ofs) {
1156         if (u->voicemode[voice] & ULTRASND_VOICE_MODE_16BIT) ofs = ultrasnd_dram_16bit_xlate(ofs);
1157         ultrasnd_select_voice(u,voice);
1158         ultrasnd_select_write16(u,0x04,ofs >> 7UL);
1159         ultrasnd_select_write16(u,0x05,ofs << 9UL);
1160 }
1161
1162 void ultrasnd_stop_voice(struct ultrasnd_ctx *u,int i) {
1163         unsigned char c;
1164         int j;
1165
1166         ultrasnd_select_voice(u,i);
1167         for (j=0;j < 16;j++) {
1168                 c = ultrasnd_select_read(u,0x80); /* voice select (read) */
1169                 ultrasnd_select_write(u,0x00,c | 3); /* voice select (write), set STOP VOICE */
1170                 t8254_wait(t8254_us2ticks(100)); /* 100us */
1171                 c = ultrasnd_select_read(u,0x80); /* voice select (read) */
1172                 ultrasnd_select_write(u,0x00,c | 3); /* voice select (write), set STOP VOICE */
1173                 t8254_wait(t8254_us2ticks(100)); /* 100us */
1174                 c = ultrasnd_select_read(u,0x80); /* voice select (read) */
1175                 if (c&1) break; /* if the voice stopped, then we succeeded */
1176         }
1177
1178 //      if (!(c&1)) fprintf(stderr,"Cannot stop voice %02x\n",c);
1179         u->voicemode[i] = c;
1180 }
1181
1182 void ultrasnd_start_voice(struct ultrasnd_ctx *u,int i) {
1183         unsigned char c;
1184         int j;
1185
1186         ultrasnd_select_voice(u,i);
1187         for (j=0;j < 16;j++) {
1188                 c = ultrasnd_select_read(u,0x80); /* voice select (read) */
1189                 ultrasnd_select_write(u,0x00,c & (~3)); /* voice select (write), clear STOP VOICE */
1190                 t8254_wait(t8254_us2ticks(100)); /* 100us */
1191                 c = ultrasnd_select_read(u,0x80); /* voice select (read) */
1192                 ultrasnd_select_write(u,0x00,c & (~3)); /* voice select (write), clear STOP VOICE */
1193                 t8254_wait(t8254_us2ticks(100)); /* 100us */
1194                 c = ultrasnd_select_read(u,0x80); /* voice select (read) */
1195                 if (!(c&1)) break; /* if the voice started, then we succeeded */
1196         }
1197
1198 //      if (c&1) fprintf(stderr,"Cannot start voice %02x\n",c);
1199         u->voicemode[i] = c;
1200 }
1201
1202 void ultrasnd_start_voice_imm(struct ultrasnd_ctx *u,int i) {
1203         unsigned char c;
1204
1205         ultrasnd_select_voice(u,i);
1206         c = ultrasnd_select_read(u,0x80); /* voice select (read) */
1207         ultrasnd_select_write(u,0x00,c & (~3)); /* voice select (write), clear STOP VOICE */
1208         u->voicemode[i] = c;
1209 }
1210
1211 void ultrasnd_set_voice_ramp_rate(struct ultrasnd_ctx *u,unsigned char voice,unsigned char adj,unsigned char rate) {
1212         ultrasnd_select_voice(u,voice);
1213         ultrasnd_select_write(u,0x06,(adj & 0x3F) | (rate << 6));
1214 }
1215
1216 void ultrasnd_set_voice_ramp_start(struct ultrasnd_ctx *u,unsigned char voice,unsigned char start) {
1217         ultrasnd_select_voice(u,voice);
1218         ultrasnd_select_write(u,0x07,start);
1219 }
1220
1221 void ultrasnd_set_voice_ramp_end(struct ultrasnd_ctx *u,unsigned char voice,unsigned char end) {
1222         ultrasnd_select_voice(u,voice);
1223         ultrasnd_select_write(u,0x08,end);
1224 }
1225
1226 void ultrasnd_set_voice_volume(struct ultrasnd_ctx *u,unsigned char voice,uint16_t vol) {
1227         ultrasnd_select_voice(u,voice);
1228         ultrasnd_select_write16(u,0x09,vol);
1229 }
1230
1231 uint32_t ultrasnd_read_voice_current(struct ultrasnd_ctx *u,unsigned char voice) {
1232         uint32_t ofs;
1233         uint16_t a,b;
1234
1235         /* nobody says or implies that the GUS keeps the halves buffered while
1236            we read, so assume the worst case scenario and re-read if we see
1237            the upper half change. */
1238         ultrasnd_select_voice(u,voice);
1239         do {
1240                 a = ultrasnd_select_read16(u,0x8A);
1241                 ofs = ultrasnd_select_read16(u,0x8B) >> 9UL;
1242                 b = ultrasnd_select_read16(u,0x8A);
1243         } while (a != b);
1244         ofs |= (uint32_t)a << 7UL;
1245         ofs &= 0xFFFFF;
1246
1247         /* NOTE TO SELF: As seen on GUS MAX ISA card: Bits 22-20 are set for some reason.
1248                          And our attempts to play forwards ends up in reverse? */
1249         if (u->voicemode[voice] & ULTRASND_VOICE_MODE_16BIT) ofs = ultrasnd_dram_16bit_xlate_from(ofs);
1250         return ofs;
1251 }
1252
1253 void ultrasnd_set_voice_current(struct ultrasnd_ctx *u,unsigned char voice,uint32_t loc) {
1254         loc &= 0xFFFFF;
1255         if (u->voicemode[voice] & ULTRASND_VOICE_MODE_16BIT) loc = ultrasnd_dram_16bit_xlate(loc);
1256         ultrasnd_select_voice(u,voice);
1257         ultrasnd_select_write16(u,0x0A,loc >> 7UL);
1258         ultrasnd_select_write16(u,0x0B,loc << 9UL);
1259 }
1260
1261 void ultrasnd_set_voice_pan(struct ultrasnd_ctx *u,unsigned char voice,uint8_t pan) {
1262         ultrasnd_select_voice(u,voice);
1263         ultrasnd_select_write(u,0x0C,pan);
1264 }
1265
1266 void ultrasnd_set_voice_ramp_control(struct ultrasnd_ctx *u,unsigned char voice,uint8_t ctl) {
1267         ultrasnd_select_voice(u,voice);
1268         ultrasnd_select_write(u,0x0D,ctl);
1269 }
1270
1271 unsigned char FAR *ultrasnd_dram_buffer_alloc(struct ultrasnd_ctx *u,unsigned long len) {
1272         if (len >= 0xFF00UL) {
1273                 ultrasnd_dram_buffer_free(u);
1274                 return NULL;
1275         }
1276
1277         if (u->dram_xfer_a != NULL) {
1278                 if (len <= u->dram_xfer_a->length) return u->dram_xfer_a->lin;
1279                 ultrasnd_dram_buffer_free(u);
1280         }
1281
1282         if ((u->dram_xfer_a = dma_8237_alloc_buffer(len)) == NULL)
1283                 return NULL;
1284
1285         return u->dram_xfer_a->lin;
1286 }
1287
1288 int ultrasnd_send_dram_buffer(struct ultrasnd_ctx *u,uint32_t ofs,unsigned long len,uint8_t flags) {
1289         unsigned char FAR *src;
1290         uint8_t dma = u->use_dma;
1291         unsigned int patience;
1292         uint32_t phys,i;
1293         uint16_t rem;
1294
1295         if (u == NULL || u->dram_xfer_a == NULL || len > u->dram_xfer_a->length || len > 0xFF00UL)
1296                 return 0;
1297
1298         src = u->dram_xfer_a->lin;
1299         phys = u->dram_xfer_a->phys;
1300
1301         /* cannot do half-word transfers when 16-bit is involved */
1302         if (dma && ((len & 1) && ((u->dma1 >= 4) || (flags & ULTRASND_DMA_DATA_SIZE_16BIT))))
1303                 dma = 0;
1304         /* the target DRAM address must be 16-bit aligned (32-bit aligned for 16-bit audio) */
1305         if (dma && (ofs & 0xF) != 0)
1306                 dma = 0;
1307         if (dma && u->dma1 >= 4 && (ofs & 0x1F) != 0)
1308                 dma = 0;
1309
1310         if (dma) {
1311                 _cli();
1312
1313                 /* disable GUS DMA */
1314                 ultrasnd_select_write(u,0x41,0x00);
1315                 ultrasnd_select_read(u,0x41); /* read to clear DMA terminal count---even though we didn't ask for TC IRQ */
1316
1317                 /* Now initiate a DMA transfer (host) */
1318                 outp(d8237_ioport(u->dma1,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(u->dma1) | D8237_MASK_SET); /* mask */
1319                 outp(d8237_ioport(u->dma1,D8237_REG_W_WRITE_MODE),
1320                         D8237_MODER_CHANNEL(u->dma1) |
1321                         D8237_MODER_TRANSFER(D8237_MODER_XFER_READ) | /* "READ" from system memory */
1322                         D8237_MODER_MODESEL(D8237_MODER_MODESEL_DEMAND));
1323                 d8237_write_base(u->dma1,phys); /* RAM location with not much around */
1324                 d8237_write_count(u->dma1,len);
1325
1326                 /* Now initiate a DMA transfer (GUS DRAM) */
1327                 ultrasnd_select_write(u,0x41,(u->dma1 >= 4 ? 4 : 0) | (flags & 0xC0)); /* data size in bit 2, writing to DRAM, enable DMA, and bits 6-7 provided by caller */
1328                 if (u->dma1 >= 4) /* Ugh, even DMA is subject to Gravis 16-bit translation */
1329                         ultrasnd_select_write16(u,0x42,(uint16_t)(ultrasnd_dram_16bit_xlate(ofs)>>4UL));
1330                 else
1331                         ultrasnd_select_write16(u,0x42,(uint16_t)(ofs>>4UL));
1332                 ultrasnd_select_write(u,0x41,(u->dma1 >= 4 ? 4 : 0) | 0x1 | (flags & 0xC0)); /* data size in bit 2, writing to DRAM, enable DMA, and bits 6-7 provided by caller */
1333
1334                 /* GO! */
1335                 outp(d8237_ioport(u->dma1,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(u->dma1)); /* unmask */
1336
1337                 _sti();
1338
1339                 /* watch it run */
1340                 /* Note that DOSBox's emulation of a GUS does not indicate DMA TC, since we didn't ask for it, but the actual GF1 chipset
1341                  * will return with bit 6 set whether we asked for TC IRQ or not. */
1342                 patience = 10000; /* 100ns * 10000 = 1 sec */
1343                 do {
1344                         rem = d8237_read_count(u->dma1);
1345                         if (rem == 0 || rem >= 0xFFFE)
1346                                 break;
1347
1348                         t8254_wait(t8254_us2ticks(100));
1349                 } while (--patience != 0);
1350                 if (rem >= 0xFFFE) rem = 0;
1351
1352                 if (patience == 0)
1353                         fprintf(stderr,"GUS DMA transfer timeout (rem=%lu)\n",rem);
1354                 if (rem != 0)
1355                         fprintf(stderr,"GUS DMA transfer TC while DMA controller has %u remaining\n",rem);
1356
1357                 /* mask DMA channel again */
1358                 outp(d8237_ioport(u->dma1,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(u->dma1) | D8237_MASK_SET); /* mask */
1359
1360                 /* stop DMA */
1361                 ultrasnd_select_write(u,0x41,0x00);
1362                 ultrasnd_select_read(u,0x41); /* read to clear DMA terminal count---even though we didn't ask for TC IRQ */
1363         }
1364         else {
1365                 if (flags & ULTRASND_DMA_FLIP_MSB) {
1366                         if (flags & ULTRASND_DMA_DATA_SIZE_16BIT) {
1367                                 for (i=0;i < len;i += 2) {
1368                                         ultrasnd_poke(u,ofs+i,src[i]);
1369                                         ultrasnd_poke(u,ofs+i+1,src[i+1] ^ 0x80);
1370                                 }
1371                         }
1372                         else {
1373                                 for (i=0;i < len;i++) ultrasnd_poke(u,ofs+i,src[i] ^ 0x80);
1374                         }
1375                 }
1376                 else {
1377                         for (i=0;i < len;i++) ultrasnd_poke(u,ofs+i,src[i]);
1378                 }
1379         }
1380
1381         return 1;
1382 }
1383
1384 void ultrasnd_dram_buffer_free(struct ultrasnd_ctx *u) {
1385         if (u->dram_xfer_a != NULL) {
1386                 dma_8237_free_buffer(u->dram_xfer_a);
1387                 u->dram_xfer_a = NULL;
1388         }
1389 }
1390