- Timestamp:
- Mar 31, 2015 10:25:47 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Audio/DevSB16.cpp
r55010 r55021 73 73 /** Current saved state version. */ 74 74 #define SB16_SAVE_STATE_VERSION 2 75 /** The version used in VirtualBox version 3.0 and earlier. This didn't include 76 * the config dump. */ 75 /** The version used in VirtualBox version 3.0 and earlier. This didn't include the config dump. */ 77 76 #define SB16_SAVE_STATE_VERSION_VBOX_30 1 78 77 #endif /* VBOX */ … … 96 95 97 96 #ifndef VBOX 98 static struct { 97 static struct 98 { 99 99 int ver_lo; 100 100 int ver_hi; … … 124 124 { 125 125 /** Node for storing this driver in our device driver 126 * list of AC97STATE. */126 * list of SB16STATE. */ 127 127 RTLISTNODE Node; 128 128 struct … … 208 208 int nzero; 209 209 210 int left_till_irq; 210 int left_till_irq; /** Note: Can be < 0. */ 211 211 212 212 int dma_running; 213 213 int bytes_per_second; 214 214 int align; 215 uint32_t audio_free;216 215 217 216 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER … … 226 225 uint64_t uTicksIO; 227 226 #else 227 uint32_t audio_free; 228 228 SWVoiceOut *voice; 229 229 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ … … 392 392 393 393 #ifndef VBOX 394 if (hold) { 395 DMA_hold_DREQ (dma); 396 AUD_set_active_out (pThis->voice, 1); 397 } 398 else { 399 DMA_release_DREQ (dma); 400 AUD_set_active_out (pThis->voice, 0); 394 if (hold) 395 { 396 DMA_hold_DREQ(dma); 397 AUD_set_active_out(pThis->voice, 1); 398 } 399 else 400 { 401 DMA_release_DREQ(dma); 402 AUD_set_active_out(pThis->voice, 0); 401 403 } 402 404 #else /* VBOX */ … … 453 455 if (pThis->freq > 0) 454 456 { 455 pThis->audio_free = 0;456 457 457 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 458 458 PDMAUDIOSTREAMCFG streamCfg; … … 465 465 AssertRC(rc); 466 466 #else 467 pThis->audio_free = 0; 468 467 469 audsettings_t streamCfg; 468 470 streamCfg.freq = pThis->freq; … … 528 530 pThis->align = (1 << pThis->fmt_stereo) - 1; 529 531 530 if (pThis->block_size & pThis->align) {532 if (pThis->block_size & pThis->align) 531 533 LogFlowFunc(("warning: misaligned block size %d, alignment %d\n", 532 pThis->block_size, pThis->align + 1)); 533 } 534 535 LogFlowFunc(("freq %d, stereo %d, sign %d, bits %d, " 536 "dma %d, auto %d, fifo %d, high %d\n", 537 pThis->freq, pThis->fmt_stereo, pThis->fmt_signed, pThis->fmt_bits, 538 pThis->block_size, pThis->dma_auto, pThis->fifo, pThis->highspeed)); 539 540 continue_dma8 (pThis); 534 pThis->block_size, pThis->align + 1)); 535 536 LogFlowFunc(("freq %d, stereo %d, sign %d, bits %d, dma %d, auto %d, fifo %d, high %d\n", 537 pThis->freq, pThis->fmt_stereo, pThis->fmt_signed, pThis->fmt_bits, 538 pThis->block_size, pThis->dma_auto, pThis->fifo, pThis->highspeed)); 539 540 continue_dma8(pThis); 541 541 sb16SpeakerControl(pThis, 1); 542 542 } 543 543 544 static void dma_cmd 544 static void dma_cmd(PSB16STATE pThis, uint8_t cmd, uint8_t d0, int dma_len) 545 545 { 546 546 pThis->use_hdma = cmd < 0xc0; … … 577 577 if (!pThis->dma_auto) 578 578 { 579 /* It is clear that for DOOM and auto-init this value 580 shouldn't take stereo into account, while Miles Sound Systems 581 setsound.exe with single transfer mode wouldn't work without it 582 wonders of SB16 yet again */ 579 /* 580 * It is clear that for DOOM and auto-init this value 581 * shouldn't take stereo into account, while Miles Sound Systems 582 * setsound.exe with single transfer mode wouldn't work without it 583 * wonders of SB16 yet again. 584 */ 583 585 pThis->block_size <<= pThis->fmt_stereo; 584 586 } … … 606 608 if (pThis->freq) 607 609 { 608 pThis->audio_free = 0;609 610 610 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 611 611 PDMAUDIOSTREAMCFG streamCfg; … … 618 618 AssertRC(rc); 619 619 #else 620 pThis->audio_free = 0; 621 620 622 audsettings_t streamCfg; 621 623 streamCfg.freq = pThis->freq; … … 657 659 } 658 660 659 static void command(PSB16STATE pThis, uint8_t cmd)661 static void sb16HandleCommand(PSB16STATE pThis, uint8_t cmd) 660 662 { 661 663 LogFlowFunc(("command %#x\n", cmd)); 662 664 663 if (cmd > 0xaf && cmd < 0xd0) { 664 if (cmd & 8) { 665 if (cmd > 0xaf && cmd < 0xd0) 666 { 667 if (cmd & 8) /** @todo Handle recording. */ 665 668 LogFlowFunc(("ADC not yet supported (command %#x)\n", cmd)); 669 670 switch (cmd >> 4) 671 { 672 case 11: 673 case 12: 674 break; 675 default: 676 LogFlowFunc(("%#x wrong bits\n", cmd)); 666 677 } 667 678 668 switch (cmd >> 4) { 669 case 11: 670 case 12: 671 break; 672 default: 673 LogFlowFunc(("%#x wrong bits\n", cmd)); 679 pThis->needed_bytes = 3; 680 } 681 else 682 { 683 pThis->needed_bytes = 0; 684 685 switch (cmd) 686 { 687 case 0x03: 688 dsp_out_data(pThis, 0x10); /* pThis->csp_param); */ 689 goto warn; 690 691 case 0x04: 692 pThis->needed_bytes = 1; 693 goto warn; 694 695 case 0x05: 696 pThis->needed_bytes = 2; 697 goto warn; 698 699 case 0x08: 700 /* __asm__ ("int3"); */ 701 goto warn; 702 703 case 0x0e: 704 pThis->needed_bytes = 2; 705 goto warn; 706 707 case 0x09: 708 dsp_out_data(pThis, 0xf8); 709 goto warn; 710 711 case 0x0f: 712 pThis->needed_bytes = 1; 713 goto warn; 714 715 case 0x10: 716 pThis->needed_bytes = 1; 717 goto warn; 718 719 case 0x14: 720 pThis->needed_bytes = 2; 721 pThis->block_size = 0; 722 break; 723 724 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */ 725 dma_cmd8(pThis, DMA8_AUTO, -1); 726 break; 727 728 case 0x20: /* Direct ADC, Juice/PL */ 729 dsp_out_data(pThis, 0xff); 730 goto warn; 731 732 case 0x35: 733 LogFlowFunc(("0x35 - MIDI command not implemented\n")); 734 break; 735 736 case 0x40: 737 pThis->freq = -1; 738 pThis->time_const = -1; 739 pThis->needed_bytes = 1; 740 break; 741 742 case 0x41: 743 pThis->freq = -1; 744 pThis->time_const = -1; 745 pThis->needed_bytes = 2; 746 break; 747 748 case 0x42: 749 pThis->freq = -1; 750 pThis->time_const = -1; 751 pThis->needed_bytes = 2; 752 goto warn; 753 754 case 0x45: 755 dsp_out_data(pThis, 0xaa); 756 goto warn; 757 758 case 0x47: /* Continue Auto-Initialize DMA 16bit */ 759 break; 760 761 case 0x48: 762 pThis->needed_bytes = 2; 763 break; 764 765 case 0x74: 766 pThis->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */ 767 LogFlowFunc(("0x75 - DMA DAC, 4-bit ADPCM not implemented\n")); 768 break; 769 770 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */ 771 pThis->needed_bytes = 2; 772 LogFlowFunc(("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n")); 773 break; 774 775 case 0x76: /* DMA DAC, 2.6-bit ADPCM */ 776 pThis->needed_bytes = 2; 777 LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n")); 778 break; 779 780 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */ 781 pThis->needed_bytes = 2; 782 LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n")); 783 break; 784 785 case 0x7d: 786 LogFlowFunc(("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n")); 787 LogFlowFunc(("not implemented\n")); 788 break; 789 790 case 0x7f: 791 LogFlowFunc(("0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n")); 792 LogFlowFunc(("not implemented\n")); 793 break; 794 795 case 0x80: 796 pThis->needed_bytes = 2; 797 break; 798 799 case 0x90: 800 case 0x91: 801 dma_cmd8(pThis, (((cmd & 1) == 0) ? 1 : 0) | DMA8_HIGH, -1); 802 break; 803 804 case 0xd0: /* halt DMA operation. 8bit */ 805 sb16Control(pThis, 0); 806 break; 807 808 case 0xd1: /* speaker on */ 809 sb16SpeakerControl(pThis, 1); 810 break; 811 812 case 0xd3: /* speaker off */ 813 sb16SpeakerControl(pThis, 0); 814 break; 815 816 case 0xd4: /* continue DMA operation. 8bit */ 817 /* KQ6 (or maybe Sierras audblst.drv in general) resets 818 the frequency between halt/continue */ 819 continue_dma8(pThis); 820 break; 821 822 case 0xd5: /* halt DMA operation. 16bit */ 823 sb16Control(pThis, 0); 824 break; 825 826 case 0xd6: /* continue DMA operation. 16bit */ 827 sb16Control(pThis, 1); 828 break; 829 830 case 0xd9: /* exit auto-init DMA after this block. 16bit */ 831 pThis->dma_auto = 0; 832 break; 833 834 case 0xda: /* exit auto-init DMA after this block. 8bit */ 835 pThis->dma_auto = 0; 836 break; 837 838 case 0xe0: /* DSP identification */ 839 pThis->needed_bytes = 1; 840 break; 841 842 case 0xe1: 843 dsp_out_data(pThis, pThis->ver & 0xff); 844 dsp_out_data(pThis, pThis->ver >> 8); 845 break; 846 847 case 0xe2: 848 pThis->needed_bytes = 1; 849 goto warn; 850 851 case 0xe3: 852 { 853 for (size_t i = sizeof (e3) - 1; i >= 0; --i) 854 dsp_out_data(pThis, e3[i]); 855 856 break; 857 } 858 859 case 0xe4: /* write test reg */ 860 pThis->needed_bytes = 1; 861 break; 862 863 case 0xe7: 864 LogFlowFunc(("Attempt to probe for ESS (0xe7)?\n")); 865 break; 866 867 case 0xe8: /* read test reg */ 868 dsp_out_data(pThis, pThis->test_reg); 869 break; 870 871 case 0xf2: 872 case 0xf3: 873 dsp_out_data(pThis, 0xaa); 874 pThis->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2; 875 #ifndef VBOX 876 qemu_irq_raise (pThis->pic[pThis->irq]); 877 #else 878 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1); 879 #endif 880 break; 881 882 case 0xf9: 883 pThis->needed_bytes = 1; 884 goto warn; 885 886 case 0xfa: 887 dsp_out_data (pThis, 0); 888 goto warn; 889 890 case 0xfc: /* FIXME */ 891 dsp_out_data (pThis, 0); 892 goto warn; 893 894 default: 895 LogFlowFunc(("Unrecognized command %#x\n", cmd)); 896 break; 674 897 } 675 pThis->needed_bytes = 3; 676 } 677 else { 678 pThis->needed_bytes = 0; 679 680 switch (cmd) { 681 case 0x03: 682 dsp_out_data (pThis, 0x10); /* pThis->csp_param); */ 683 goto warn; 684 685 case 0x04: 686 pThis->needed_bytes = 1; 687 goto warn; 688 689 case 0x05: 690 pThis->needed_bytes = 2; 691 goto warn; 692 693 case 0x08: 694 /* __asm__ ("int3"); */ 695 goto warn; 696 697 case 0x0e: 698 pThis->needed_bytes = 2; 699 goto warn; 700 701 case 0x09: 702 dsp_out_data (pThis, 0xf8); 703 goto warn; 704 705 case 0x0f: 706 pThis->needed_bytes = 1; 707 goto warn; 708 709 case 0x10: 710 pThis->needed_bytes = 1; 711 goto warn; 712 713 case 0x14: 714 pThis->needed_bytes = 2; 715 pThis->block_size = 0; 716 break; 717 718 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */ 719 dma_cmd8 (pThis, DMA8_AUTO, -1); 720 break; 721 722 case 0x20: /* Direct ADC, Juice/PL */ 723 dsp_out_data (pThis, 0xff); 724 goto warn; 725 726 case 0x35: 727 LogFlowFunc(("0x35 - MIDI command not implemented\n")); 728 break; 729 730 case 0x40: 731 pThis->freq = -1; 732 pThis->time_const = -1; 733 pThis->needed_bytes = 1; 734 break; 735 736 case 0x41: 737 pThis->freq = -1; 738 pThis->time_const = -1; 739 pThis->needed_bytes = 2; 740 break; 741 742 case 0x42: 743 pThis->freq = -1; 744 pThis->time_const = -1; 745 pThis->needed_bytes = 2; 746 goto warn; 747 748 case 0x45: 749 dsp_out_data (pThis, 0xaa); 750 goto warn; 751 752 case 0x47: /* Continue Auto-Initialize DMA 16bit */ 753 break; 754 755 case 0x48: 756 pThis->needed_bytes = 2; 757 break; 758 759 case 0x74: 760 pThis->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */ 761 LogFlowFunc(("0x75 - DMA DAC, 4-bit ADPCM not implemented\n")); 762 break; 763 764 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */ 765 pThis->needed_bytes = 2; 766 LogFlowFunc(("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n")); 767 break; 768 769 case 0x76: /* DMA DAC, 2.6-bit ADPCM */ 770 pThis->needed_bytes = 2; 771 LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n")); 772 break; 773 774 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */ 775 pThis->needed_bytes = 2; 776 LogFlowFunc(("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n")); 777 break; 778 779 case 0x7d: 780 LogFlowFunc(("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n")); 781 LogFlowFunc(("not implemented\n")); 782 break; 783 784 case 0x7f: 785 LogFlowFunc(("0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n")); 786 LogFlowFunc(("not implemented\n")); 787 break; 788 789 case 0x80: 790 pThis->needed_bytes = 2; 791 break; 792 793 case 0x90: 794 case 0x91: 795 dma_cmd8(pThis, (((cmd & 1) == 0) ? 1 : 0) | DMA8_HIGH, -1); 796 break; 797 798 case 0xd0: /* halt DMA operation. 8bit */ 799 sb16Control(pThis, 0); 800 break; 801 802 case 0xd1: /* speaker on */ 803 sb16SpeakerControl(pThis, 1); 804 break; 805 806 case 0xd3: /* speaker off */ 807 sb16SpeakerControl(pThis, 0); 808 break; 809 810 case 0xd4: /* continue DMA operation. 8bit */ 811 /* KQ6 (or maybe Sierras audblst.drv in general) resets 812 the frequency between halt/continue */ 813 continue_dma8 (pThis); 814 break; 815 816 case 0xd5: /* halt DMA operation. 16bit */ 817 sb16Control(pThis, 0); 818 break; 819 820 case 0xd6: /* continue DMA operation. 16bit */ 821 sb16Control(pThis, 1); 822 break; 823 824 case 0xd9: /* exit auto-init DMA after this block. 16bit */ 825 pThis->dma_auto = 0; 826 break; 827 828 case 0xda: /* exit auto-init DMA after this block. 8bit */ 829 pThis->dma_auto = 0; 830 break; 831 832 case 0xe0: /* DSP identification */ 833 pThis->needed_bytes = 1; 834 break; 835 836 case 0xe1: 837 dsp_out_data (pThis, pThis->ver & 0xff); 838 dsp_out_data (pThis, pThis->ver >> 8); 839 break; 840 841 case 0xe2: 842 pThis->needed_bytes = 1; 843 goto warn; 844 845 case 0xe3: 846 { 847 int i; 848 for (i = sizeof (e3) - 1; i >= 0; --i) 849 dsp_out_data (pThis, e3[i]); 850 } 851 break; 852 853 case 0xe4: /* write test reg */ 854 pThis->needed_bytes = 1; 855 break; 856 857 case 0xe7: 858 LogFlowFunc(("Attempt to probe for ESS (0xe7)?\n")); 859 break; 860 861 case 0xe8: /* read test reg */ 862 dsp_out_data (pThis, pThis->test_reg); 863 break; 864 865 case 0xf2: 866 case 0xf3: 867 dsp_out_data (pThis, 0xaa); 868 pThis->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2; 869 #ifndef VBOX 870 qemu_irq_raise (pThis->pic[pThis->irq]); 871 #else 872 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1); 873 #endif 874 break; 875 876 case 0xf9: 877 pThis->needed_bytes = 1; 878 goto warn; 879 880 case 0xfa: 881 dsp_out_data (pThis, 0); 882 goto warn; 883 884 case 0xfc: /* FIXME */ 885 dsp_out_data (pThis, 0); 886 goto warn; 887 888 default: 889 LogFlowFunc(("Unrecognized command %#x\n", cmd)); 890 break; 891 } 892 } 893 894 if (!pThis->needed_bytes) { 898 } 899 900 if (!pThis->needed_bytes) 895 901 LogFlow(("\n")); 896 } 897 898 exit: 899 if (!pThis->needed_bytes) {902 903 exit: 904 905 if (!pThis->needed_bytes) 900 906 pThis->cmd = -1; 901 } 902 else { 907 else 903 908 pThis->cmd = cmd; 904 } 909 905 910 return; 906 911 907 912 warn: 908 913 LogFlowFunc(("warning: command %#x,%d is not truly understood yet\n", 909 cmd, pThis->needed_bytes));914 cmd, pThis->needed_bytes)); 910 915 goto exit; 911 912 916 } 913 917 … … 926 930 } 927 931 928 static void complete 932 static void complete(PSB16STATE pThis) 929 933 { 930 934 int d0, d1, d2; … … 932 936 pThis->cmd, pThis->in_index, pThis->needed_bytes)); 933 937 934 if (pThis->cmd > 0xaf && pThis->cmd < 0xd0) { 938 if (pThis->cmd > 0xaf && pThis->cmd < 0xd0) 939 { 935 940 d2 = dsp_get_data (pThis); 936 941 d1 = dsp_get_data (pThis); 937 942 d0 = dsp_get_data (pThis); 938 943 939 if (pThis->cmd & 8) { 940 LogFlowFunc(("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n", 941 pThis->cmd, d0, d1, d2)); 944 if (pThis->cmd & 8) 945 LogFlowFunc(("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n", pThis->cmd, d0, d1, d2)); 946 else 947 { 948 LogFlowFunc(("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n", pThis->cmd, d0, d1, d2)); 949 dma_cmd(pThis, pThis->cmd, d0, d1 + (d2 << 8)); 942 950 } 943 else { 944 LogFlowFunc(("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n", 945 pThis->cmd, d0, d1, d2)); 946 dma_cmd (pThis, pThis->cmd, d0, d1 + (d2 << 8)); 947 } 948 } 949 else { 950 switch (pThis->cmd) { 951 } 952 else 953 { 954 switch (pThis->cmd) 955 { 951 956 case 0x04: 952 957 pThis->csp_mode = dsp_get_data (pThis); … … 965 970 966 971 case 0x0e: 967 d0 = dsp_get_data (pThis); 968 d1 = dsp_get_data (pThis); 972 { 973 d0 = dsp_get_data(pThis); 974 d1 = dsp_get_data(pThis); 969 975 LogFlowFunc(("write CSP register %d <- %#x\n", d1, d0)); 970 if (d1 == 0x83) { 976 if (d1 == 0x83) 977 { 971 978 LogFlowFunc(("0x83[%d] <- %#x\n", pThis->csp_reg83r, d0)); 972 979 pThis->csp_reg83[pThis->csp_reg83r % 4] = d0; 973 980 pThis->csp_reg83r += 1; 974 981 } 975 else {982 else 976 983 pThis->csp_regs[d1] = d0; 977 }978 break;984 break; 985 } 979 986 980 987 case 0x0f: 981 d0 = dsp_get_data 982 LogFlowFunc(("read CSP register %#x -> %#x, mode=%#x\n", 983 d0, pThis->csp_regs[d0], pThis->csp_mode));984 if (d0 == 0x83){988 d0 = dsp_get_data(pThis); 989 LogFlowFunc(("read CSP register %#x -> %#x, mode=%#x\n", d0, pThis->csp_regs[d0], pThis->csp_mode)); 990 if (d0 == 0x83) 991 { 985 992 LogFlowFunc(("0x83[%d] -> %#x\n", 986 993 pThis->csp_reg83w, … … 989 996 pThis->csp_reg83w += 1; 990 997 } 991 else { 992 dsp_out_data (pThis, pThis->csp_regs[d0]); 993 } 998 else 999 dsp_out_data(pThis, pThis->csp_regs[d0]); 994 1000 break; 995 1001 996 1002 case 0x10: 997 d0 = dsp_get_data 1003 d0 = dsp_get_data(pThis); 998 1004 LogFlowFunc(("cmd 0x10 d0=%#x\n", d0)); 999 1005 break; … … 1004 1010 1005 1011 case 0x40: 1006 pThis->time_const = dsp_get_data 1012 pThis->time_const = dsp_get_data(pThis); 1007 1013 LogFlowFunc(("set time const %d\n", pThis->time_const)); 1008 1014 break; … … 1013 1019 #endif 1014 1020 case 0x41: 1015 pThis->freq = dsp_get_hilo 1021 pThis->freq = dsp_get_hilo(pThis); 1016 1022 LogFlowFunc(("set freq %d\n", pThis->freq)); 1017 1023 break; 1018 1024 1019 1025 case 0x48: 1020 pThis->block_size = dsp_get_lohi 1026 pThis->block_size = dsp_get_lohi(pThis) + 1; 1021 1027 LogFlowFunc(("set dma block len %d\n", pThis->block_size)); 1022 1028 break; … … 1030 1036 1031 1037 case 0x80: 1032 1033 1034 1035 1036 1037 1038 1038 { 1039 int freq, samples, bytes; 1040 uint64_t ticks; 1041 1042 freq = pThis->freq > 0 ? pThis->freq : 11025; 1043 samples = dsp_get_lohi (pThis) + 1; 1044 bytes = samples << pThis->fmt_stereo << ((pThis->fmt_bits == 16) ? 1 : 0); 1039 1045 #ifndef VBOX 1040 ticks = (bytes * ticks_per_sec) / freq; 1041 if (ticks < ticks_per_sec / 1024) { 1042 qemu_irq_raise (pThis->pic[pThis->irq]); 1046 ticks = (bytes * ticks_per_sec) / freq; 1047 if (ticks < ticks_per_sec / 1024) { 1048 qemu_irq_raise (pThis->pic[pThis->irq]); 1049 } 1050 else { 1051 if (pThis->aux_ts) { 1052 qemu_mod_timer ( 1053 pThis->aux_ts, 1054 qemu_get_clock (vm_clock) + ticks 1055 ); 1043 1056 } 1044 else { 1045 if (pThis->aux_ts) { 1046 qemu_mod_timer ( 1047 pThis->aux_ts, 1048 qemu_get_clock (vm_clock) + ticks 1049 ); 1050 } 1051 } 1052 LogFlowFunc(("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks)); 1057 } 1058 LogFlowFunc(("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks)); 1053 1059 #else /* VBOX */ 1054 1055 1056 1057 1058 1059 1060 ticks = (bytes * TMTimerGetFreq(pThis->pTimerIRQ)) / freq; 1061 if (ticks < TMTimerGetFreq(pThis->pTimerIRQ) / 1024) 1062 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1); 1063 else 1064 TMTimerSet(pThis->pTimerIRQ, TMTimerGet(pThis->pTimerIRQ) + ticks); 1065 LogFlowFunc(("mix silence %d %d % %RU64\n", samples, bytes, ticks)); 1060 1066 #endif /* VBOX */ 1061 } 1062 break; 1067 1068 break; 1069 } 1063 1070 1064 1071 case 0xe0: 1065 d0 = dsp_get_data 1072 d0 = dsp_get_data(pThis); 1066 1073 pThis->out_data_len = 0; 1067 1074 LogFlowFunc(("E0 data = %#x\n", d0)); 1068 dsp_out_data 1075 dsp_out_data(pThis, ~d0); 1069 1076 break; 1070 1077 1071 1078 case 0xe2: 1072 d0 = dsp_get_data 1079 d0 = dsp_get_data(pThis); 1073 1080 LogFlow(("SB16:E2 = %#x\n", d0)); 1074 1081 break; 1075 1082 1076 1083 case 0xe4: 1077 pThis->test_reg = dsp_get_data 1084 pThis->test_reg = dsp_get_data(pThis); 1078 1085 break; 1079 1086 1080 1087 case 0xf9: 1081 d0 = dsp_get_data 1088 d0 = dsp_get_data(pThis); 1082 1089 LogFlowFunc(("command 0xf9 with %#x\n", d0)); 1083 1090 switch (d0) { 1084 1091 case 0x0e: 1085 dsp_out_data 1092 dsp_out_data(pThis, 0xff); 1086 1093 break; 1087 1094 1088 1095 case 0x0f: 1089 dsp_out_data 1096 dsp_out_data(pThis, 0x07); 1090 1097 break; 1091 1098 1092 1099 case 0x37: 1093 dsp_out_data 1100 dsp_out_data(pThis, 0x38); 1094 1101 break; 1095 1102 1096 1103 default: 1097 dsp_out_data 1104 dsp_out_data(pThis, 0x00); 1098 1105 break; 1099 1106 } … … 1111 1118 } 1112 1119 1113 static void legacy_reset(PSB16STATE pThis)1120 static void sb16ResetLegacy(PSB16STATE pThis) 1114 1121 { 1115 1122 pThis->freq = 11025; … … 1157 1164 #else /* VBOX */ 1158 1165 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0); 1159 if (pThis->dma_auto) { 1166 if (pThis->dma_auto) 1167 { 1160 1168 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 1); 1161 1169 PDMDevHlpISASetIrq(pThis->pDevIns, pThis->irq, 0); … … 1178 1186 sb16SpeakerControl(pThis, 0); 1179 1187 sb16Control(pThis, 0); 1180 legacy_reset(pThis);1188 sb16ResetLegacy(pThis); 1181 1189 } 1182 1190 … … 1245 1253 if (0 == pThis->needed_bytes) 1246 1254 { 1247 command(pThis, val);1255 sb16HandleCommand(pThis, val); 1248 1256 #if 0 1249 1257 if (0 == pThis->needed_bytes) { … … 1381 1389 1382 1390 RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node) 1383 pDrv->Out.phStrmOut 1391 pDrv->Out.phStrmOut = NULL; 1384 1392 1385 1393 pThis->pSinkOutput = NULL; … … 1726 1734 { 1727 1735 LogFlowFunc(("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n", 1728 pThis->block_size, nchan, dma_pos, dma_len));1736 pThis->block_size, nchan, dma_pos, dma_len)); 1729 1737 return dma_pos; 1730 1738 } … … 1790 1798 written = sb16WriteAudio(pThis, nchan, dma_pos, dma_len, copy); 1791 1799 dma_pos = (dma_pos + written) % dma_len; 1792 Assert(pThis->left_till_irq >= written);1793 1800 pThis->left_till_irq -= written; 1794 1801 … … 2036 2043 if (pThis->freq) 2037 2044 { 2038 pThis->audio_free = 0;2039 2040 2045 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2041 2046 PDMAUDIOSTREAMCFG streamCfg; … … 2048 2053 AssertRC(rc); 2049 2054 #else 2055 pThis->audio_free = 0; 2056 2050 2057 audsettings_t as; 2051 2058 as.freq = pThis->freq; … … 2140 2147 static DECLCALLBACK(int) sb16LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass) 2141 2148 { 2142 PSB16STATE pThis = PDMINS_2_DATA 2149 PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE); 2143 2150 2144 2151 SSMR3PutS32(pSSM, pThis->irqCfg); … … 2152 2159 static DECLCALLBACK(int) sb16SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM) 2153 2160 { 2154 PSB16STATE pThis = PDMINS_2_DATA 2161 PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE); 2155 2162 2156 2163 sb16LiveExec (pDevIns, pSSM, 0); … … 2161 2168 static DECLCALLBACK(int) sb16LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass) 2162 2169 { 2163 PSB16STATE pThis = PDMINS_2_DATA 2170 PSB16STATE pThis = PDMINS_2_DATA(pDevIns, PSB16STATE); 2164 2171 2165 2172 AssertMsgReturn( uVersion == SB16_SAVE_STATE_VERSION … … 2185 2192 || hdma != pThis->hdmaCfg 2186 2193 || port != pThis->portCfg 2187 || ver != pThis->verCfg ) 2194 || ver != pThis->verCfg) 2195 { 2188 2196 return SSMR3SetCfgError(pSSM, RT_SRC_POS, 2189 2197 N_("config changed: irq=%x/%x dma=%x/%x hdma=%x/%x port=%x/%x ver=%x/%x (saved/config)"), … … 2193 2201 port, pThis->portCfg, 2194 2202 ver, pThis->verCfg); 2195 } 2203 } 2204 } 2205 2196 2206 if (uPass != SSM_PASS_FINAL) 2197 2207 return VINF_SUCCESS; … … 2201 2211 } 2202 2212 2213 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2203 2214 static int sb16OpenOut(PSB16STATE pThis, PPDMAUDIOSTREAMCFG pCfg) 2204 2215 { … … 2244 2255 return rc; 2245 2256 } 2257 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */ 2246 2258 2247 2259 /** … … 2366 2378 AssertMsgFailedReturn(("Error creating IRQ timer, rc=%Rrc\n", rc), rc); 2367 2379 2368 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER2369 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16TimerIO, pThis,2370 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 IO timer", &pThis->pTimerIO);2371 if (RT_FAILURE(rc))2372 AssertMsgFailedReturn(("Error creating I/O timer, rc=%Rrc\n", rc), rc);2373 else2374 {2375 pThis->uTicksIO = PDMDevHlpTMTimeVirtGetFreq(pDevIns) / 200; /** Hz. @todo Make this configurable! */2376 if (pThis->uTicksIO < 100)2377 pThis->uTicksIO = 100;2378 LogFunc(("I/O timer ticks=%RU64\n", pThis->uTicksIO));2379 2380 /* Fire off timer. */2381 TMTimerSet(pThis->pTimerIO, TMTimerGet(pThis->pTimerIO) + pThis->uTicksIO);2382 }2383 #endif /* VBOX_WITH_PDM_AUDIO_DRIVER */2384 2385 2380 rc = PDMDevHlpIOPortRegister(pDevIns, pThis->port + 0x04, 2, pThis, 2386 2381 mixer_write, mixer_read, NULL, NULL, "SB16"); … … 2428 2423 rc = PDMDevHlpDriverAttach(pDevIns, 0, &pThis->IBase, &pThis->pDrvBase, "Audio Driver Port"); 2429 2424 if (rc == VERR_PDM_NO_ATTACHED_DRIVER) 2430 LogFunc((" ac97: No attached driver!\n"));2425 LogFunc(("SB16: No attached driver!\n")); 2431 2426 else if (RT_FAILURE(rc)) 2432 2427 { 2433 AssertMsgFailed(("Failed to attach AC97LUN #0! rc=%Rrc\n", rc));2428 AssertMsgFailed(("Failed to attach SB16 LUN #0! rc=%Rrc\n", rc)); 2434 2429 return rc; 2435 2430 } … … 2437 2432 2438 2433 #ifdef VBOX_WITH_PDM_AUDIO_DRIVER 2439 legacy_reset(pThis);2434 sb16ResetLegacy(pThis); 2440 2435 2441 2436 PSB16DRIVER pDrv; … … 2443 2438 RTListForEach(&pThis->lstDrv, pDrv, SB16DRIVER, Node) 2444 2439 { 2445 /*2446 * Only primary drivers are critical for the VM to run. Everything else2447 * might not worth showing an own error message box in the GUI.2448 */2449 if (!(pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY))2450 continue;2451 2452 2440 PPDMIAUDIOCONNECTOR pCon = pDrv->pConnector; 2453 2441 AssertPtr(pCon); 2454 if (!pCon->pfnIsOutputOK(pCon, pDrv->Out.pStrmOut)) 2442 2443 bool fIsOK = pCon->pfnIsOutputOK(pCon, pDrv->Out.pStrmOut); 2444 if (fIsOK) 2455 2445 { 2456 LogRel(("SB16: WARNING: Unable to open PCM OUT!\n")); 2446 rc = pCon->pfnEnableOut(pCon, pDrv->Out.pStrmOut, true /* fEnable */); 2447 fIsOK = RT_SUCCESS(rc); 2448 } 2449 2450 if (!fIsOK) 2451 { 2452 /* 2453 * Only primary drivers are critical for the VM to run. Everything else 2454 * might not worth showing an own error message box in the GUI. 2455 */ 2456 if (!(pDrv->Flags & PDMAUDIODRVFLAG_PRIMARY)) 2457 continue; 2458 2459 LogRel(("SB16: Warning: Unable to enable/use output for LUN#%RU8\n", uLUN)); 2457 2460 2458 2461 pCon->pfnCloseOut(pCon, pDrv->Out.pStrmOut); … … 2465 2468 "with the consequence that no sound is audible")); 2466 2469 } 2470 2471 uLUN++; 2472 } 2473 2474 if (RT_SUCCESS(rc)) 2475 { 2476 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, sb16TimerIO, pThis, 2477 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "SB16 IO timer", &pThis->pTimerIO); 2478 if (RT_FAILURE(rc)) 2479 AssertMsgFailedReturn(("Error creating I/O timer, rc=%Rrc\n", rc), rc); 2480 else 2481 { 2482 pThis->uTicksIO = PDMDevHlpTMTimeVirtGetFreq(pDevIns) / 200; /** Hz. @todo Make this configurable! */ 2483 if (pThis->uTicksIO < 100) 2484 pThis->uTicksIO = 100; 2485 LogFunc(("I/O timer ticks=%RU64\n", pThis->uTicksIO)); 2486 2487 /* Fire off timer. */ 2488 TMTimerSet(pThis->pTimerIO, TMTimerGet(pThis->pTimerIO) + pThis->uTicksIO); 2489 } 2467 2490 } 2468 2491 #else 2469 2492 AUD_register_card("sb16", &pThis->card); 2470 legacy_reset(pThis);2493 sb16ResetLegacy(pThis); 2471 2494 2472 2495 if (!AUD_is_host_voice_out_ok(pThis->voice))
Note:
See TracChangeset
for help on using the changeset viewer.