1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
 * COPYRIGHT:        See COPYING in the top level directory
 * PROJECT:          ReactOS kernel
 * FILE:             mkernel/modules/sound/sound.c
 * PURPOSE:          SoundBlaster 16 Driver
 * PROGRAMMER:       Snatched from David Welch (welch@mcmail.com)
 *		     Modified for Soundblaster by Robert Bergkvist (fragdance@hotmail.com)
 * UPDATE HISTORY:
 *              ??/??/??: Created
 *
 */

/* FUNCTIONS **************************************************************/

#include <ntddk.h>
#include <string.h>
#include <devices.h>

#include "sb16.h"
#include "dsp.h"
#include "mixer.h"
#include "in.h"
#include "wave.h"

#define NDEBUG
#include <debug.h>

SB16 sb16;

ULONG OldIRQ;
PKINTERRUPT IrqObject;

static BOOLEAN NTAPI DMAOutputISR(PKINTERRUPT Interrupt, PVOID ServiceContext)
{
	DPRINT1("interrupt\n");
	return FALSE;
}

void sb16_play(WAVE_HDR* wave)
{
	ULONG MappedIrq;
	KIRQL Dirql;
	KAFFINITY Affinity;
	PKINTERRUPT IrqObject;
	unsigned int newmask;

	unsigned int i;
	unsigned int tmp[255];
	i=0;<--- Assignment 'i=0', assigned value is 0<--- Assignment 'i=0', assigned value is 0
	dump_wav(wave);
  	do
  	{
//  		tmp[i++]=get_dma_page(0x0fffff);
//			DPRINT1("0x%x ",tmp[i-1]);
  	}
  	while((tmp[i-1]&0xffff)!=0);<--- Negative array index<--- Uninitialized variable: tmp
  			// free_page((tmp[0]),i-1);
  	sb16.buffer=((unsigned char*)tmp[i-1]);<--- Negative array index

   /*
    * Because this is used by almost every subsystem including irqs it
    * must be atomic. The following code sequence disables interrupts after
    * saving the previous state of the interrupt flag
    */

   	_disable();

       memcpy(sb16.buffer,(&wave->data),wave->dLen);


				MappedIrq = HalGetInterruptVector(Internal,0,0,8+sb16.irq,&Dirql,&Affinity);



				IoConnectInterrupt(&IrqObject,DMAOutputISR,0,NULL,MappedIrq,Dirql,Dirql,0,FALSE,Affinity,FALSE);

	// mask=inb(0x21);
	newmask=((int)1<<sb16.irq);
	// outb(0x21,(mask&~newmask));

       // Restore the interrupt flag
	_enable();



	// disable_dma(sb16.dma8);
	//outb(0x0a,5);
	// clear_dma_ff(1);
	//outb(0xc,0);
	// set_dma_count(1,wave->dLen);
	//set_dma_mode(1,DMA_MODE_WRITE);
	//outb(0xb,0x49);
	//outb(0x3,(wave->dLen)&0xff);
	//outb(0x3,((unsigned int)(wave->dLen)>>8)&0xff);
	//set_dma_addr(sb16.dma8,(unsigned int)sb16.buffer);
	//outb(0x83,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>16))&0xf);
	//outb(0x2,((unsigned int)sb16.buffer&0xff));
	//outb(0x2,(((unsigned int)(sb16.buffer-IDMAP_BASE)>>8))&0xff);
	//enable_dma(sb16.dma8);
	//outb(0xa,1);

	write_dsp(sb16.base,0x00D1);

	write_dsp(sb16.base,0x40);
	write_dsp(sb16.base,((unsigned char)256-(1000000/wave->nSamplesPerSec)));

//  outb(sb16.base + 4, (int) 0xa);
//  outb(sb16.base + 5, (int) 0x00);

//  outb(sb16.base + 4, (int) 4);
//  outb(sb16.base + 5, (int) 0xFF);

//  outb(sb16.base + 4, (int) 0x22);
//  outb(sb16.base + 5, (int) 0xFF);

	write_dsp(sb16.base,0x14);
	write_dsp(sb16.base,(wave->dLen&0x00ff));
	write_dsp(sb16.base,((wave->dLen)&0xff00)>>8);

//	write_dsp(sb16.base,0xc0);
//	write_dsp(sb16.base,0x0);
//	OldIRQ=HalGetInterruptVector(Internal,0,0,irq+8,&irql,&affinity);
//	DPRINT1("OldIRQ: 0x%x\n",OldIRQ);

//  status=IoConnectInterrupt(&IrqObject,playRoutine,0,NULL,OldIRQ,irql,irql,0,FALSE,affinity,FALSE);
//  if(status!=STATUS_SUCCESS) DPRINT1("Couldn't set irq\n");
//  else DPRINT1("IRQ set\n");

}

void dump_wav(WAVE_HDR* wave)
{
	DPRINT1("wave.rID: %c%c%c%c\n",wave->rID[0],wave->rID[1],wave->rID[2],wave->rID[3]);
	DPRINT1("wave.rLen: 0x%x\n",wave->rLen);
	DPRINT1("wave.wID: %c%c%c%c\n",wave->wID[0],wave->wID[1],wave->wID[2],wave->wID[3]);
	DPRINT1("wave.fID: %c%c%c%c\n",wave->fID[0],wave->fID[1],wave->fID[2],wave->fID[3]);
	DPRINT1("wave.fLen: 0x%x\n",wave->fLen);
	DPRINT1("wave.wFormatTag: 0x%x\n",wave->wFormatTag);
	DPRINT1("wave.nChannels: 0x%x\n",wave->nChannels);
	DPRINT1("wave.nSamplesPerSec: 0x%x\n",wave->nSamplesPerSec);
	DPRINT1("wave.nAvgBytesPerSec: 0x%x\n",wave->nAvgBytesPerSec);
	DPRINT1("wave.nBlockAlign: 0x%x\n",wave->nBlockAlign);
	DPRINT1("wave.FormatSpecific: 0x%x\n",wave->FormatSpecific);
	DPRINT1("wave.dID: %c%c%c%c\n",wave->dID[0],wave->dID[1],wave->dID[2],wave->dID[3]);
	DPRINT1("wave.dLen: 0x%x\n",wave->dLen);
}

BOOLEAN playRoutine(PKINTERRUPT Interrupt,PVOID ServiceContext)
{
	return FALSE;
}