Category : C Source Code
Archive   : SBDAC.ZIP
Filename : DACDMA.C

 
Output of file : DACDMA.C contained in archive : SBDAC.ZIP
/* Output to SB DAC using DMA mode */

#include
#include
#include
#include
#include
#include
#include
#include

#include "sb.h"

void far interrupt (*OldIRQ)();
volatile int DMA_complete;


/* Interrupt handler for DMA complete IRQ from Soundblaster */
void far interrupt SBHandler()
{
enable();
DMA_complete = 1;
outportb(0x20,0x20);
}

/* Sets the sample rate to be used for digitising or playback */
void SetSampleRate(unsigned rate)
{
unsigned char tc;

tc = (unsigned char)(256 - (1000000/rate));

writedac(0x40); /* Command byte for sample rate */
writedac(tc); /* Sample rate time constant */
}

void SetVoice(int state)
{
writedac((state) ? 0xd1 : 0xd3); /* Command bytes for voice: */
/* 0xD1 - voice on */
/* 0xD3 - voice off */
}




void OutVoice(char *data, unsigned dlen)
{
int t;
long addr;
register int i;
unsigned char im, tm;

DMA_complete = 0;

/* Enable interrupts on PIC */
im = inportb(0x21);
tm = ~(1 << SbIRQ);
outportb(0x21,im & tm);
enable();

/* Set DMA mode */
outportb(DMA_MASK,5);
outportb(DMA_FF,0);
outportb(DMA_MODE,0x49);

/* Set transfer address */
addr = ((long)FP_SEG(data) << 4) + (long)FP_OFF(data);
t = (int)(addr >> 16);
outportb(DMAPAGE+3,t);
t = (int)(addr & 0xffff);
outportb(DMA + 2 * SbDMAchan,t & 0xff);
outportb(DMA + 2 * SbDMAchan,t >> 8);

/* Set transfer length byte count */
outportb(DMA + 2 * SbDMAchan + 1,dlen & 0xff);
outportb(DMA + 2 * SbDMAchan + 1,dlen >> 8);

/* Unmask DMA channel */
outportb(DMA_MASK,SbDMAchan);

/* Setup Soundblaster for transfer */
writedac(0x48); /* One command byte used for DMA DAC transfer */

/* Write length */
writedac(dlen & 0xff);
writedac(dlen >> 8);

writedac(0x14); /* Second command byte for DMA DAC transfer */

/* Write length */
writedac(dlen & 0xff);
writedac(dlen >> 8);
}

void main(int argc, char *argv[])
{
FILE *f;
char *raw;
long sample_len;
register int j, i;
unsigned sl, tmp, nr, sr;
unsigned char tm;

if(argc < 2)
{
puts("Usage: dacdma sample [sample rate]");
exit(1);
}

if(GetSBParams(&SbIOaddr,&SbIRQ,&SbDMAchan))
{
puts("BLASTER environment variable not set.");
exit(1);
}

if(InitSB())
{
printf("Could not find Soundblaster!\n");
exit(1);
}
printf("Found Soundblaster at address %xh, IRQ %d, DMA %d.\n",
SbIOaddr,SbIRQ,SbDMAchan);

f = fopen(argv[1],"rb");
if(f == NULL)
{
printf("Could not open sample file %s\n",argv[1]);
exit(1);
}
sample_len = filelength(fileno(f));
if(sample_len > 64000)
sl = 64000;
else
sl = (int)sample_len;

raw = (signed char *)farmalloc((unsigned long)sl);
nr = fread(raw,1,sl,f);

fclose(f);


/* Insert our IRQ handler into interrupt chain */
disable();
OldIRQ = getvect(0x08 + SbIRQ);
setvect(0x08 + SbIRQ,SBHandler);
enable();

sr = 11000;
if(argc == 3)
sr = atoi(argv[2]);

printf("Playing sample\n");

SetSampleRate(sr);
SetVoice(1);

OutVoice(raw,sl);

while(!kbhit() && !DMA_complete)
;
if(!DMA_complete)
getch();

SetVoice(0);

printf("Done.\n");

/* Restore old IRQ vector */
disable();
setvect(0x08 + SbIRQ,OldIRQ);
tm = inportb(0x21);
outportb(0x21,tm | (1 << SbIRQ));
enable();

farfree(raw);

exit(0);
}


  3 Responses to “Category : C Source Code
Archive   : SBDAC.ZIP
Filename : DACDMA.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/