Commit d75d9f6be958f0245ed7794bbd2a31eaffae40da

Authored by bellard
1 parent 769bec72

SDL Audio support and SB16 fixes (malc)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1108 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 860 additions and 233 deletions
Changelog
... ... @@ -26,6 +26,7 @@ version 0.6.1:
26 26 - BIOS floppy fix for NT4 (Mike Nordell, Derek Fawcus, Volker Ruppert)
27 27 - Floppy fixes for NT4 and NT5 (Mike Nordell)
28 28 - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
  29 + - SDL Audio support and SB16 fixes (malc)
29 30  
30 31 version 0.6.0:
31 32  
... ...
hw/sb16.c
... ... @@ -26,12 +26,10 @@
26 26 #define MIN(a, b) ((a)>(b)?(b):(a))
27 27 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
28 28  
29   -#define log(...) do { \
30   - fprintf (stderr, "sb16: " __VA_ARGS__); \
31   - fputc ('\n', stderr); \
32   -} while (0)
  29 +#define dolog(...) fprintf (stderr, "sb16: " __VA_ARGS__);
33 30  
34 31 /* #define DEBUG_SB16 */
  32 +
35 33 #ifdef DEBUG_SB16
36 34 #define lwarn(...) fprintf (stderr, "sb16: " __VA_ARGS__)
37 35 #define linfo(...) fprintf (stderr, "sb16: " __VA_ARGS__)
... ... @@ -47,7 +45,10 @@
47 45 #define IO_WRITE_PROTO(name) \
48 46 void name (void *opaque, uint32_t nport, uint32_t val)
49 47  
50   -static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
  48 +static const char e3[] =
  49 + "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992\0"
  50 + "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1994-1997";
  51 + /* "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1994."; */
51 52  
52 53 static struct {
53 54 int ver_lo;
... ... @@ -80,10 +81,13 @@ typedef struct SB16State {
80 81  
81 82 int v2x6;
82 83  
83   - uint8_t in_data[10];
84   - uint8_t out_data[50];
  84 + uint8_t in2_data[10];
  85 + uint8_t out_data[1024];
85 86  
86 87 int left_till_irq;
  88 + uint64_t nzero;
  89 + uint8_t last_read_byte;
  90 + uint8_t test_reg;
87 91  
88 92 /* mixer state */
89 93 int mixer_nreg;
... ... @@ -95,7 +99,7 @@ static struct SB16State dsp;
95 99  
96 100 static void log_dsp (SB16State *dsp)
97 101 {
98   - linfo ("%c:%c:%d:%c:dmabuf=%d:pos=%d:freq=%d:timeconst=%d:speaker=%d\n",
  102 + ldebug ("%c:%c:%d:%c:dmabuf=%d:pos=%d:freq=%d:timeconst=%d:speaker=%d\n",
99 103 dsp->fmt_stereo ? 'S' : 'M',
100 104 dsp->fmt_signed ? 'S' : 'U',
101 105 dsp->fmt_bits,
... ... @@ -191,6 +195,7 @@ static void dma_cmd (uint8_t cmd, uint8_t d0, int dma_len)
191 195 mix_block = ((dsp.freq * align) / 100) & ~(align - 1);
192 196 }
193 197  
  198 + if (dsp.freq)
194 199 AUD_reset (dsp.freq, 1 << dsp.fmt_stereo, fmt);
195 200 control (1);
196 201 dsp.speaker = 1;
... ... @@ -202,9 +207,17 @@ static inline void dsp_out_data(SB16State *dsp, int val)
202 207 dsp->out_data[dsp->out_data_len++] = val;
203 208 }
204 209  
  210 +static inline uint8_t dsp_get_data(SB16State *dsp)
  211 +{
  212 + if (dsp->in_index)
  213 + return dsp->in2_data[--dsp->in_index];
  214 + else
  215 + return 0;
  216 +}
  217 +
205 218 static void command (SB16State *dsp, uint8_t cmd)
206 219 {
207   - linfo ("%#x\n", cmd);
  220 + linfo ("command: %#x\n", cmd);
208 221  
209 222 if (cmd > 0xaf && cmd < 0xd0) {
210 223 if (cmd & 8)
... ... @@ -215,7 +228,7 @@ static void command (SB16State *dsp, uint8_t cmd)
215 228 case 12:
216 229 break;
217 230 default:
218   - log("%#x wrong bits", cmd);
  231 + dolog ("command: %#x wrong bits specification\n", cmd);
219 232 goto error;
220 233 }
221 234 dsp->needed_bytes = 3;
... ... @@ -223,23 +236,25 @@ static void command (SB16State *dsp, uint8_t cmd)
223 236 else {
224 237 switch (cmd) {
225 238 case 0x00:
226   - case 0x03:
227 239 case 0xe7:
228 240 /* IMS uses those when probing for sound devices */
229 241 return;
230 242  
  243 + case 0x03:
231 244 case 0x04:
232   - dsp->needed_bytes = 1;
233   - break;
  245 + dsp_out_data (dsp, 0);
  246 + return;
234 247  
235 248 case 0x05:
  249 + dsp->needed_bytes = 2;
  250 + break;
  251 +
236 252 case 0x0e:
237 253 dsp->needed_bytes = 2;
238 254 break;
239 255  
240 256 case 0x0f:
241 257 dsp->needed_bytes = 1;
242   - dsp_out_data (dsp, 0);
243 258 break;
244 259  
245 260 case 0x10:
... ... @@ -272,6 +287,8 @@ static void command (SB16State *dsp, uint8_t cmd)
272 287 dsp->needed_bytes = 2;
273 288 break;
274 289  
  290 + case 0x45:
  291 + dsp_out_data (dsp, 0xaa);
275 292 case 0x47: /* Continue Auto-Initialize DMA 16bit */
276 293 break;
277 294  
... ... @@ -346,19 +363,39 @@ static void command (SB16State *dsp, uint8_t cmd)
346 363 case 0xe3:
347 364 {
348 365 int i;
349   - for (i = sizeof (e3) - 1; i >= 0; --i)
  366 + for (i = sizeof (e3) - 1; i >= 0; i--)
350 367 dsp_out_data (dsp, e3[i]);
351 368 return;
352 369 }
353 370  
  371 + case 0xe4: /* write test reg */
  372 + dsp->needed_bytes = 1;
  373 + break;
  374 +
  375 + case 0xe8: /* read test reg */
  376 + dsp_out_data (dsp, dsp->test_reg);
  377 + break;
  378 +
354 379 case 0xf2:
355   - dsp_out_data(dsp, 0xaa);
  380 + dsp_out_data (dsp, 0xaa);
356 381 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
357 382 pic_set_irq (sb.irq, 1);
358 383 return;
359 384  
  385 + case 0xf9:
  386 + dsp->needed_bytes = 1;
  387 + break;
  388 +
  389 + case 0xfa:
  390 + dsp_out_data (dsp, 0);
  391 + break;
  392 +
  393 + case 0xfc: /* FIXME */
  394 + dsp_out_data (dsp, 0);
  395 + break;
  396 +
360 397 default:
361   - log("%#x is unknown", cmd);
  398 + dolog ("unrecognized command %#x\n", cmd);
362 399 goto error;
363 400 }
364 401 }
... ... @@ -371,15 +408,14 @@ static void command (SB16State *dsp, uint8_t cmd)
371 408  
372 409 static void complete (SB16State *dsp)
373 410 {
  411 + int d0, d1, d2;
374 412 linfo ("complete command %#x, in_index %d, needed_bytes %d\n",
375 413 dsp->cmd, dsp->in_index, dsp->needed_bytes);
376 414  
377 415 if (dsp->cmd > 0xaf && dsp->cmd < 0xd0) {
378   - int d0, d1, d2;
379   -
380   - d0 = dsp->in_data[0];
381   - d1 = dsp->in_data[1];
382   - d2 = dsp->in_data[2];
  416 + d2 = dsp_get_data (dsp);
  417 + d1 = dsp_get_data (dsp);
  418 + d0 = dsp_get_data (dsp);
383 419  
384 420 ldebug ("d0 = %d, d1 = %d, d2 = %d\n",
385 421 d0, d1, d2);
... ... @@ -387,23 +423,29 @@ static void complete (SB16State *dsp)
387 423 }
388 424 else {
389 425 switch (dsp->cmd) {
390   - case 0x05:
391 426 case 0x04:
392   - case 0x0e:
  427 + case 0x10:
  428 + dsp_get_data (dsp);
  429 + break;
  430 +
393 431 case 0x0f:
  432 + d0 = dsp_get_data (dsp);
  433 + dsp_out_data (dsp, 0xf8);
394 434 break;
395 435  
396   - case 0x10:
  436 + case 0x05:
  437 + case 0x0e:
  438 + dsp_get_data (dsp);
  439 + dsp_get_data (dsp);
397 440 break;
398 441  
399 442 case 0x14:
400 443 {
401   - int d0, d1;
402 444 int save_left;
403 445 int save_pos;
404 446  
405   - d0 = dsp->in_data[0];
406   - d1 = dsp->in_data[1];
  447 + d1 = dsp_get_data (dsp);
  448 + d0 = dsp_get_data (dsp);
407 449  
408 450 save_left = dsp->left_till_irq;
409 451 save_pos = dsp->dma_pos;
... ... @@ -417,35 +459,60 @@ static void complete (SB16State *dsp)
417 459 }
418 460  
419 461 case 0x40:
420   - dsp->time_const = dsp->in_data[0];
  462 + dsp->time_const = dsp_get_data (dsp);
421 463 linfo ("set time const %d\n", dsp->time_const);
422 464 break;
423 465  
424 466 case 0x41:
425 467 case 0x42:
426   - dsp->freq = dsp->in_data[1] + (dsp->in_data[0] << 8);
427   - linfo ("set freq %#x, %#x = %d\n",
428   - dsp->in_data[1], dsp->in_data[0], dsp->freq);
  468 + d1 = dsp_get_data (dsp);
  469 + d0 = dsp_get_data (dsp);
  470 +
  471 + dsp->freq = d1 + (d0 << 8);
  472 + linfo ("set freq %#x, %#x = %d\n", d1, d0, dsp->freq);
429 473 break;
430 474  
431 475 case 0x48:
432   - dsp->dma_buffer_size = dsp->in_data[1] + (dsp->in_data[0] << 8);
  476 + d1 = dsp_get_data (dsp);
  477 + d0 = dsp_get_data (dsp);
  478 + dsp->dma_buffer_size = d1 + (d0 << 8);
433 479 linfo ("set dma len %#x, %#x = %d\n",
434   - dsp->in_data[1], dsp->in_data[0], dsp->dma_buffer_size);
  480 + d1, d0, dsp->dma_buffer_size);
435 481 break;
436 482  
437 483 case 0xe0:
  484 + d0 = dsp_get_data (dsp);
438 485 dsp->out_data_len = 0;
439   - linfo ("data = %#x\n", dsp->in_data[0]);
440   - dsp_out_data(dsp, dsp->in_data[0] ^ 0xff);
  486 + linfo ("data = %#x\n", d0);
  487 + dsp_out_data (dsp, d0 ^ 0xff);
  488 + break;
  489 +
  490 + case 0xe4:
  491 + dsp->test_reg = dsp_get_data (dsp);
  492 + break;
  493 +
  494 +
  495 + case 0xf9:
  496 + d0 = dsp_get_data (dsp);
  497 + ldebug ("f9 <- %#x\n", d0);
  498 + switch (d0) {
  499 + case 0x0e: dsp_out_data (dsp, 0xff); break;
  500 + case 0x0f: dsp_out_data (dsp, 0x07); break;
  501 + case 0xf9: dsp_out_data (dsp, 0x00); break;
  502 + case 0x37:
  503 + dsp_out_data (dsp, 0x38); break;
  504 + default:
  505 + dsp_out_data (dsp, 0);
  506 + }
441 507 break;
442 508  
443 509 default:
444   - log ("unrecognized command %#x", dsp->cmd);
  510 + dolog ("complete: unrecognized command %#x\n", dsp->cmd);
445 511 return;
446 512 }
447 513 }
448 514  
  515 + dsp->needed_bytes = 0;
449 516 dsp->cmd = -1;
450 517 return;
451 518 }
... ... @@ -457,7 +524,7 @@ static IO_WRITE_PROTO (dsp_write)
457 524  
458 525 iport = nport - sb.port;
459 526  
460   - ldebug ("write %#x %#x\n", nport, iport);
  527 + ldebug ("dsp_write %#x <- %#x\n", nport, val);
461 528 switch (iport) {
462 529 case 0x6:
463 530 control (0);
... ... @@ -465,6 +532,14 @@ static IO_WRITE_PROTO (dsp_write)
465 532 dsp->v2x6 = 0;
466 533 else if ((1 == val) && (0 == dsp->v2x6)) {
467 534 dsp->v2x6 = 1;
  535 + dsp->dma_pos = 0;
  536 + dsp->dma_auto = 0;
  537 + dsp->in_index = 0;
  538 + dsp->out_data_len = 0;
  539 + dsp->left_till_irq = 0;
  540 + dsp->speaker = 0;
  541 + dsp->needed_bytes = 0;
  542 + pic_set_irq (sb.irq, 0);
468 543 dsp_out_data(dsp, 0xaa);
469 544 }
470 545 else
... ... @@ -479,18 +554,22 @@ static IO_WRITE_PROTO (dsp_write)
479 554 }
480 555 }
481 556 else {
482   - dsp->in_data[dsp->in_index++] = val;
  557 + if (dsp->in_index == sizeof (dsp->in2_data)) {
  558 + dolog ("in data overrun\n");
  559 + }
  560 + else {
  561 + dsp->in2_data[dsp->in_index++] = val;
483 562 if (dsp->in_index == dsp->needed_bytes) {
484 563 dsp->needed_bytes = 0;
485   - dsp->in_index = 0;
486 564 complete (dsp);
487 565 log_dsp (dsp);
488 566 }
489 567 }
  568 + }
490 569 break;
491 570  
492 571 default:
493   - log ("(nport=%#x, val=%#x)", nport, val);
  572 + dolog ("dsp_write (nport=%#x, val=%#x)\n", nport, val);
494 573 break;
495 574 }
496 575 }
... ... @@ -503,31 +582,36 @@ static IO_READ_PROTO (dsp_read)
503 582 iport = nport - sb.port;
504 583  
505 584 switch (iport) {
506   -
507 585 case 0x6: /* reset */
508   - return 0;
  586 + control (0);
  587 + retval = 0;
  588 + dsp->speaker = 0;
  589 + break;
509 590  
510 591 case 0xa: /* read data */
511 592 if (dsp->out_data_len) {
512 593 retval = dsp->out_data[--dsp->out_data_len];
  594 + dsp->last_read_byte = retval;
513 595 } else {
514   - log("empty output buffer");
515   - goto error;
  596 + retval = dsp->last_read_byte;
  597 + dolog ("empty output buffer\n");
  598 + /* goto error; */
516 599 }
517 600 break;
518 601  
519   - case 0xc: /* 0 can write */
  602 + case 0xc: /* 0xxxxxxx can write */
520 603 retval = 0;
  604 + if (dsp->out_data_len == sizeof (dsp->out_data)) retval |= 0x80;
521 605 break;
522 606  
523 607 case 0xd: /* timer interrupt clear */
524   - log("timer interrupt clear");
  608 + dolog ("timer interrupt clear\n");
525 609 goto error;
526 610  
527 611 case 0xe: /* data available status | irq 8 ack */
528 612 /* XXX drop pic irq line here? */
529   - ldebug ("8 ack\n");
530   - retval = (0 == dsp->out_data_len) ? 0 : 0x80;
  613 + /* ldebug ("8 ack\n"); */
  614 + retval = dsp->out_data_len ? 0x80 : 0;
531 615 dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80];
532 616 pic_set_irq (sb.irq, 0);
533 617 break;
... ... @@ -544,15 +628,30 @@ static IO_READ_PROTO (dsp_read)
544 628 goto error;
545 629 }
546 630  
547   - if ((0xc != iport) && (0xe != iport)) {
548   - ldebug ("nport=%#x iport %#x = %#x\n",
  631 + if (0xe == iport) {
  632 + if (0 == retval) {
  633 + if (!dsp->nzero) {
  634 + ldebug ("dsp_read (nport=%#x iport %#x) = %#x, %lld\n",
  635 + nport, iport, retval, dsp->nzero);
  636 + }
  637 + dsp->nzero += 1;
  638 + }
  639 + else {
  640 + ldebug ("dsp_read (nport=%#x iport %#x) = %#x, %lld\n",
  641 + nport, iport, retval, dsp->nzero);
  642 + dsp->nzero = 0;
  643 + }
  644 + }
  645 + else {
  646 + ldebug ("dsp_read (nport=%#x iport %#x) = %#x\n",
549 647 nport, iport, retval);
550 648 }
551 649  
552 650 return retval;
553 651  
554 652 error:
555   - return 0;
  653 + printf ("dsp_read error %#x\n", nport);
  654 + return 0xff;
556 655 }
557 656  
558 657 static IO_WRITE_PROTO(mixer_write_indexb)
... ... @@ -564,12 +663,100 @@ static IO_WRITE_PROTO(mixer_write_indexb)
564 663 static IO_WRITE_PROTO(mixer_write_datab)
565 664 {
566 665 SB16State *dsp = opaque;
  666 + int i;
567 667  
568   - if (dsp->mixer_nreg > 0x83)
  668 + linfo ("mixer [%#x] <- %#x\n", dsp->mixer_nreg, val);
  669 + switch (dsp->mixer_nreg) {
  670 + case 0x00:
  671 + /* Bochs */
  672 + dsp->mixer_regs[0x04] = 0xcc;
  673 + dsp->mixer_regs[0x0a] = 0x00;
  674 + dsp->mixer_regs[0x22] = 0xcc;
  675 + dsp->mixer_regs[0x26] = 0xcc;
  676 + dsp->mixer_regs[0x28] = 0x00;
  677 + dsp->mixer_regs[0x2e] = 0x00;
  678 + dsp->mixer_regs[0x3c] = 0x1f;
  679 + dsp->mixer_regs[0x3d] = 0x15;
  680 + dsp->mixer_regs[0x3e] = 0x0b;
  681 +
  682 + for (i = 0x30; i <= 0x35; i++)
  683 + dsp->mixer_regs[i] = 0xc0;
  684 +
  685 + for (i = 0x36; i <= 0x3b; i++)
  686 + dsp->mixer_regs[i] = 0x00;
  687 +
  688 + for (i = 0x3f; i <= 0x43; i++)
  689 + dsp->mixer_regs[i] = 0x00;
  690 +
  691 + for (i = 0x44; i <= 0x47; i++)
  692 + dsp->mixer_regs[i] = 0x80;
  693 +
  694 + for (i = 0x30; i < 0x48; i++) {
  695 + dsp->mixer_regs[i] = 0x20;
  696 + }
  697 + break;
  698 +
  699 + case 0x04:
  700 + case 0x0a:
  701 + case 0x22:
  702 + case 0x26:
  703 + case 0x28:
  704 + case 0x2e:
  705 + case 0x30:
  706 + case 0x31:
  707 + case 0x32:
  708 + case 0x33:
  709 + case 0x34:
  710 + case 0x35:
  711 + case 0x36:
  712 + case 0x37:
  713 + case 0x38:
  714 + case 0x39:
  715 + case 0x3a:
  716 + case 0x3b:
  717 + case 0x3c:
  718 + case 0x3d:
  719 + case 0x3e:
  720 + case 0x3f:
  721 + case 0x40:
  722 + case 0x41:
  723 + case 0x42:
  724 + case 0x43:
  725 + case 0x44:
  726 + case 0x45:
  727 + case 0x46:
  728 + case 0x47:
  729 + case 0x80:
  730 + case 0x81:
  731 + break;
  732 + default:
569 733 return;
  734 + }
570 735 dsp->mixer_regs[dsp->mixer_nreg] = val;
571 736 }
572 737  
  738 +static IO_WRITE_PROTO(mpu_write)
  739 +{
  740 + linfo ("mpu: %#x\n", val);
  741 +}
  742 +
  743 +static IO_WRITE_PROTO(adlib_write)
  744 +{
  745 + linfo ("adlib: %#x\n", val);
  746 +}
  747 +
  748 +static IO_READ_PROTO(mpu_read)
  749 +{
  750 + linfo ("mpu read: %#x\n", nport);
  751 + return 0x80;
  752 +}
  753 +
  754 +static IO_READ_PROTO(adlib_read)
  755 +{
  756 + linfo ("adlib read: %#x\n", nport);
  757 + return 0;
  758 +}
  759 +
573 760 static IO_WRITE_PROTO(mixer_write_indexw)
574 761 {
575 762 mixer_write_indexb (opaque, nport, val & 0xff);
... ... @@ -579,6 +766,7 @@ static IO_WRITE_PROTO(mixer_write_indexw)
579 766 static IO_READ_PROTO(mixer_read)
580 767 {
581 768 SB16State *dsp = opaque;
  769 + linfo ("mixer [%#x] -> %#x\n", dsp->mixer_nreg, dsp->mixer_regs[dsp->mixer_nreg]);
582 770 return dsp->mixer_regs[dsp->mixer_nreg];
583 771 }
584 772  
... ... @@ -637,6 +825,8 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
637 825 return 0;
638 826  
639 827 if (dsp->left_till_irq < 0) {
  828 + ldebug ("left_till_irq < 0, %d, pos %d \n",
  829 + dsp->left_till_irq, dsp->dma_buffer_size);
640 830 dsp->left_till_irq += dsp->dma_buffer_size;
641 831 return dsp->dma_pos;
642 832 }
... ... @@ -644,6 +834,7 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
644 834 free = AUD_get_free ();
645 835  
646 836 if ((free <= 0) || (0 == size)) {
  837 + ldebug ("returning, since free = %d and size = %d\n", free, size);
647 838 return dsp->dma_pos;
648 839 }
649 840  
... ... @@ -656,8 +847,11 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
656 847  
657 848 till = dsp->left_till_irq;
658 849  
  850 +#ifdef DEBUG_SB16_MOST
659 851 ldebug ("addr:%#010x free:%d till:%d size:%d\n",
660 852 addr, free, till, size);
  853 +#endif
  854 +
661 855 if (till <= copy) {
662 856 if (0 == dsp->dma_auto) {
663 857 copy = till;
... ... @@ -671,7 +865,8 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
671 865 if (dsp->left_till_irq <= 0) {
672 866 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
673 867 if (0 == noirq) {
674   - ldebug ("request irq\n");
  868 + ldebug ("request irq pos %d, left %d\n",
  869 + dsp->dma_pos, dsp->left_till_irq);
675 870 pic_set_irq(sb.irq, 1);
676 871 }
677 872  
... ... @@ -680,9 +875,11 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
680 875 }
681 876 }
682 877  
  878 +#ifdef DEBUG_SB16_MOST
683 879 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
684 880 dsp->dma_pos, free, size, dsp->left_till_irq, copy,
685 881 dsp->dma_buffer_size);
  882 +#endif
686 883  
687 884 if (dsp->left_till_irq <= 0) {
688 885 dsp->left_till_irq += dsp->dma_buffer_size;
... ... @@ -703,7 +900,7 @@ static int magic_of_irq (int irq)
703 900 case 10:
704 901 return 8;
705 902 default:
706   - log ("bad irq %d", irq);
  903 + dolog ("bad irq %d\n", irq);
707 904 return 2;
708 905 }
709 906 }
... ... @@ -721,12 +918,42 @@ static int irq_of_magic (int magic)
721 918 case 8:
722 919 return 10;
723 920 default:
724   - log ("bad irq magic %d", magic);
  921 + dolog ("bad irq magic %d\n", magic);
725 922 return 2;
726 923 }
727 924 }
728 925 #endif
729 926  
  927 +#ifdef SB16_TRAP_ALL
  928 +static IO_READ_PROTO (trap_read)
  929 +{
  930 + switch (nport) {
  931 + case 0x220:
  932 + return 0;
  933 + case 0x226:
  934 + case 0x22a:
  935 + case 0x22c:
  936 + case 0x22d:
  937 + case 0x22e:
  938 + case 0x22f:
  939 + return dsp_read (opaque, nport);
  940 + }
  941 + linfo ("trap_read: %#x\n", nport);
  942 + return 0xff;
  943 +}
  944 +
  945 +static IO_WRITE_PROTO (trap_write)
  946 +{
  947 + switch (nport) {
  948 + case 0x226:
  949 + case 0x22c:
  950 + dsp_write (opaque, nport, val);
  951 + return;
  952 + }
  953 + linfo ("trap_write: %#x = %#x\n", nport, val);
  954 +}
  955 +#endif
  956 +
730 957 void SB16_init (void)
731 958 {
732 959 SB16State *s = &dsp;
... ... @@ -736,13 +963,23 @@ void SB16_init (void)
736 963  
737 964 memset(s->mixer_regs, 0xff, sizeof(s->mixer_regs));
738 965  
  966 + s->mixer_regs[0x00] = 0;
739 967 s->mixer_regs[0x0e] = ~0;
740 968 s->mixer_regs[0x80] = magic_of_irq (sb.irq);
741   - s->mixer_regs[0x81] = 0x20 | (sb.dma << 1);
742   -
743   - for (i = 0x30; i < 0x48; i++) {
744   - s->mixer_regs[i] = 0x20;
  969 + s->mixer_regs[0x81] = 0x80 | 0x10 | (sb.dma << 1);
  970 + s->mixer_regs[0x82] = 0;
  971 + s->mixer_regs[0xfd] = 16; /* bochs */
  972 + s->mixer_regs[0xfe] = 6; /* bochs */
  973 + mixer_write_indexw (s, 0x224, 0);
  974 +
  975 +#ifdef SB16_TRAP_ALL
  976 + for (i = 0; i < 0x100; i++) {
  977 + if (i != 4 && i != 5) {
  978 + register_ioport_write (sb.port + i, 1, 1, trap_write, s);
  979 + register_ioport_read (sb.port + i, 1, 1, trap_read, s);
  980 + }
745 981 }
  982 +#else
746 983  
747 984 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
748 985 register_ioport_write (sb.port + dsp_write_ports[i], 1, 1, dsp_write, s);
... ... @@ -751,12 +988,20 @@ void SB16_init (void)
751 988 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
752 989 register_ioport_read (sb.port + dsp_read_ports[i], 1, 1, dsp_read, s);
753 990 }
  991 +#endif
754 992  
755 993 register_ioport_write (sb.port + 0x4, 1, 1, mixer_write_indexb, s);
756 994 register_ioport_write (sb.port + 0x4, 1, 2, mixer_write_indexw, s);
757 995 register_ioport_read (sb.port + 0x5, 1, 1, mixer_read, s);
758 996 register_ioport_write (sb.port + 0x5, 1, 1, mixer_write_datab, s);
759 997  
  998 + for (i = 0; 4 < 4; i++) {
  999 + register_ioport_read (0x330 + i, 1, 1, mpu_read, s);
  1000 + register_ioport_write (0x330 + i, 1, 1, mpu_write, s);
  1001 + register_ioport_read (0x388 + i, 1, 1, adlib_read, s);
  1002 + register_ioport_write (0x388 + i, 1, 1, adlib_write, s);
  1003 + }
  1004 +
760 1005 DMA_register_channel (sb.hdma, SB_read_DMA, s);
761 1006 DMA_register_channel (sb.dma, SB_read_DMA, s);
762 1007 }
... ...
... ... @@ -23,22 +23,446 @@
23 23 */
24 24 #include "vl.h"
25 25  
26   -#if !defined(_WIN32) && !defined(__APPLE__)
27   -#include <ctype.h>
  26 +#include <stdio.h>
  27 +#include <limits.h>
  28 +#include <stdlib.h>
  29 +#include <string.h>
  30 +
  31 +/* TODO: Graceful error handling */
  32 +
  33 +#if defined(_WIN32)
  34 +#define USE_SDL_AUDIO
  35 +#endif
  36 +
  37 +#define MIN(a, b) ((a)>(b)?(b):(a))
  38 +#define MAX(a, b) ((a)<(b)?(b):(a))
  39 +
  40 +#define DEREF(x) (void)x
  41 +#define dolog(...) fprintf (stderr, "audio: " __VA_ARGS__)
  42 +#define ERRFail(...) do { \
  43 + int _errno = errno; \
  44 + fprintf (stderr, "audio: " __VA_ARGS__); \
  45 + fprintf (stderr, "\nsystem error: %s\n", strerror (_errno)); \
  46 + abort (); \
  47 +} while (0)
  48 +#define Fail(...) do { \
  49 + fprintf (stderr, "audio: " __VA_ARGS__); \
  50 + fprintf (stderr, "\n"); \
  51 + abort (); \
  52 +} while (0)
  53 +
  54 +#ifdef DEBUG_AUDIO
  55 +#define lwarn(...) fprintf (stderr, "audio: " __VA_ARGS__)
  56 +#define linfo(...) fprintf (stderr, "audio: " __VA_ARGS__)
  57 +#define ldebug(...) fprintf (stderr, "audio: " __VA_ARGS__)
  58 +#else
  59 +#define lwarn(...)
  60 +#define linfo(...)
  61 +#define ldebug(...)
  62 +#endif
  63 +
  64 +static int get_conf_val (const char *key, int defval)
  65 +{
  66 + int val = defval;
  67 + char *strval;
  68 +
  69 + strval = getenv (key);
  70 + if (strval) {
  71 + val = atoi (strval);
  72 + }
  73 +
  74 + return val;
  75 +}
  76 +
  77 +static void copy_no_conversion (void *dst, void *src, int size)
  78 +{
  79 + memcpy (dst, src, size);
  80 +}
  81 +
  82 +static void copy_u16_to_s16 (void *dst, void *src, int size)
  83 +{
  84 + int i;
  85 + uint16_t *out, *in;
  86 +
  87 + out = dst;
  88 + in = src;
  89 +
  90 + for (i = 0; i < size / 2; i++) {
  91 + out[i] = in[i] + 0x8000;
  92 + }
  93 +}
  94 +
  95 +#ifdef USE_SDL_AUDIO
  96 +#include <SDL/SDL.h>
  97 +#include <SDL/SDL_thread.h>
  98 +
  99 +static struct {
  100 + int samples;
  101 +} conf = {
  102 + .samples = 4096
  103 +};
  104 +
  105 +typedef struct AudioState {
  106 + int freq;
  107 + int bits16;
  108 + int nchannels;
  109 + int rpos;
  110 + int wpos;
  111 + volatile int live;
  112 + volatile int exit;
  113 + int bytes_per_second;
  114 + Uint8 *buf;
  115 + int bufsize;
  116 + int leftover;
  117 + uint64_t old_ticks;
  118 + SDL_AudioSpec spec;
  119 + SDL_mutex *mutex;
  120 + SDL_sem *sem;
  121 + void (*copy_fn)(void *, void *, int);
  122 +} AudioState;
  123 +
  124 +static AudioState sdl_audio;
  125 +
  126 +void AUD_run (void)
  127 +{
  128 +}
  129 +
  130 +static void own (AudioState *s)
  131 +{
  132 + /* SDL_LockAudio (); */
  133 + if (SDL_mutexP (s->mutex))
  134 + dolog ("SDL_mutexP: %s\n", SDL_GetError ());
  135 +}
  136 +
  137 +static void disown (AudioState *s)
  138 +{
  139 + /* SDL_UnlockAudio (); */
  140 + if (SDL_mutexV (s->mutex))
  141 + dolog ("SDL_mutexV: %s\n", SDL_GetError ());
  142 +}
  143 +
  144 +static void sem_wait (AudioState *s)
  145 +{
  146 + if (SDL_SemWait (s->sem))
  147 + dolog ("SDL_SemWait: %s\n", SDL_GetError ());
  148 +}
  149 +
  150 +static void sem_post (AudioState *s)
  151 +{
  152 + if (SDL_SemPost (s->sem))
  153 + dolog ("SDL_SemPost: %s\n", SDL_GetError ());
  154 +}
  155 +
  156 +static void audio_callback (void *data, Uint8 *stream, int len)
  157 +{
  158 + int to_mix;
  159 + AudioState *s = data;
  160 +
  161 + if (s->exit) return;
  162 + while (len) {
  163 + sem_wait (s);
  164 + if (s->exit) return;
  165 + own (s);
  166 + to_mix = MIN (len, s->live);
  167 + len -= to_mix;
  168 + /* printf ("to_mix=%d len=%d live=%d\n", to_mix, len, s->live); */
  169 + while (to_mix) {
  170 + int chunk = MIN (to_mix, s->bufsize - s->rpos);
  171 + /* SDL_MixAudio (stream, buf, chunk, SDL_MIX_MAXVOLUME); */
  172 + memcpy (stream, s->buf + s->rpos, chunk);
  173 +
  174 + s->rpos += chunk;
  175 + s->live -= chunk;
  176 +
  177 + stream += chunk;
  178 + to_mix -= chunk;
  179 +
  180 + if (s->rpos == s->bufsize) s->rpos = 0;
  181 + }
  182 + disown (s);
  183 + }
  184 +}
  185 +
  186 +static void sem_zero (AudioState *s)
  187 +{
  188 + int res;
  189 +
  190 + do {
  191 + res = SDL_SemTryWait (s->sem);
  192 + if (res < 0) {
  193 + dolog ("SDL_SemTryWait: %s\n", SDL_GetError ());
  194 + return;
  195 + }
  196 + } while (res != SDL_MUTEX_TIMEDOUT);
  197 +}
  198 +
  199 +static void do_open (AudioState *s)
  200 +{
  201 + int status;
  202 + SDL_AudioSpec obtained;
  203 +
  204 + SDL_PauseAudio (1);
  205 + if (s->buf) {
  206 + s->exit = 1;
  207 + sem_post (s);
  208 + SDL_CloseAudio ();
  209 + s->exit = 0;
  210 + qemu_free (s->buf);
  211 + s->buf = NULL;
  212 + sem_zero (s);
  213 + }
  214 +
  215 + s->bytes_per_second = (s->spec.freq << (s->spec.channels >> 1)) << s->bits16;
  216 + s->spec.samples = conf.samples;
  217 + s->spec.userdata = s;
  218 + s->spec.callback = audio_callback;
  219 +
  220 + status = SDL_OpenAudio (&s->spec, &obtained);
  221 + if (status < 0) {
  222 + dolog ("SDL_OpenAudio: %s\n", SDL_GetError ());
  223 + goto exit;
  224 + }
  225 +
  226 + if (obtained.freq != s->spec.freq ||
  227 + obtained.channels != s->spec.channels ||
  228 + obtained.format != s->spec.format) {
  229 + dolog ("Audio spec mismatch requested obtained\n"
  230 + "freq %5d %5d\n"
  231 + "channels %5d %5d\n"
  232 + "fmt %5d %5d\n",
  233 + s->spec.freq, obtained.freq,
  234 + s->spec.channels, obtained.channels,
  235 + s->spec.format, obtained.format
  236 + );
  237 + }
  238 +
  239 + s->bufsize = obtained.size;
  240 + s->buf = qemu_mallocz (s->bufsize);
  241 + if (!s->buf) {
  242 + dolog ("qemu_mallocz(%d)\n", s->bufsize);
  243 + goto exit;
  244 + }
  245 + SDL_PauseAudio (0);
  246 +
  247 +exit:
  248 + s->rpos = 0;
  249 + s->wpos = 0;
  250 + s->live = 0;
  251 +}
  252 +
  253 +int AUD_write (void *in_buf, int size)
  254 +{
  255 + AudioState *s = &sdl_audio;
  256 + int to_copy, temp;
  257 + uint8_t *in, *out;
  258 +
  259 + own (s);
  260 + to_copy = MIN (s->bufsize - s->live, size);
  261 +
  262 + temp = to_copy;
  263 +
  264 + in = in_buf;
  265 + out = s->buf;
  266 +
  267 + while (temp) {
  268 + int copy;
  269 +
  270 + copy = MIN (temp, s->bufsize - s->wpos);
  271 + s->copy_fn (out + s->wpos, in, copy);
  272 +
  273 + s->wpos += copy;
  274 + if (s->wpos == s->bufsize) {
  275 + s->wpos = 0;
  276 + }
  277 +
  278 + temp -= copy;
  279 + in += copy;
  280 + s->live += copy;
  281 + }
  282 +
  283 + disown (s);
  284 + sem_post (s);
  285 + return to_copy;
  286 +}
  287 +
  288 +static void maybe_open (AudioState *s, int req_freq, int req_nchannels,
  289 + audfmt_e req_fmt, int force_open)
  290 +{
  291 + int sdl_fmt, bits16;
  292 +
  293 + switch (req_fmt) {
  294 + case AUD_FMT_U8:
  295 + bits16 = 0;
  296 + sdl_fmt = AUDIO_U8;
  297 + s->copy_fn = copy_no_conversion;
  298 + break;
  299 +
  300 + case AUD_FMT_S8:
  301 + fprintf (stderr, "audio: can not play 8bit signed\n");
  302 + return;
  303 +
  304 + case AUD_FMT_S16:
  305 + bits16 = 1;
  306 + sdl_fmt = AUDIO_S16;
  307 + s->copy_fn = copy_no_conversion;
  308 + break;
  309 +
  310 + case AUD_FMT_U16:
  311 + bits16 = 1;
  312 + sdl_fmt = AUDIO_S16;
  313 + s->copy_fn = copy_u16_to_s16;
  314 + break;
  315 +
  316 + default:
  317 + abort ();
  318 + }
  319 +
  320 + if (force_open
  321 + || (NULL == s->buf)
  322 + || (sdl_fmt != s->spec.format)
  323 + || (req_nchannels != s->spec.channels)
  324 + || (req_freq != s->spec.freq)
  325 + || (bits16 != s->bits16)) {
  326 +
  327 + s->spec.format = sdl_fmt;
  328 + s->spec.channels = req_nchannels;
  329 + s->spec.freq = req_freq;
  330 + s->bits16 = bits16;
  331 + do_open (s);
  332 + }
  333 +}
  334 +
  335 +void AUD_reset (int req_freq, int req_nchannels, audfmt_e req_fmt)
  336 +{
  337 + AudioState *s = &sdl_audio;
  338 + own (s);
  339 + maybe_open (s, req_freq, req_nchannels, req_fmt, 0);
  340 + disown (s);
  341 +}
  342 +
  343 +void AUD_open (int req_freq, int req_nchannels, audfmt_e req_fmt)
  344 +{
  345 + AudioState *s = &sdl_audio;
  346 + own (s);
  347 + maybe_open (s, req_freq, req_nchannels, req_fmt, 1);
  348 + disown (s);
  349 +}
  350 +
  351 +void AUD_adjust_estimate (int leftover)
  352 +{
  353 + AudioState *s = &sdl_audio;
  354 + own (s);
  355 + s->leftover = leftover;
  356 + disown (s);
  357 +}
  358 +
  359 +int AUD_get_free (void)
  360 +{
  361 + int free, elapsed;
  362 + uint64_t ticks, delta;
  363 + uint64_t ua_elapsed;
  364 + uint64_t al_elapsed;
  365 + AudioState *s = &sdl_audio;
  366 +
  367 + own (s);
  368 + free = s->bufsize - s->live;
  369 +
  370 + if (0 == free) {
  371 + disown (s);
  372 + return 0;
  373 + }
  374 +
  375 + elapsed = free;
  376 + ticks = qemu_get_clock(rt_clock);
  377 + delta = ticks - s->old_ticks;
  378 + s->old_ticks = ticks;
  379 +
  380 + ua_elapsed = (delta * s->bytes_per_second) / 1000;
  381 + al_elapsed = ua_elapsed & ~3ULL;
  382 +
  383 + ldebug ("tid elapsed %llu bytes\n", ua_elapsed);
  384 +
  385 + if (al_elapsed > (uint64_t) INT_MAX)
  386 + elapsed = INT_MAX;
  387 + else
  388 + elapsed = al_elapsed;
  389 +
  390 + elapsed += s->leftover;
  391 + disown (s);
  392 +
  393 + if (elapsed > free) {
  394 + lwarn ("audio can not keep up elapsed %d free %d\n", elapsed, free);
  395 + return free;
  396 + }
  397 + else {
  398 + return elapsed;
  399 + }
  400 +}
  401 +
  402 +int AUD_get_live (void)
  403 +{
  404 + int live;
  405 + AudioState *s = &sdl_audio;
  406 +
  407 + own (s);
  408 + live = s->live;
  409 + disown (s);
  410 + return live;
  411 +}
  412 +
  413 +int AUD_get_buffer_size (void)
  414 +{
  415 + int bufsize;
  416 + AudioState *s = &sdl_audio;
  417 +
  418 + own (s);
  419 + bufsize = s->bufsize;
  420 + disown (s);
  421 + return bufsize;
  422 +}
  423 +
  424 +#define QC_SDL_NSAMPLES "QEMU_SDL_NSAMPLES"
  425 +
  426 +static void cleanup (void)
  427 +{
  428 + AudioState *s = &sdl_audio;
  429 + own (s);
  430 + s->exit = 1;
  431 + sem_post (s);
  432 + disown (s);
  433 +}
  434 +
  435 +void AUD_init (void)
  436 +{
  437 + AudioState *s = &sdl_audio;
  438 +
  439 + atexit (cleanup);
  440 + SDL_InitSubSystem (SDL_INIT_AUDIO);
  441 + s->mutex = SDL_CreateMutex ();
  442 + if (!s->mutex) {
  443 + dolog ("SDL_CreateMutex: %s\n", SDL_GetError ());
  444 + return;
  445 + }
  446 +
  447 + s->sem = SDL_CreateSemaphore (0);
  448 + if (!s->sem) {
  449 + dolog ("SDL_CreateSemaphore: %s\n", SDL_GetError ());
  450 + return;
  451 + }
  452 +
  453 + conf.samples = get_conf_val (QC_SDL_NSAMPLES, conf.samples);
  454 +}
  455 +
  456 +#elif !defined(_WIN32) && !defined(__APPLE__)
  457 +
28 458 #include <fcntl.h>
29 459 #include <errno.h>
30   -#include <stdio.h>
31 460 #include <unistd.h>
32   -#include <string.h>
33   -#include <stdlib.h>
34   -#include <limits.h>
35   -#include <inttypes.h>
36 461 #include <sys/mman.h>
37 462 #include <sys/types.h>
38 463 #include <sys/ioctl.h>
39 464 #include <sys/soundcard.h>
40 465  
41   -
42 466 /* http://www.df.lth.se/~john_e/gems/gem002d.html */
43 467 /* http://www.multi-platforms.com/Tips/PopCount.htm */
44 468 static inline uint32_t popcount (uint32_t u)
... ... @@ -56,34 +480,6 @@ static inline uint32_t lsbindex (uint32_t u)
56 480 return popcount ((u&-u)-1);
57 481 }
58 482  
59   -#define MIN(a, b) ((a)>(b)?(b):(a))
60   -#define MAX(a, b) ((a)<(b)?(b):(a))
61   -
62   -#define DEREF(x) (void)x
63   -#define log(...) fprintf (stderr, "oss: " __VA_ARGS__)
64   -#define ERRFail(...) do { \
65   - int _errno = errno; \
66   - fprintf (stderr, "oss: " __VA_ARGS__); \
67   - fprintf (stderr, "system error: %s\n", strerror (_errno)); \
68   - abort (); \
69   -} while (0)
70   -#define Fail(...) do { \
71   - fprintf (stderr, "oss: " __VA_ARGS__); \
72   - fprintf (stderr, "\n"); \
73   - abort (); \
74   -} while (0)
75   -
76   -#ifdef DEBUG_OSS
77   -#define lwarn(...) fprintf (stderr, "oss: " __VA_ARGS__)
78   -#define linfo(...) fprintf (stderr, "oss: " __VA_ARGS__)
79   -#define ldebug(...) fprintf (stderr, "oss: " __VA_ARGS__)
80   -#else
81   -#define lwarn(...)
82   -#define linfo(...)
83   -#define ldebug(...)
84   -#endif
85   -
86   -
87 483 #define IOCTL(args) do { \
88 484 int ret = ioctl args; \
89 485 if (-1 == ret) { \
... ... @@ -92,7 +488,7 @@ static inline uint32_t lsbindex (uint32_t u)
92 488 ldebug ("ioctl " #args " = %d\n", ret); \
93 489 } while (0)
94 490  
95   -static struct {
  491 +typedef struct AudioState {
96 492 int fd;
97 493 int freq;
98 494 int bits16;
... ... @@ -111,7 +507,9 @@ static struct {
111 507 int leftover;
112 508 uint64_t old_ticks;
113 509 void (*copy_fn)(void *, void *, int);
114   -} oss = { .fd = -1 };
  510 +} AudioState;
  511 +
  512 +static AudioState oss_audio = { .fd = -1 };
115 513  
116 514 static struct {
117 515 int try_mmap;
... ... @@ -125,25 +523,7 @@ static struct {
125 523  
126 524 static enum {DONT, DSP, TID} est = DONT;
127 525  
128   -static void copy_no_conversion (void *dst, void *src, int size)
129   -{
130   - memcpy (dst, src, size);
131   -}
132   -
133   -static void copy_u16_to_s16 (void *dst, void *src, int size)
134   -{
135   - int i;
136   - uint16_t *out, *in;
137   -
138   - out = dst;
139   - in = src;
140   -
141   - for (i = 0; i < size / 2; i++) {
142   - out[i] = in[i] + 0x8000;
143   - }
144   -}
145   -
146   -static void pab (struct audio_buf_info *abinfo)
  526 +static void pab (AudioState *s, struct audio_buf_info *abinfo)
147 527 {
148 528 DEREF (abinfo);
149 529  
... ... @@ -153,118 +533,122 @@ static void pab (struct audio_buf_info *abinfo)
153 533 abinfo->fragstotal,
154 534 abinfo->fragsize,
155 535 abinfo->bytes,
156   - rpos, wpos, live);
  536 + s->rpos, s->wpos, s->live);
157 537 }
158 538  
159   -static void do_open ()
  539 +static void do_open (AudioState *s)
160 540 {
161 541 int mmmmssss;
162 542 audio_buf_info abinfo;
163 543 int fmt, freq, nchannels;
164 544  
165   - if (oss.buf) {
166   - if (-1 == munmap (oss.buf, oss.bufsize)) {
  545 + if (s->buf) {
  546 + if (s->is_mapped) {
  547 + if (-1 == munmap (s->buf, s->bufsize)) {
167 548 ERRFail ("failed to unmap audio buffer %p %d",
168   - oss.buf, oss.bufsize);
  549 + s->buf, s->bufsize);
  550 + }
169 551 }
170   - oss.buf = NULL;
  552 + else {
  553 + qemu_free (s->buf);
  554 + }
  555 + s->buf = NULL;
171 556 }
172 557  
173   - if (-1 != oss.fd)
174   - close (oss.fd);
  558 + if (-1 != s->fd)
  559 + close (s->fd);
175 560  
176   - oss.fd = open ("/dev/dsp", O_RDWR | O_NONBLOCK);
177   - if (-1 == oss.fd) {
  561 + s->fd = open ("/dev/dsp", O_RDWR | O_NONBLOCK);
  562 + if (-1 == s->fd) {
178 563 ERRFail ("can not open /dev/dsp");
179 564 }
180 565  
181   - fmt = oss.oss_fmt;
182   - freq = oss.freq;
183   - nchannels = oss.nchannels;
  566 + fmt = s->oss_fmt;
  567 + freq = s->freq;
  568 + nchannels = s->nchannels;
184 569  
185   - IOCTL ((oss.fd, SNDCTL_DSP_RESET, 1));
186   - IOCTL ((oss.fd, SNDCTL_DSP_SAMPLESIZE, &fmt));
187   - IOCTL ((oss.fd, SNDCTL_DSP_CHANNELS, &nchannels));
188   - IOCTL ((oss.fd, SNDCTL_DSP_SPEED, &freq));
189   - IOCTL ((oss.fd, SNDCTL_DSP_NONBLOCK));
  570 + IOCTL ((s->fd, SNDCTL_DSP_RESET, 1));
  571 + IOCTL ((s->fd, SNDCTL_DSP_SAMPLESIZE, &fmt));
  572 + IOCTL ((s->fd, SNDCTL_DSP_CHANNELS, &nchannels));
  573 + IOCTL ((s->fd, SNDCTL_DSP_SPEED, &freq));
  574 + IOCTL ((s->fd, SNDCTL_DSP_NONBLOCK));
190 575  
191 576 mmmmssss = (conf.nfrags << 16) | conf.fragsize;
192   - IOCTL ((oss.fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss));
  577 + IOCTL ((s->fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss));
193 578  
194   - if ((oss.oss_fmt != fmt)
195   - || (oss.nchannels != nchannels)
196   - || (oss.freq != freq)) {
  579 + if ((s->oss_fmt != fmt)
  580 + || (s->nchannels != nchannels)
  581 + || (s->freq != freq)) {
197 582 Fail ("failed to set audio parameters\n"
198 583 "parameter | requested value | obtained value\n"
199 584 "format | %10d | %10d\n"
200 585 "channels | %10d | %10d\n"
201 586 "frequency | %10d | %10d\n",
202   - oss.oss_fmt, fmt,
203   - oss.nchannels, nchannels,
204   - oss.freq, freq);
  587 + s->oss_fmt, fmt,
  588 + s->nchannels, nchannels,
  589 + s->freq, freq);
205 590 }
206 591  
207   - IOCTL ((oss.fd, SNDCTL_DSP_GETOSPACE, &abinfo));
  592 + IOCTL ((s->fd, SNDCTL_DSP_GETOSPACE, &abinfo));
208 593  
209   - oss.nfrags = abinfo.fragstotal;
210   - oss.fragsize = abinfo.fragsize;
211   - oss.bufsize = oss.nfrags * oss.fragsize;
212   - oss.old_optr = 0;
  594 + s->nfrags = abinfo.fragstotal;
  595 + s->fragsize = abinfo.fragsize;
  596 + s->bufsize = s->nfrags * s->fragsize;
  597 + s->old_optr = 0;
213 598  
214   - oss.bytes_per_second = (freq << (nchannels >> 1)) << oss.bits16;
  599 + s->bytes_per_second = (freq << (nchannels >> 1)) << s->bits16;
215 600  
216   - linfo ("bytes per second %d\n", oss.bytes_per_second);
  601 + linfo ("bytes per second %d\n", s->bytes_per_second);
217 602  
218 603 linfo ("fragments %d, fragstotal %d, fragsize %d, bytes %d, bufsize %d\n",
219 604 abinfo.fragments,
220 605 abinfo.fragstotal,
221 606 abinfo.fragsize,
222 607 abinfo.bytes,
223   - oss.bufsize);
  608 + s->bufsize);
224 609  
225   - oss.buf = MAP_FAILED;
226   - oss.is_mapped = 0;
  610 + s->buf = MAP_FAILED;
  611 + s->is_mapped = 0;
227 612  
228 613 if (conf.try_mmap) {
229   - oss.buf = mmap (NULL, oss.bufsize, PROT_WRITE, MAP_SHARED, oss.fd, 0);
230   - if (MAP_FAILED == oss.buf) {
  614 + s->buf = mmap (NULL, s->bufsize, PROT_WRITE, MAP_SHARED, s->fd, 0);
  615 + if (MAP_FAILED == s->buf) {
231 616 int err;
232 617  
233 618 err = errno;
234   - log ("failed to mmap audio, size %d, fd %d\n"
  619 + dolog ("failed to mmap audio, size %d, fd %d\n"
235 620 "syserr: %s\n",
236   - oss.bufsize, oss.fd, strerror (err));
  621 + s->bufsize, s->fd, strerror (err));
237 622 }
238 623 else {
239 624 est = TID;
240   - oss.is_mapped = 1;
  625 + s->is_mapped = 1;
241 626 }
242 627 }
243 628  
244   - if (MAP_FAILED == oss.buf) {
  629 + if (MAP_FAILED == s->buf) {
245 630 est = TID;
246   - oss.buf = mmap (NULL, oss.bufsize, PROT_READ | PROT_WRITE,
247   - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
248   - if (MAP_FAILED == oss.buf) {
249   - ERRFail ("mmap audio buf, size %d", oss.bufsize);
  631 + s->buf = qemu_mallocz (s->bufsize);
  632 + if (!s->buf) {
  633 + ERRFail ("audio buf malloc failed, size %d", s->bufsize);
250 634 }
251 635 }
252 636  
253   - oss.rpos = 0;
254   - oss.wpos = 0;
255   - oss.live = 0;
  637 + s->rpos = 0;
  638 + s->wpos = 0;
  639 + s->live = 0;
256 640  
257   - if (oss.is_mapped) {
  641 + if (s->is_mapped) {
258 642 int trig;
259 643  
260 644 trig = 0;
261   - IOCTL ((oss.fd, SNDCTL_DSP_SETTRIGGER, &trig));
  645 + IOCTL ((s->fd, SNDCTL_DSP_SETTRIGGER, &trig));
262 646 trig = PCM_ENABLE_OUTPUT;
263   - IOCTL ((oss.fd, SNDCTL_DSP_SETTRIGGER, &trig));
  647 + IOCTL ((s->fd, SNDCTL_DSP_SETTRIGGER, &trig));
264 648 }
265 649 }
266 650  
267   -static void maybe_open (int req_freq, int req_nchannels,
  651 +static void maybe_open (AudioState *s, int req_freq, int req_nchannels,
268 652 audfmt_e req_fmt, int force_open)
269 653 {
270 654 int oss_fmt, bits16;
... ... @@ -273,7 +657,7 @@ static void maybe_open (int req_freq, int req_nchannels,
273 657 case AUD_FMT_U8:
274 658 bits16 = 0;
275 659 oss_fmt = AFMT_U8;
276   - oss.copy_fn = copy_no_conversion;
  660 + s->copy_fn = copy_no_conversion;
277 661 break;
278 662  
279 663 case AUD_FMT_S8:
... ... @@ -282,13 +666,13 @@ static void maybe_open (int req_freq, int req_nchannels,
282 666 case AUD_FMT_S16:
283 667 bits16 = 1;
284 668 oss_fmt = AFMT_S16_LE;
285   - oss.copy_fn = copy_no_conversion;
  669 + s->copy_fn = copy_no_conversion;
286 670 break;
287 671  
288 672 case AUD_FMT_U16:
289 673 bits16 = 1;
290 674 oss_fmt = AFMT_S16_LE;
291   - oss.copy_fn = copy_u16_to_s16;
  675 + s->copy_fn = copy_u16_to_s16;
292 676 break;
293 677  
294 678 default:
... ... @@ -296,55 +680,58 @@ static void maybe_open (int req_freq, int req_nchannels,
296 680 }
297 681  
298 682 if (force_open
299   - || (-1 == oss.fd)
300   - || (oss_fmt != oss.oss_fmt)
301   - || (req_nchannels != oss.nchannels)
302   - || (req_freq != oss.freq)
303   - || (bits16 != oss.bits16)) {
304   - oss.oss_fmt = oss_fmt;
305   - oss.nchannels = req_nchannels;
306   - oss.freq = req_freq;
307   - oss.bits16 = bits16;
308   - do_open ();
  683 + || (-1 == s->fd)
  684 + || (oss_fmt != s->oss_fmt)
  685 + || (req_nchannels != s->nchannels)
  686 + || (req_freq != s->freq)
  687 + || (bits16 != s->bits16)) {
  688 + s->oss_fmt = oss_fmt;
  689 + s->nchannels = req_nchannels;
  690 + s->freq = req_freq;
  691 + s->bits16 = bits16;
  692 + do_open (s);
309 693 }
310 694 }
311 695  
312 696 void AUD_reset (int req_freq, int req_nchannels, audfmt_e req_fmt)
313 697 {
314   - maybe_open (req_freq, req_nchannels, req_fmt, 0);
  698 + AudioState *s = &oss_audio;
  699 + maybe_open (s, req_freq, req_nchannels, req_fmt, 0);
315 700 }
316 701  
317 702 void AUD_open (int req_freq, int req_nchannels, audfmt_e req_fmt)
318 703 {
319   - maybe_open (req_freq, req_nchannels, req_fmt, 1);
  704 + AudioState *s = &oss_audio;
  705 + maybe_open (s, req_freq, req_nchannels, req_fmt, 1);
320 706 }
321 707  
322 708 int AUD_write (void *in_buf, int size)
323 709 {
  710 + AudioState *s = &oss_audio;
324 711 int to_copy, temp;
325 712 uint8_t *in, *out;
326 713  
327   - to_copy = MIN (oss.bufsize - oss.live, size);
  714 + to_copy = MIN (s->bufsize - s->live, size);
328 715  
329 716 temp = to_copy;
330 717  
331 718 in = in_buf;
332   - out = oss.buf;
  719 + out = s->buf;
333 720  
334 721 while (temp) {
335 722 int copy;
336 723  
337   - copy = MIN (temp, oss.bufsize - oss.wpos);
338   - oss.copy_fn (out + oss.wpos, in, copy);
  724 + copy = MIN (temp, s->bufsize - s->wpos);
  725 + s->copy_fn (out + s->wpos, in, copy);
339 726  
340   - oss.wpos += copy;
341   - if (oss.wpos == oss.bufsize) {
342   - oss.wpos = 0;
  727 + s->wpos += copy;
  728 + if (s->wpos == s->bufsize) {
  729 + s->wpos = 0;
343 730 }
344 731  
345 732 temp -= copy;
346 733 in += copy;
347   - oss.live += copy;
  734 + s->live += copy;
348 735 }
349 736  
350 737 return to_copy;
... ... @@ -355,15 +742,16 @@ void AUD_run (void)
355 742 int res;
356 743 int bytes;
357 744 struct audio_buf_info abinfo;
  745 + AudioState *s = &oss_audio;
358 746  
359   - if (0 == oss.live)
  747 + if (0 == s->live)
360 748 return;
361 749  
362   - if (oss.is_mapped) {
  750 + if (s->is_mapped) {
363 751 count_info info;
364 752  
365   - res = ioctl (oss.fd, SNDCTL_DSP_GETOPTR, &info);
366   - if (-1 == res) {
  753 + res = ioctl (s->fd, SNDCTL_DSP_GETOPTR, &info);
  754 + if (res < 0) {
367 755 int err;
368 756  
369 757 err = errno;
... ... @@ -371,29 +759,30 @@ void AUD_run (void)
371 759 return;
372 760 }
373 761  
374   - if (info.ptr > oss.old_optr) {
375   - bytes = info.ptr - oss.old_optr;
  762 + if (info.ptr > s->old_optr) {
  763 + bytes = info.ptr - s->old_optr;
376 764 }
377 765 else {
378   - bytes = oss.bufsize + info.ptr - oss.old_optr;
  766 + bytes = s->bufsize + info.ptr - s->old_optr;
379 767 }
380 768  
381   - oss.old_optr = info.ptr;
382   - oss.live -= bytes;
  769 + s->old_optr = info.ptr;
  770 + s->live -= bytes;
383 771 return;
384 772 }
385 773  
386   - res = ioctl (oss.fd, SNDCTL_DSP_GETOSPACE, &abinfo);
  774 + res = ioctl (s->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
387 775  
388   - if (-1 == res) {
  776 + if (res < 0) {
389 777 int err;
390 778  
391 779 err = errno;
392 780 lwarn ("SNDCTL_DSP_GETOSPACE failed with %s\n", strerror (err));
  781 + return;
393 782 }
394 783  
395 784 bytes = abinfo.bytes;
396   - bytes = MIN (oss.live, bytes);
  785 + bytes = MIN (s->live, bytes);
397 786 #if 0
398 787 bytes = (bytes / fragsize) * fragsize;
399 788 #endif
... ... @@ -401,9 +790,9 @@ void AUD_run (void)
401 790 while (bytes) {
402 791 int left, play, written;
403 792  
404   - left = oss.bufsize - oss.rpos;
  793 + left = s->bufsize - s->rpos;
405 794 play = MIN (left, bytes);
406   - written = write (oss.fd, (uint8_t *)oss.buf + oss.rpos, play);
  795 + written = write (s->fd, (uint8_t *)s->buf + s->rpos, play);
407 796  
408 797 if (-1 == written) {
409 798 if (EAGAIN == errno || EINTR == errno) {
... ... @@ -415,12 +804,12 @@ void AUD_run (void)
415 804 }
416 805  
417 806 play = written;
418   - oss.live -= play;
419   - oss.rpos += play;
  807 + s->live -= play;
  808 + s->rpos += play;
420 809 bytes -= play;
421 810  
422   - if (oss.rpos == oss.bufsize) {
423   - oss.rpos = 0;
  811 + if (s->rpos == s->bufsize) {
  812 + s->rpos = 0;
424 813 }
425 814 }
426 815 }
... ... @@ -429,8 +818,9 @@ static int get_dsp_bytes (void)
429 818 {
430 819 int res;
431 820 struct count_info info;
  821 + AudioState *s = &oss_audio;
432 822  
433   - res = ioctl (oss.fd, SNDCTL_DSP_GETOPTR, &info);
  823 + res = ioctl (s->fd, SNDCTL_DSP_GETOPTR, &info);
434 824 if (-1 == res) {
435 825 int err;
436 826  
... ... @@ -446,16 +836,18 @@ static int get_dsp_bytes (void)
446 836  
447 837 void AUD_adjust_estimate (int leftover)
448 838 {
449   - oss.leftover = leftover;
  839 + AudioState *s = &oss_audio;
  840 + s->leftover = leftover;
450 841 }
451 842  
452 843 int AUD_get_free (void)
453 844 {
454 845 int free, elapsed;
  846 + AudioState *s = &oss_audio;
455 847  
456   - free = oss.bufsize - oss.live;
  848 + free = s->bufsize - s->live;
457 849  
458   - if (0 == free)
  850 + if (free <= 0)
459 851 return 0;
460 852  
461 853 elapsed = free;
... ... @@ -485,10 +877,10 @@ int AUD_get_free (void)
485 877 uint64_t al_elapsed;
486 878  
487 879 ticks = qemu_get_clock(rt_clock);
488   - delta = ticks - oss.old_ticks;
489   - oss.old_ticks = ticks;
  880 + delta = ticks - s->old_ticks;
  881 + s->old_ticks = ticks;
490 882  
491   - ua_elapsed = (delta * oss.bytes_per_second) / 1000;
  883 + ua_elapsed = (delta * s->bytes_per_second) / 1000;
492 884 al_elapsed = ua_elapsed & ~3ULL;
493 885  
494 886 ldebug ("tid elapsed %llu bytes\n", ua_elapsed);
... ... @@ -498,7 +890,7 @@ int AUD_get_free (void)
498 890 else
499 891 elapsed = al_elapsed;
500 892  
501   - elapsed += oss.leftover;
  893 + elapsed += s->leftover;
502 894 }
503 895 }
504 896  
... ... @@ -513,31 +905,20 @@ int AUD_get_free (void)
513 905  
514 906 int AUD_get_live (void)
515 907 {
516   - return oss.live;
  908 + AudioState *s = &oss_audio;
  909 + return s->live;
517 910 }
518 911  
519 912 int AUD_get_buffer_size (void)
520 913 {
521   - return oss.bufsize;
  914 + AudioState *s = &oss_audio;
  915 + return s->bufsize;
522 916 }
523 917  
524 918 #define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE"
525 919 #define QC_OSS_NFRAGS "QEMU_OSS_NFRAGS"
526 920 #define QC_OSS_MMAP "QEMU_OSS_MMAP"
527 921  
528   -static int get_conf_val (const char *key, int defval)
529   -{
530   - int val = defval;
531   - char *strval;
532   -
533   - strval = getenv (key);
534   - if (strval) {
535   - val = atoi (strval);
536   - }
537   -
538   - return val;
539   -}
540   -
541 922 void AUD_init (void)
542 923 {
543 924 int fsp;
... ...