1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: mkernel/modules/sound/sound.c 5 * PURPOSE: SoundBlaster 16 Driver 6 * PROGRAMMER: Snatched from David Welch (welch@mcmail.com) 7 * Modified for Soundblaster by Robert Bergkvist (fragdance@hotmail.com) 8 * UPDATE HISTORY: 9 * ??/??/??: Created 10 * 11 */ 12 13 /* FUNCTIONS **************************************************************/ 14 15 #include <ntddk.h> 16 #include <string.h> 17 #include <devices.h> 18 19 #include "sb16.h" 20 #include "dsp.h" 21 #include "mixer.h" 22 #include "in.h" 23 #include "wave.h" 24 25 #define NDEBUG 26 #include <debug.h> 27 28 SB16 sb16; 29 30 ULONG OldIRQ; 31 PKINTERRUPT IrqObject; 32 33 static BOOLEAN NTAPI DMAOutputISR(PKINTERRUPT Interrupt, PVOID ServiceContext) 34 { 35 DPRINT1("interrupt\n"); 36 return FALSE; 37 } 38 39 void sb16_play(WAVE_HDR* wave) 40 { 41 ULONG MappedIrq; 42 KIRQL Dirql; 43 KAFFINITY Affinity; 44 PKINTERRUPT IrqObject; 45 unsigned int newmask; 46 47 unsigned int i; 48 unsigned int tmp[255]; 49 i=0; 50 dump_wav(wave); 51 do 52 { 53 // tmp[i++]=get_dma_page(0x0fffff); 54 // DPRINT1("0x%x ",tmp[i-1]); 55 } 56 while((tmp[i-1]&0xffff)!=0); 57 // free_page((tmp[0]),i-1); 58 sb16.buffer=((unsigned char*)tmp[i-1]); 59 60 /* 61 * Because this is used by almost every subsystem including irqs it 62 * must be atomic. The following code sequence disables interrupts after 63 * saving the previous state of the interrupt flag 64 */ 65 66 _disable(); 67 68 memcpy(sb16.buffer,(&wave->data),wave->dLen); 69 70 71 MappedIrq = HalGetInterruptVector(Internal,0,0,8+sb16.irq,&Dirql,&Affinity); 72 73 74 75 IoConnectInterrupt(&IrqObject,DMAOutputISR,0,NULL,MappedIrq,Dirql,Dirql,0,FALSE,Affinity,FALSE); 76 77 // mask=inb(0x21); 78 newmask=((int)1<<sb16.irq); 79 // outb(0x21,(mask&~newmask)); 80 81 // Restore the interrupt flag 82 _enable(); 83 84 85 86 // disable_dma(sb16.dma8); 87 //outb(0x0a,5); 88 // clear_dma_ff(1); 89 //outb(0xc,0); 90 // set_dma_count(1,wave->dLen); 91 //set_dma_mode(1,DMA_MODE_WRITE); 92 //outb(0xb,0x49); 93 //outb(0x3,(wave->dLen)&0xff); 94 //outb(0x3,((unsigned int)(wave->dLen)>>8)&0xff); 95 //set_dma_addr(sb16.dma8,(unsigned int)sb16.buffer); 96 //outb(0x83,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>16))&0xf); 97 //outb(0x2,((unsigned int)sb16.buffer&0xff)); 98 //outb(0x2,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>8))&0xff); 99 //enable_dma(sb16.dma8); 100 //outb(0xa,1); 101 102 write_dsp(sb16.base,0x00D1); 103 104 write_dsp(sb16.base,0x40); 105 write_dsp(sb16.base,((unsigned char)256-(1000000/wave->nSamplesPerSec))); 106 107 // outb(sb16.base + 4, (int) 0xa); 108 // outb(sb16.base + 5, (int) 0x00); 109 110 // outb(sb16.base + 4, (int) 4); 111 // outb(sb16.base + 5, (int) 0xFF); 112 113 // outb(sb16.base + 4, (int) 0x22); 114 // outb(sb16.base + 5, (int) 0xFF); 115 116 write_dsp(sb16.base,0x14); 117 write_dsp(sb16.base,(wave->dLen&0x00ff)); 118 write_dsp(sb16.base,((wave->dLen)&0xff00)>>8); 119 120 // write_dsp(sb16.base,0xc0); 121 // write_dsp(sb16.base,0x0); 122 // OldIRQ=HalGetInterruptVector(Internal,0,0,irq+8,&irql,&affinity); 123 // DPRINT1("OldIRQ: 0x%x\n",OldIRQ); 124 125 // status=IoConnectInterrupt(&IrqObject,playRoutine,0,NULL,OldIRQ,irql,irql,0,FALSE,affinity,FALSE); 126 // if(status!=STATUS_SUCCESS) DPRINT1("Couldn't set irq\n"); 127 // else DPRINT1("IRQ set\n"); 128 129 } 130 131 void dump_wav(WAVE_HDR* wave) 132 { 133 DPRINT1("wave.rID: %c%c%c%c\n",wave->rID[0],wave->rID[1],wave->rID[2],wave->rID[3]); 134 DPRINT1("wave.rLen: 0x%x\n",wave->rLen); 135 DPRINT1("wave.wID: %c%c%c%c\n",wave->wID[0],wave->wID[1],wave->wID[2],wave->wID[3]); 136 DPRINT1("wave.fID: %c%c%c%c\n",wave->fID[0],wave->fID[1],wave->fID[2],wave->fID[3]); 137 DPRINT1("wave.fLen: 0x%x\n",wave->fLen); 138 DPRINT1("wave.wFormatTag: 0x%x\n",wave->wFormatTag); 139 DPRINT1("wave.nChannels: 0x%x\n",wave->nChannels); 140 DPRINT1("wave.nSamplesPerSec: 0x%x\n",wave->nSamplesPerSec); 141 DPRINT1("wave.nAvgBytesPerSec: 0x%x\n",wave->nAvgBytesPerSec); 142 DPRINT1("wave.nBlockAlign: 0x%x\n",wave->nBlockAlign); 143 DPRINT1("wave.FormatSpecific: 0x%x\n",wave->FormatSpecific); 144 DPRINT1("wave.dID: %c%c%c%c\n",wave->dID[0],wave->dID[1],wave->dID[2],wave->dID[3]); 145 DPRINT1("wave.dLen: 0x%x\n",wave->dLen); 146 } 147 148 BOOLEAN playRoutine(PKINTERRUPT Interrupt,PVOID ServiceContext) 149 { 150 return FALSE; 151 } 152