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,6 +26,7 @@ version 0.6.1:
26 - BIOS floppy fix for NT4 (Mike Nordell, Derek Fawcus, Volker Ruppert) 26 - BIOS floppy fix for NT4 (Mike Nordell, Derek Fawcus, Volker Ruppert)
27 - Floppy fixes for NT4 and NT5 (Mike Nordell) 27 - Floppy fixes for NT4 and NT5 (Mike Nordell)
28 - NT4 IDE fixes (Ben Pfaf, Mike Nordell) 28 - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
  29 + - SDL Audio support and SB16 fixes (malc)
29 30
30 version 0.6.0: 31 version 0.6.0:
31 32
hw/sb16.c
@@ -26,12 +26,10 @@ @@ -26,12 +26,10 @@
26 #define MIN(a, b) ((a)>(b)?(b):(a)) 26 #define MIN(a, b) ((a)>(b)?(b):(a))
27 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0]))) 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 /* #define DEBUG_SB16 */ 31 /* #define DEBUG_SB16 */
  32 +
35 #ifdef DEBUG_SB16 33 #ifdef DEBUG_SB16
36 #define lwarn(...) fprintf (stderr, "sb16: " __VA_ARGS__) 34 #define lwarn(...) fprintf (stderr, "sb16: " __VA_ARGS__)
37 #define linfo(...) fprintf (stderr, "sb16: " __VA_ARGS__) 35 #define linfo(...) fprintf (stderr, "sb16: " __VA_ARGS__)
@@ -47,7 +45,10 @@ @@ -47,7 +45,10 @@
47 #define IO_WRITE_PROTO(name) \ 45 #define IO_WRITE_PROTO(name) \
48 void name (void *opaque, uint32_t nport, uint32_t val) 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 static struct { 53 static struct {
53 int ver_lo; 54 int ver_lo;
@@ -80,10 +81,13 @@ typedef struct SB16State { @@ -80,10 +81,13 @@ typedef struct SB16State {
80 81
81 int v2x6; 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 int left_till_irq; 87 int left_till_irq;
  88 + uint64_t nzero;
  89 + uint8_t last_read_byte;
  90 + uint8_t test_reg;
87 91
88 /* mixer state */ 92 /* mixer state */
89 int mixer_nreg; 93 int mixer_nreg;
@@ -95,7 +99,7 @@ static struct SB16State dsp; @@ -95,7 +99,7 @@ static struct SB16State dsp;
95 99
96 static void log_dsp (SB16State *dsp) 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 dsp->fmt_stereo ? 'S' : 'M', 103 dsp->fmt_stereo ? 'S' : 'M',
100 dsp->fmt_signed ? 'S' : 'U', 104 dsp->fmt_signed ? 'S' : 'U',
101 dsp->fmt_bits, 105 dsp->fmt_bits,
@@ -191,6 +195,7 @@ static void dma_cmd (uint8_t cmd, uint8_t d0, int dma_len) @@ -191,6 +195,7 @@ static void dma_cmd (uint8_t cmd, uint8_t d0, int dma_len)
191 mix_block = ((dsp.freq * align) / 100) & ~(align - 1); 195 mix_block = ((dsp.freq * align) / 100) & ~(align - 1);
192 } 196 }
193 197
  198 + if (dsp.freq)
194 AUD_reset (dsp.freq, 1 << dsp.fmt_stereo, fmt); 199 AUD_reset (dsp.freq, 1 << dsp.fmt_stereo, fmt);
195 control (1); 200 control (1);
196 dsp.speaker = 1; 201 dsp.speaker = 1;
@@ -202,9 +207,17 @@ static inline void dsp_out_data(SB16State *dsp, int val) @@ -202,9 +207,17 @@ static inline void dsp_out_data(SB16State *dsp, int val)
202 dsp->out_data[dsp->out_data_len++] = val; 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 static void command (SB16State *dsp, uint8_t cmd) 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 if (cmd > 0xaf && cmd < 0xd0) { 222 if (cmd > 0xaf && cmd < 0xd0) {
210 if (cmd & 8) 223 if (cmd & 8)
@@ -215,7 +228,7 @@ static void command (SB16State *dsp, uint8_t cmd) @@ -215,7 +228,7 @@ static void command (SB16State *dsp, uint8_t cmd)
215 case 12: 228 case 12:
216 break; 229 break;
217 default: 230 default:
218 - log("%#x wrong bits", cmd); 231 + dolog ("command: %#x wrong bits specification\n", cmd);
219 goto error; 232 goto error;
220 } 233 }
221 dsp->needed_bytes = 3; 234 dsp->needed_bytes = 3;
@@ -223,23 +236,25 @@ static void command (SB16State *dsp, uint8_t cmd) @@ -223,23 +236,25 @@ static void command (SB16State *dsp, uint8_t cmd)
223 else { 236 else {
224 switch (cmd) { 237 switch (cmd) {
225 case 0x00: 238 case 0x00:
226 - case 0x03:  
227 case 0xe7: 239 case 0xe7:
228 /* IMS uses those when probing for sound devices */ 240 /* IMS uses those when probing for sound devices */
229 return; 241 return;
230 242
  243 + case 0x03:
231 case 0x04: 244 case 0x04:
232 - dsp->needed_bytes = 1;  
233 - break; 245 + dsp_out_data (dsp, 0);
  246 + return;
234 247
235 case 0x05: 248 case 0x05:
  249 + dsp->needed_bytes = 2;
  250 + break;
  251 +
236 case 0x0e: 252 case 0x0e:
237 dsp->needed_bytes = 2; 253 dsp->needed_bytes = 2;
238 break; 254 break;
239 255
240 case 0x0f: 256 case 0x0f:
241 dsp->needed_bytes = 1; 257 dsp->needed_bytes = 1;
242 - dsp_out_data (dsp, 0);  
243 break; 258 break;
244 259
245 case 0x10: 260 case 0x10:
@@ -272,6 +287,8 @@ static void command (SB16State *dsp, uint8_t cmd) @@ -272,6 +287,8 @@ static void command (SB16State *dsp, uint8_t cmd)
272 dsp->needed_bytes = 2; 287 dsp->needed_bytes = 2;
273 break; 288 break;
274 289
  290 + case 0x45:
  291 + dsp_out_data (dsp, 0xaa);
275 case 0x47: /* Continue Auto-Initialize DMA 16bit */ 292 case 0x47: /* Continue Auto-Initialize DMA 16bit */
276 break; 293 break;
277 294
@@ -346,19 +363,39 @@ static void command (SB16State *dsp, uint8_t cmd) @@ -346,19 +363,39 @@ static void command (SB16State *dsp, uint8_t cmd)
346 case 0xe3: 363 case 0xe3:
347 { 364 {
348 int i; 365 int i;
349 - for (i = sizeof (e3) - 1; i >= 0; --i) 366 + for (i = sizeof (e3) - 1; i >= 0; i--)
350 dsp_out_data (dsp, e3[i]); 367 dsp_out_data (dsp, e3[i]);
351 return; 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 case 0xf2: 379 case 0xf2:
355 - dsp_out_data(dsp, 0xaa); 380 + dsp_out_data (dsp, 0xaa);
356 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80]; 381 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
357 pic_set_irq (sb.irq, 1); 382 pic_set_irq (sb.irq, 1);
358 return; 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 default: 397 default:
361 - log("%#x is unknown", cmd); 398 + dolog ("unrecognized command %#x\n", cmd);
362 goto error; 399 goto error;
363 } 400 }
364 } 401 }
@@ -371,15 +408,14 @@ static void command (SB16State *dsp, uint8_t cmd) @@ -371,15 +408,14 @@ static void command (SB16State *dsp, uint8_t cmd)
371 408
372 static void complete (SB16State *dsp) 409 static void complete (SB16State *dsp)
373 { 410 {
  411 + int d0, d1, d2;
374 linfo ("complete command %#x, in_index %d, needed_bytes %d\n", 412 linfo ("complete command %#x, in_index %d, needed_bytes %d\n",
375 dsp->cmd, dsp->in_index, dsp->needed_bytes); 413 dsp->cmd, dsp->in_index, dsp->needed_bytes);
376 414
377 if (dsp->cmd > 0xaf && dsp->cmd < 0xd0) { 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 ldebug ("d0 = %d, d1 = %d, d2 = %d\n", 420 ldebug ("d0 = %d, d1 = %d, d2 = %d\n",
385 d0, d1, d2); 421 d0, d1, d2);
@@ -387,23 +423,29 @@ static void complete (SB16State *dsp) @@ -387,23 +423,29 @@ static void complete (SB16State *dsp)
387 } 423 }
388 else { 424 else {
389 switch (dsp->cmd) { 425 switch (dsp->cmd) {
390 - case 0x05:  
391 case 0x04: 426 case 0x04:
392 - case 0x0e: 427 + case 0x10:
  428 + dsp_get_data (dsp);
  429 + break;
  430 +
393 case 0x0f: 431 case 0x0f:
  432 + d0 = dsp_get_data (dsp);
  433 + dsp_out_data (dsp, 0xf8);
394 break; 434 break;
395 435
396 - case 0x10: 436 + case 0x05:
  437 + case 0x0e:
  438 + dsp_get_data (dsp);
  439 + dsp_get_data (dsp);
397 break; 440 break;
398 441
399 case 0x14: 442 case 0x14:
400 { 443 {
401 - int d0, d1;  
402 int save_left; 444 int save_left;
403 int save_pos; 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 save_left = dsp->left_till_irq; 450 save_left = dsp->left_till_irq;
409 save_pos = dsp->dma_pos; 451 save_pos = dsp->dma_pos;
@@ -417,35 +459,60 @@ static void complete (SB16State *dsp) @@ -417,35 +459,60 @@ static void complete (SB16State *dsp)
417 } 459 }
418 460
419 case 0x40: 461 case 0x40:
420 - dsp->time_const = dsp->in_data[0]; 462 + dsp->time_const = dsp_get_data (dsp);
421 linfo ("set time const %d\n", dsp->time_const); 463 linfo ("set time const %d\n", dsp->time_const);
422 break; 464 break;
423 465
424 case 0x41: 466 case 0x41:
425 case 0x42: 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 break; 473 break;
430 474
431 case 0x48: 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 linfo ("set dma len %#x, %#x = %d\n", 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 break; 481 break;
436 482
437 case 0xe0: 483 case 0xe0:
  484 + d0 = dsp_get_data (dsp);
438 dsp->out_data_len = 0; 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 break; 507 break;
442 508
443 default: 509 default:
444 - log ("unrecognized command %#x", dsp->cmd); 510 + dolog ("complete: unrecognized command %#x\n", dsp->cmd);
445 return; 511 return;
446 } 512 }
447 } 513 }
448 514
  515 + dsp->needed_bytes = 0;
449 dsp->cmd = -1; 516 dsp->cmd = -1;
450 return; 517 return;
451 } 518 }
@@ -457,7 +524,7 @@ static IO_WRITE_PROTO (dsp_write) @@ -457,7 +524,7 @@ static IO_WRITE_PROTO (dsp_write)
457 524
458 iport = nport - sb.port; 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 switch (iport) { 528 switch (iport) {
462 case 0x6: 529 case 0x6:
463 control (0); 530 control (0);
@@ -465,6 +532,14 @@ static IO_WRITE_PROTO (dsp_write) @@ -465,6 +532,14 @@ static IO_WRITE_PROTO (dsp_write)
465 dsp->v2x6 = 0; 532 dsp->v2x6 = 0;
466 else if ((1 == val) && (0 == dsp->v2x6)) { 533 else if ((1 == val) && (0 == dsp->v2x6)) {
467 dsp->v2x6 = 1; 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 dsp_out_data(dsp, 0xaa); 543 dsp_out_data(dsp, 0xaa);
469 } 544 }
470 else 545 else
@@ -479,18 +554,22 @@ static IO_WRITE_PROTO (dsp_write) @@ -479,18 +554,22 @@ static IO_WRITE_PROTO (dsp_write)
479 } 554 }
480 } 555 }
481 else { 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 if (dsp->in_index == dsp->needed_bytes) { 562 if (dsp->in_index == dsp->needed_bytes) {
484 dsp->needed_bytes = 0; 563 dsp->needed_bytes = 0;
485 - dsp->in_index = 0;  
486 complete (dsp); 564 complete (dsp);
487 log_dsp (dsp); 565 log_dsp (dsp);
488 } 566 }
489 } 567 }
  568 + }
490 break; 569 break;
491 570
492 default: 571 default:
493 - log ("(nport=%#x, val=%#x)", nport, val); 572 + dolog ("dsp_write (nport=%#x, val=%#x)\n", nport, val);
494 break; 573 break;
495 } 574 }
496 } 575 }
@@ -503,31 +582,36 @@ static IO_READ_PROTO (dsp_read) @@ -503,31 +582,36 @@ static IO_READ_PROTO (dsp_read)
503 iport = nport - sb.port; 582 iport = nport - sb.port;
504 583
505 switch (iport) { 584 switch (iport) {
506 -  
507 case 0x6: /* reset */ 585 case 0x6: /* reset */
508 - return 0; 586 + control (0);
  587 + retval = 0;
  588 + dsp->speaker = 0;
  589 + break;
509 590
510 case 0xa: /* read data */ 591 case 0xa: /* read data */
511 if (dsp->out_data_len) { 592 if (dsp->out_data_len) {
512 retval = dsp->out_data[--dsp->out_data_len]; 593 retval = dsp->out_data[--dsp->out_data_len];
  594 + dsp->last_read_byte = retval;
513 } else { 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 break; 600 break;
518 601
519 - case 0xc: /* 0 can write */ 602 + case 0xc: /* 0xxxxxxx can write */
520 retval = 0; 603 retval = 0;
  604 + if (dsp->out_data_len == sizeof (dsp->out_data)) retval |= 0x80;
521 break; 605 break;
522 606
523 case 0xd: /* timer interrupt clear */ 607 case 0xd: /* timer interrupt clear */
524 - log("timer interrupt clear"); 608 + dolog ("timer interrupt clear\n");
525 goto error; 609 goto error;
526 610
527 case 0xe: /* data available status | irq 8 ack */ 611 case 0xe: /* data available status | irq 8 ack */
528 /* XXX drop pic irq line here? */ 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 dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80]; 615 dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80];
532 pic_set_irq (sb.irq, 0); 616 pic_set_irq (sb.irq, 0);
533 break; 617 break;
@@ -544,15 +628,30 @@ static IO_READ_PROTO (dsp_read) @@ -544,15 +628,30 @@ static IO_READ_PROTO (dsp_read)
544 goto error; 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 nport, iport, retval); 647 nport, iport, retval);
550 } 648 }
551 649
552 return retval; 650 return retval;
553 651
554 error: 652 error:
555 - return 0; 653 + printf ("dsp_read error %#x\n", nport);
  654 + return 0xff;
556 } 655 }
557 656
558 static IO_WRITE_PROTO(mixer_write_indexb) 657 static IO_WRITE_PROTO(mixer_write_indexb)
@@ -564,12 +663,100 @@ static IO_WRITE_PROTO(mixer_write_indexb) @@ -564,12 +663,100 @@ static IO_WRITE_PROTO(mixer_write_indexb)
564 static IO_WRITE_PROTO(mixer_write_datab) 663 static IO_WRITE_PROTO(mixer_write_datab)
565 { 664 {
566 SB16State *dsp = opaque; 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 return; 733 return;
  734 + }
570 dsp->mixer_regs[dsp->mixer_nreg] = val; 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 static IO_WRITE_PROTO(mixer_write_indexw) 760 static IO_WRITE_PROTO(mixer_write_indexw)
574 { 761 {
575 mixer_write_indexb (opaque, nport, val & 0xff); 762 mixer_write_indexb (opaque, nport, val & 0xff);
@@ -579,6 +766,7 @@ static IO_WRITE_PROTO(mixer_write_indexw) @@ -579,6 +766,7 @@ static IO_WRITE_PROTO(mixer_write_indexw)
579 static IO_READ_PROTO(mixer_read) 766 static IO_READ_PROTO(mixer_read)
580 { 767 {
581 SB16State *dsp = opaque; 768 SB16State *dsp = opaque;
  769 + linfo ("mixer [%#x] -> %#x\n", dsp->mixer_nreg, dsp->mixer_regs[dsp->mixer_nreg]);
582 return dsp->mixer_regs[dsp->mixer_nreg]; 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,6 +825,8 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
637 return 0; 825 return 0;
638 826
639 if (dsp->left_till_irq < 0) { 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 dsp->left_till_irq += dsp->dma_buffer_size; 830 dsp->left_till_irq += dsp->dma_buffer_size;
641 return dsp->dma_pos; 831 return dsp->dma_pos;
642 } 832 }
@@ -644,6 +834,7 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size) @@ -644,6 +834,7 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
644 free = AUD_get_free (); 834 free = AUD_get_free ();
645 835
646 if ((free <= 0) || (0 == size)) { 836 if ((free <= 0) || (0 == size)) {
  837 + ldebug ("returning, since free = %d and size = %d\n", free, size);
647 return dsp->dma_pos; 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,8 +847,11 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
656 847
657 till = dsp->left_till_irq; 848 till = dsp->left_till_irq;
658 849
  850 +#ifdef DEBUG_SB16_MOST
659 ldebug ("addr:%#010x free:%d till:%d size:%d\n", 851 ldebug ("addr:%#010x free:%d till:%d size:%d\n",
660 addr, free, till, size); 852 addr, free, till, size);
  853 +#endif
  854 +
661 if (till <= copy) { 855 if (till <= copy) {
662 if (0 == dsp->dma_auto) { 856 if (0 == dsp->dma_auto) {
663 copy = till; 857 copy = till;
@@ -671,7 +865,8 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size) @@ -671,7 +865,8 @@ static int SB_read_DMA (void *opaque, target_ulong addr, int size)
671 if (dsp->left_till_irq <= 0) { 865 if (dsp->left_till_irq <= 0) {
672 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80]; 866 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
673 if (0 == noirq) { 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 pic_set_irq(sb.irq, 1); 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,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 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n", 879 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
684 dsp->dma_pos, free, size, dsp->left_till_irq, copy, 880 dsp->dma_pos, free, size, dsp->left_till_irq, copy,
685 dsp->dma_buffer_size); 881 dsp->dma_buffer_size);
  882 +#endif
686 883
687 if (dsp->left_till_irq <= 0) { 884 if (dsp->left_till_irq <= 0) {
688 dsp->left_till_irq += dsp->dma_buffer_size; 885 dsp->left_till_irq += dsp->dma_buffer_size;
@@ -703,7 +900,7 @@ static int magic_of_irq (int irq) @@ -703,7 +900,7 @@ static int magic_of_irq (int irq)
703 case 10: 900 case 10:
704 return 8; 901 return 8;
705 default: 902 default:
706 - log ("bad irq %d", irq); 903 + dolog ("bad irq %d\n", irq);
707 return 2; 904 return 2;
708 } 905 }
709 } 906 }
@@ -721,12 +918,42 @@ static int irq_of_magic (int magic) @@ -721,12 +918,42 @@ static int irq_of_magic (int magic)
721 case 8: 918 case 8:
722 return 10; 919 return 10;
723 default: 920 default:
724 - log ("bad irq magic %d", magic); 921 + dolog ("bad irq magic %d\n", magic);
725 return 2; 922 return 2;
726 } 923 }
727 } 924 }
728 #endif 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 void SB16_init (void) 957 void SB16_init (void)
731 { 958 {
732 SB16State *s = &dsp; 959 SB16State *s = &dsp;
@@ -736,13 +963,23 @@ void SB16_init (void) @@ -736,13 +963,23 @@ void SB16_init (void)
736 963
737 memset(s->mixer_regs, 0xff, sizeof(s->mixer_regs)); 964 memset(s->mixer_regs, 0xff, sizeof(s->mixer_regs));
738 965
  966 + s->mixer_regs[0x00] = 0;
739 s->mixer_regs[0x0e] = ~0; 967 s->mixer_regs[0x0e] = ~0;
740 s->mixer_regs[0x80] = magic_of_irq (sb.irq); 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 for (i = 0; i < LENOFA (dsp_write_ports); i++) { 984 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
748 register_ioport_write (sb.port + dsp_write_ports[i], 1, 1, dsp_write, s); 985 register_ioport_write (sb.port + dsp_write_ports[i], 1, 1, dsp_write, s);
@@ -751,12 +988,20 @@ void SB16_init (void) @@ -751,12 +988,20 @@ void SB16_init (void)
751 for (i = 0; i < LENOFA (dsp_read_ports); i++) { 988 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
752 register_ioport_read (sb.port + dsp_read_ports[i], 1, 1, dsp_read, s); 989 register_ioport_read (sb.port + dsp_read_ports[i], 1, 1, dsp_read, s);
753 } 990 }
  991 +#endif
754 992
755 register_ioport_write (sb.port + 0x4, 1, 1, mixer_write_indexb, s); 993 register_ioport_write (sb.port + 0x4, 1, 1, mixer_write_indexb, s);
756 register_ioport_write (sb.port + 0x4, 1, 2, mixer_write_indexw, s); 994 register_ioport_write (sb.port + 0x4, 1, 2, mixer_write_indexw, s);
757 register_ioport_read (sb.port + 0x5, 1, 1, mixer_read, s); 995 register_ioport_read (sb.port + 0x5, 1, 1, mixer_read, s);
758 register_ioport_write (sb.port + 0x5, 1, 1, mixer_write_datab, s); 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 DMA_register_channel (sb.hdma, SB_read_DMA, s); 1005 DMA_register_channel (sb.hdma, SB_read_DMA, s);
761 DMA_register_channel (sb.dma, SB_read_DMA, s); 1006 DMA_register_channel (sb.dma, SB_read_DMA, s);
762 } 1007 }
@@ -23,22 +23,446 @@ @@ -23,22 +23,446 @@
23 */ 23 */
24 #include "vl.h" 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 #include <fcntl.h> 458 #include <fcntl.h>
29 #include <errno.h> 459 #include <errno.h>
30 -#include <stdio.h>  
31 #include <unistd.h> 460 #include <unistd.h>
32 -#include <string.h>  
33 -#include <stdlib.h>  
34 -#include <limits.h>  
35 -#include <inttypes.h>  
36 #include <sys/mman.h> 461 #include <sys/mman.h>
37 #include <sys/types.h> 462 #include <sys/types.h>
38 #include <sys/ioctl.h> 463 #include <sys/ioctl.h>
39 #include <sys/soundcard.h> 464 #include <sys/soundcard.h>
40 465
41 -  
42 /* http://www.df.lth.se/~john_e/gems/gem002d.html */ 466 /* http://www.df.lth.se/~john_e/gems/gem002d.html */
43 /* http://www.multi-platforms.com/Tips/PopCount.htm */ 467 /* http://www.multi-platforms.com/Tips/PopCount.htm */
44 static inline uint32_t popcount (uint32_t u) 468 static inline uint32_t popcount (uint32_t u)
@@ -56,34 +480,6 @@ static inline uint32_t lsbindex (uint32_t u) @@ -56,34 +480,6 @@ static inline uint32_t lsbindex (uint32_t u)
56 return popcount ((u&-u)-1); 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 #define IOCTL(args) do { \ 483 #define IOCTL(args) do { \
88 int ret = ioctl args; \ 484 int ret = ioctl args; \
89 if (-1 == ret) { \ 485 if (-1 == ret) { \
@@ -92,7 +488,7 @@ static inline uint32_t lsbindex (uint32_t u) @@ -92,7 +488,7 @@ static inline uint32_t lsbindex (uint32_t u)
92 ldebug ("ioctl " #args " = %d\n", ret); \ 488 ldebug ("ioctl " #args " = %d\n", ret); \
93 } while (0) 489 } while (0)
94 490
95 -static struct { 491 +typedef struct AudioState {
96 int fd; 492 int fd;
97 int freq; 493 int freq;
98 int bits16; 494 int bits16;
@@ -111,7 +507,9 @@ static struct { @@ -111,7 +507,9 @@ static struct {
111 int leftover; 507 int leftover;
112 uint64_t old_ticks; 508 uint64_t old_ticks;
113 void (*copy_fn)(void *, void *, int); 509 void (*copy_fn)(void *, void *, int);
114 -} oss = { .fd = -1 }; 510 +} AudioState;
  511 +
  512 +static AudioState oss_audio = { .fd = -1 };
115 513
116 static struct { 514 static struct {
117 int try_mmap; 515 int try_mmap;
@@ -125,25 +523,7 @@ static struct { @@ -125,25 +523,7 @@ static struct {
125 523
126 static enum {DONT, DSP, TID} est = DONT; 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 DEREF (abinfo); 528 DEREF (abinfo);
149 529
@@ -153,118 +533,122 @@ static void pab (struct audio_buf_info *abinfo) @@ -153,118 +533,122 @@ static void pab (struct audio_buf_info *abinfo)
153 abinfo->fragstotal, 533 abinfo->fragstotal,
154 abinfo->fragsize, 534 abinfo->fragsize,
155 abinfo->bytes, 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 int mmmmssss; 541 int mmmmssss;
162 audio_buf_info abinfo; 542 audio_buf_info abinfo;
163 int fmt, freq, nchannels; 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 ERRFail ("failed to unmap audio buffer %p %d", 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 ERRFail ("can not open /dev/dsp"); 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 mmmmssss = (conf.nfrags << 16) | conf.fragsize; 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 Fail ("failed to set audio parameters\n" 582 Fail ("failed to set audio parameters\n"
198 "parameter | requested value | obtained value\n" 583 "parameter | requested value | obtained value\n"
199 "format | %10d | %10d\n" 584 "format | %10d | %10d\n"
200 "channels | %10d | %10d\n" 585 "channels | %10d | %10d\n"
201 "frequency | %10d | %10d\n", 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 linfo ("fragments %d, fragstotal %d, fragsize %d, bytes %d, bufsize %d\n", 603 linfo ("fragments %d, fragstotal %d, fragsize %d, bytes %d, bufsize %d\n",
219 abinfo.fragments, 604 abinfo.fragments,
220 abinfo.fragstotal, 605 abinfo.fragstotal,
221 abinfo.fragsize, 606 abinfo.fragsize,
222 abinfo.bytes, 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 if (conf.try_mmap) { 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 int err; 616 int err;
232 617
233 err = errno; 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 "syserr: %s\n", 620 "syserr: %s\n",
236 - oss.bufsize, oss.fd, strerror (err)); 621 + s->bufsize, s->fd, strerror (err));
237 } 622 }
238 else { 623 else {
239 est = TID; 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 est = TID; 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 int trig; 642 int trig;
259 643
260 trig = 0; 644 trig = 0;
261 - IOCTL ((oss.fd, SNDCTL_DSP_SETTRIGGER, &trig)); 645 + IOCTL ((s->fd, SNDCTL_DSP_SETTRIGGER, &trig));
262 trig = PCM_ENABLE_OUTPUT; 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 audfmt_e req_fmt, int force_open) 652 audfmt_e req_fmt, int force_open)
269 { 653 {
270 int oss_fmt, bits16; 654 int oss_fmt, bits16;
@@ -273,7 +657,7 @@ static void maybe_open (int req_freq, int req_nchannels, @@ -273,7 +657,7 @@ static void maybe_open (int req_freq, int req_nchannels,
273 case AUD_FMT_U8: 657 case AUD_FMT_U8:
274 bits16 = 0; 658 bits16 = 0;
275 oss_fmt = AFMT_U8; 659 oss_fmt = AFMT_U8;
276 - oss.copy_fn = copy_no_conversion; 660 + s->copy_fn = copy_no_conversion;
277 break; 661 break;
278 662
279 case AUD_FMT_S8: 663 case AUD_FMT_S8:
@@ -282,13 +666,13 @@ static void maybe_open (int req_freq, int req_nchannels, @@ -282,13 +666,13 @@ static void maybe_open (int req_freq, int req_nchannels,
282 case AUD_FMT_S16: 666 case AUD_FMT_S16:
283 bits16 = 1; 667 bits16 = 1;
284 oss_fmt = AFMT_S16_LE; 668 oss_fmt = AFMT_S16_LE;
285 - oss.copy_fn = copy_no_conversion; 669 + s->copy_fn = copy_no_conversion;
286 break; 670 break;
287 671
288 case AUD_FMT_U16: 672 case AUD_FMT_U16:
289 bits16 = 1; 673 bits16 = 1;
290 oss_fmt = AFMT_S16_LE; 674 oss_fmt = AFMT_S16_LE;
291 - oss.copy_fn = copy_u16_to_s16; 675 + s->copy_fn = copy_u16_to_s16;
292 break; 676 break;
293 677
294 default: 678 default:
@@ -296,55 +680,58 @@ static void maybe_open (int req_freq, int req_nchannels, @@ -296,55 +680,58 @@ static void maybe_open (int req_freq, int req_nchannels,
296 } 680 }
297 681
298 if (force_open 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 void AUD_reset (int req_freq, int req_nchannels, audfmt_e req_fmt) 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 void AUD_open (int req_freq, int req_nchannels, audfmt_e req_fmt) 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 int AUD_write (void *in_buf, int size) 708 int AUD_write (void *in_buf, int size)
323 { 709 {
  710 + AudioState *s = &oss_audio;
324 int to_copy, temp; 711 int to_copy, temp;
325 uint8_t *in, *out; 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 temp = to_copy; 716 temp = to_copy;
330 717
331 in = in_buf; 718 in = in_buf;
332 - out = oss.buf; 719 + out = s->buf;
333 720
334 while (temp) { 721 while (temp) {
335 int copy; 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 temp -= copy; 732 temp -= copy;
346 in += copy; 733 in += copy;
347 - oss.live += copy; 734 + s->live += copy;
348 } 735 }
349 736
350 return to_copy; 737 return to_copy;
@@ -355,15 +742,16 @@ void AUD_run (void) @@ -355,15 +742,16 @@ void AUD_run (void)
355 int res; 742 int res;
356 int bytes; 743 int bytes;
357 struct audio_buf_info abinfo; 744 struct audio_buf_info abinfo;
  745 + AudioState *s = &oss_audio;
358 746
359 - if (0 == oss.live) 747 + if (0 == s->live)
360 return; 748 return;
361 749
362 - if (oss.is_mapped) { 750 + if (s->is_mapped) {
363 count_info info; 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 int err; 755 int err;
368 756
369 err = errno; 757 err = errno;
@@ -371,29 +759,30 @@ void AUD_run (void) @@ -371,29 +759,30 @@ void AUD_run (void)
371 return; 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 else { 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 return; 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 int err; 777 int err;
390 778
391 err = errno; 779 err = errno;
392 lwarn ("SNDCTL_DSP_GETOSPACE failed with %s\n", strerror (err)); 780 lwarn ("SNDCTL_DSP_GETOSPACE failed with %s\n", strerror (err));
  781 + return;
393 } 782 }
394 783
395 bytes = abinfo.bytes; 784 bytes = abinfo.bytes;
396 - bytes = MIN (oss.live, bytes); 785 + bytes = MIN (s->live, bytes);
397 #if 0 786 #if 0
398 bytes = (bytes / fragsize) * fragsize; 787 bytes = (bytes / fragsize) * fragsize;
399 #endif 788 #endif
@@ -401,9 +790,9 @@ void AUD_run (void) @@ -401,9 +790,9 @@ void AUD_run (void)
401 while (bytes) { 790 while (bytes) {
402 int left, play, written; 791 int left, play, written;
403 792
404 - left = oss.bufsize - oss.rpos; 793 + left = s->bufsize - s->rpos;
405 play = MIN (left, bytes); 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 if (-1 == written) { 797 if (-1 == written) {
409 if (EAGAIN == errno || EINTR == errno) { 798 if (EAGAIN == errno || EINTR == errno) {
@@ -415,12 +804,12 @@ void AUD_run (void) @@ -415,12 +804,12 @@ void AUD_run (void)
415 } 804 }
416 805
417 play = written; 806 play = written;
418 - oss.live -= play;  
419 - oss.rpos += play; 807 + s->live -= play;
  808 + s->rpos += play;
420 bytes -= play; 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,8 +818,9 @@ static int get_dsp_bytes (void)
429 { 818 {
430 int res; 819 int res;
431 struct count_info info; 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 if (-1 == res) { 824 if (-1 == res) {
435 int err; 825 int err;
436 826
@@ -446,16 +836,18 @@ static int get_dsp_bytes (void) @@ -446,16 +836,18 @@ static int get_dsp_bytes (void)
446 836
447 void AUD_adjust_estimate (int leftover) 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 int AUD_get_free (void) 843 int AUD_get_free (void)
453 { 844 {
454 int free, elapsed; 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 return 0; 851 return 0;
460 852
461 elapsed = free; 853 elapsed = free;
@@ -485,10 +877,10 @@ int AUD_get_free (void) @@ -485,10 +877,10 @@ int AUD_get_free (void)
485 uint64_t al_elapsed; 877 uint64_t al_elapsed;
486 878
487 ticks = qemu_get_clock(rt_clock); 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 al_elapsed = ua_elapsed & ~3ULL; 884 al_elapsed = ua_elapsed & ~3ULL;
493 885
494 ldebug ("tid elapsed %llu bytes\n", ua_elapsed); 886 ldebug ("tid elapsed %llu bytes\n", ua_elapsed);
@@ -498,7 +890,7 @@ int AUD_get_free (void) @@ -498,7 +890,7 @@ int AUD_get_free (void)
498 else 890 else
499 elapsed = al_elapsed; 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,31 +905,20 @@ int AUD_get_free (void)
513 905
514 int AUD_get_live (void) 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 int AUD_get_buffer_size (void) 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 #define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE" 918 #define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE"
525 #define QC_OSS_NFRAGS "QEMU_OSS_NFRAGS" 919 #define QC_OSS_NFRAGS "QEMU_OSS_NFRAGS"
526 #define QC_OSS_MMAP "QEMU_OSS_MMAP" 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 void AUD_init (void) 922 void AUD_init (void)
542 { 923 {
543 int fsp; 924 int fsp;