xref: /reactos/drivers/multimedia/audio/sound/wave.c (revision 40462c92)
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