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
11 Gravis Ultrasound Max:
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).
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.
31 Following this sequence of steps resolves the staticy crackly
32 audio observed with a GUS Max on an ancient Pentium/100MHz
38 Bidirectional looping misconception:
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.
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
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.
60 Proper voice programming sequence:
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.
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
74 Pre-initialized state and "stuck" IRQ: [BUG: FIXME]
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.
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.
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.
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
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.
99 DMA transfer programming:
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.
110 DMA problem on real hardware with DMA channels 5, 6, and 7. [BUG: FIXME]
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
117 Card identification [TODO: FIXME]
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.
124 Also refer to the Linux driver source code on how to go about this process:
126 http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/sound/isa/gus/gus_dma.c
129 SBOS initialization check [TODO: FIXME add to Sound Blaster library]
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.
140 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
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>
160 static int debug_on = 0;
161 static int ultrasnd_test_irq_fired = 0;
162 static int ultrasnd_test_irq_n = 0;
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 */
172 struct ultrasnd_ctx ultrasnd_card[MAX_ULTRASND];
173 struct ultrasnd_ctx *ultrasnd_env = NULL;
174 int ultrasnd_inited = 0;
176 void ultrasnd_debug(int on) {
180 uint32_t ultrasnd_dram_16bit_xlate(uint32_t a) {
182 return (a & 0x000C0000) | ((a & 0x3FFFF) >> 1UL);
185 uint32_t ultrasnd_dram_16bit_xlate_from(uint32_t a) {
187 return (a & 0xFFFC0000) | ((a & 0x1FFFF) << 1UL);
190 static void gus_delay(struct ultrasnd_ctx *u) {
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);
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);
215 outp(u->port+0x105,data);
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);
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);
227 outpw(u->port+0x104,data);
230 uint8_t ultrasnd_select_read(struct ultrasnd_ctx *u,uint8_t reg) {
231 outp(u->port+0x103,reg);
233 return inp(u->port+0x105);
236 uint8_t ultrasnd_selected_read(struct ultrasnd_ctx *u) {
237 return inp(u->port+0x105);
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 */
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);
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 */
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);
258 int ultrasnd_valid_dma(struct ultrasnd_ctx *u,int8_t i) {
269 int ultrasnd_valid_irq(struct ultrasnd_ctx *u,int8_t i) {
282 static void interrupt far ultrasnd_test_irq() {
283 ultrasnd_test_irq_fired++;
286 if (ultrasnd_test_irq_n >= 8) p8259_OCW2(8,P8259_OCW2_NON_SPECIFIC_EOI);
287 p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
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));
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).
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;
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;
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);
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);
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? */
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? */
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);
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? */
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);
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);
365 /* the tests below can cause interrupts. so hook the IRQ */
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. */
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 */
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 */
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;
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
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);
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);
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 */
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 */
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);
425 /* clear all IRQ events */
427 ultrasnd_select_voice(u,0);
429 if (--patience == 0) {
430 if (debug_on) fprintf(stderr,"GUS: Ran out of patience attempting to clear interrupt events\n");
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);
441 } while (c1 != 0xC0);
442 c1 = inp(u->port+0x006);
445 /* any IRQs that did happen, ignore them */
446 ultrasnd_test_irq_fired = 0;
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 */
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);
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 */
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);
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");
482 /* wait for the timer to stop */
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);
491 } while ((c&0x60) == 0x00);
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;
498 /* unless we know otherwise, samples cannot straddle a 256KB boundary */
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;
506 /* put sentry value at base to detect address wrapping */
507 ultrasnd_poke(u,0,0x55);
508 ultrasnd_poke(u,1,0xAA);
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);
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)
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)
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)
529 /* it's RAM. count it. move on */
530 u->total_ram = ofs + 0x40000UL;
533 /* Next: the DMA test */
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;
539 if ((str=buffer=ultrasnd_dram_buffer_alloc(u,testlen)) != NULL) {
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;
546 #if TARGET_MSDOS == 32
547 memset(buffer,128,testlen);
549 _fmemset(buffer,128,testlen);
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 */
558 /* clear GUS DRAM so that we're not comparing stale data */
559 for (i=0;i < 0x2000;i++) ultrasnd_poke(u,i,0x00);
561 /* Fill the buffer with a chosen phrase */
562 len = strlen(testing)+1;
563 for (i=0;i < len;i++) str[i] = testing[i];
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);
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);
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 */
583 outp(d8237_ioport(u->dma1,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(u->dma1)); /* unmask */
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. */
590 rem = d8237_read_count(u->dma1);
591 if (rem == 0 || rem >= 0xFFFE)
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 */
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 */
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 */
606 ultrasnd_dram_buffer_free(u);
608 if ((unsigned int)rem >= testlen) goto dmafail;
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);
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");
628 fprintf(stderr,"Gravis Ultrasound[0x%03x]: Unable to allocate buffer for DMA testing\n",u->port);
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);
637 _dos_setvect(irq2int(u->irq1),old_irq);
646 for (i=0;i < 32;i++) u->voicemode[i] = 0;
647 ultrasnd_set_active_voices(u,14);
650 fprintf(stderr,"Gravis Ultrasound[0x%03x]: DMA test failed, nothing was transferred\n",u->port);
653 fprintf(stderr,"Gravis Ultrasound[0x%03x]: IRQ test failed, timers did not signal IRQ handler\n",u->port);
656 fprintf(stderr,"Gravis Ultrasound[0x%03x]: RAM test failed\n",u->port);
659 fprintf(stderr,"Gravis Ultrasound[0x%03x]: Timer test failed (IRQstatus=0x%02X)\n",u->port,inp(u->port+0x006));
665 _dos_setvect(irq2int(u->irq1),old_irq);
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 */
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 */
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 */
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 */
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);
701 /* clear all IRQ events */
703 ultrasnd_select_voice(u,0);
705 if (--patience == 0) {
706 if (debug_on) fprintf(stderr,"GUS: Ran out of patience attempting to clear interrupt events\n");
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);
717 } while (c1 != 0xC0);
719 /* suck up all possible IRQ events */
720 for (i=0;i < 255;i++) c1 = inp(u->port+0x006); /* IRQ status */
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));
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));
744 int ultrasnd_irq_taken(int irq) {
747 for (i=0;i < MAX_ULTRASND;i++) {
748 struct ultrasnd_ctx *u = &ultrasnd_card[i];
749 if (u->irq1 == irq || u->irq2 == irq)
756 int ultrasnd_dma_taken(int dma) {
759 for (i=0;i < MAX_ULTRASND;i++) {
760 struct ultrasnd_ctx *u = &ultrasnd_card[i];
761 if (u->dma1 == dma || u->dma2 == dma)
768 int ultrasnd_port_taken(int port) {
771 for (i=0;i < MAX_ULTRASND;i++) {
772 struct ultrasnd_ctx *u = &ultrasnd_card[i];
780 void ultrasnd_init_ctx(struct ultrasnd_ctx *u) {
783 u->dma1 = u->dma2 = -1;
784 u->irq1 = u->irq2 = -1;
785 u->dram_xfer_a = NULL;
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;
794 int ultrasnd_card_taken(struct ultrasnd_ctx *u) {
795 return (u->port >= 0);
798 int init_ultrasnd() {
801 if (!ultrasnd_inited) {
803 for (i=0;i < MAX_ULTRASND;i++)
804 ultrasnd_init_ctx(&ultrasnd_card[i]);
810 struct ultrasnd_ctx *ultrasnd_alloc_card() {
813 for (i=0;i < MAX_ULTRASND;i++) {
814 if (!ultrasnd_card_taken(&ultrasnd_card[i]))
815 return &ultrasnd_card[i];
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);
826 static void interrupt far dummy_irq() {
827 p8259_OCW2(0,P8259_OCW2_NON_SPECIFIC_EOI);
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;
838 #if TARGET_MSDOS == 32
839 uint32_t *intvec = (uint32_t*)0x00000000;
841 uint32_t far *intvec = (uint32_t far *)MK_FP(0x0000,0x000);
844 for (irq=0;irq < 16;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);
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. */
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);
874 for (patience=0;patience < 250;patience++) {
875 t8254_wait(t8254_us2ticks(1000));
877 irr = (unsigned short)p8259_read_IRR(0);
878 irr |= (unsigned short)p8259_read_IRR(8) << 8U;
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. */
887 else if (stuck & (1U << irq)) {
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 */
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);
901 t8254_wait(t8254_us2ticks(1000));
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)) {
908 else if (irr & (1U << irq)) {
912 } while (--patience != 0);
914 // fprintf(stdout,"Pre-test IRQ elimination: 0x%04X irr=0x%04x stuck=0x%04x\n",*eirq,irr,stuck);
916 /* restore interrupt mask */
917 p8259_write_mask(0,ml);
918 p8259_write_mask(8,mh);
921 for (irq=0;irq < 16;irq++) {
922 if (oldvec[irq] != NULL) {
924 intvec[intv] = 0x00000000UL;
931 int ultrasnd_test_irq_timer(struct ultrasnd_ctx *u,int irq) {
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);
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 */
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 */
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);
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);
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;
984 if (ultrasnd_port_taken(base))
986 if ((u = ultrasnd_alloc_card()) == NULL)
989 ultrasnd_init_ctx(u);
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);
998 if (ultrasnd_probe(u,0)) {
999 ultrasnd_free_card(u);
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);
1014 else if ((stuck & (stuck - 1)) == 0) { /* if only 1 bit set */
1016 for (iv=0;iv < 16;iv++) {
1017 if (stuck & (1 << iv)) {
1023 if ((eliminated_irq & (1 << iv)) == 0) {
1024 if (ultrasnd_valid_irq(u,i) != 0 && ultrasnd_test_irq_timer(u,i))
1027 eliminated_irq |= 1 << iv;
1029 stuck = ultrasnd_irq_watch(NULL);
1033 break; /* we'll have to try another way */
1037 for (tri=0;u->irq1 < 0 && tri < sizeof(irq_tries);tri++) {
1038 if (eliminated_irq & (1 << irq_tries[tri]))
1041 if (ultrasnd_valid_irq(u,irq_tries[tri]) != 0 && ultrasnd_test_irq_timer(u,irq_tries[tri]))
1042 u->irq1 = irq_tries[tri];
1044 eliminated_irq |= 1 << irq_tries[tri];
1046 ultrasnd_irq_watch(NULL);
1048 ultrasnd_irq_watch(NULL);
1052 /* TODO: DMA channel probing code */
1058 /* try initializing a card based on the ULTRASND env variable */
1059 struct ultrasnd_ctx *ultrasnd_try_ultrasnd_env() {
1060 struct ultrasnd_ctx *u;
1064 if ((p = getenv("ULTRASND")) == NULL)
1066 if ((u = ultrasnd_alloc_card()) == NULL)
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> */
1080 if (par == 0) { /* port num, hex */
1081 val[par] = (int)strtol(p,NULL,16); /* hexadecimal */
1084 val[par] = (int)strtol(p,NULL,0); /* decimal */
1091 while (*p && *p != ',') p++;
1093 if (++par >= 6) break;
1096 if (ultrasnd_port_taken(val[0]))
1099 if (val[0] >= 0x200)
1113 return (ultrasnd_env=u);
1116 uint16_t ultrasnd_sample_rate_to_fc(struct ultrasnd_ctx *u,unsigned int r) {
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;
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);
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;
1133 ultrasnd_select_voice(u,voice);
1134 ultrasnd_select_write(u,0x00,mode);
1136 t8254_wait(t8254_us2ticks(100)); /* 100us */
1138 ultrasnd_select_voice(u,voice);
1139 ultrasnd_select_write(u,0x00,mode);
1140 u->voicemode[voice] = mode;
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);
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);
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);
1162 void ultrasnd_stop_voice(struct ultrasnd_ctx *u,int i) {
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 */
1178 // if (!(c&1)) fprintf(stderr,"Cannot stop voice %02x\n",c);
1179 u->voicemode[i] = c;
1182 void ultrasnd_start_voice(struct ultrasnd_ctx *u,int i) {
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 */
1198 // if (c&1) fprintf(stderr,"Cannot start voice %02x\n",c);
1199 u->voicemode[i] = c;
1202 void ultrasnd_start_voice_imm(struct ultrasnd_ctx *u,int i) {
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;
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));
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);
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);
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);
1231 uint32_t ultrasnd_read_voice_current(struct ultrasnd_ctx *u,unsigned char voice) {
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);
1240 a = ultrasnd_select_read16(u,0x8A);
1241 ofs = ultrasnd_select_read16(u,0x8B) >> 9UL;
1242 b = ultrasnd_select_read16(u,0x8A);
1244 ofs |= (uint32_t)a << 7UL;
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);
1253 void ultrasnd_set_voice_current(struct ultrasnd_ctx *u,unsigned char voice,uint32_t loc) {
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);
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);
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);
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);
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);
1282 if ((u->dram_xfer_a = dma_8237_alloc_buffer(len)) == NULL)
1285 return u->dram_xfer_a->lin;
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;
1295 if (u == NULL || u->dram_xfer_a == NULL || len > u->dram_xfer_a->length || len > 0xFF00UL)
1298 src = u->dram_xfer_a->lin;
1299 phys = u->dram_xfer_a->phys;
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))))
1304 /* the target DRAM address must be 16-bit aligned (32-bit aligned for 16-bit audio) */
1305 if (dma && (ofs & 0xF) != 0)
1307 if (dma && u->dma1 >= 4 && (ofs & 0x1F) != 0)
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 */
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);
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));
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 */
1335 outp(d8237_ioport(u->dma1,D8237_REG_W_SINGLE_MASK),D8237_MASK_CHANNEL(u->dma1)); /* unmask */
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 */
1344 rem = d8237_read_count(u->dma1);
1345 if (rem == 0 || rem >= 0xFFFE)
1348 t8254_wait(t8254_us2ticks(100));
1349 } while (--patience != 0);
1350 if (rem >= 0xFFFE) rem = 0;
1353 fprintf(stderr,"GUS DMA transfer timeout (rem=%lu)\n",rem);
1355 fprintf(stderr,"GUS DMA transfer TC while DMA controller has %u remaining\n",rem);
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 */
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 */
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);
1373 for (i=0;i < len;i++) ultrasnd_poke(u,ofs+i,src[i] ^ 0x80);
1377 for (i=0;i < len;i++) ultrasnd_poke(u,ofs+i,src[i]);
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;