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