Пример #1
0
void TrashAudio(void)
{
  /* If SoundBlaster was initialized... */
  if(SndRate)
  {
    /* Reset DSP */
    WriteDSP(0xD3);
    WriteDSP(0xD0);
    /* Disable DMA */
    outp(0x0A,SBDMA|0x04);
    /* Disable IRQ */
    outp(0x21,inp(0x21)|(1<<SBIRQ));
  }

  /* If SB interrupt vector changed, restore it */
  if(IRQ5Old) { _dos_setvect(SBIRQ+8,IRQ5Old);IRQ5Old=0; }
  /* If low memory was allocated for DMA, free it */
  if(SBSegment) { FreeSegment(SBSegment);SBSegment=0; }
  /* Sound trashed */
  SndRate=0;
}
Пример #2
0
/*
================
StartSB

================
*/
void StartSB(void)
{
	int		i;

// version 4.xx startup code
	if (dsp_version >= 4)
	{
		Con_Printf("Version 4 SB startup\n");
		WriteDSP(0xd1); // turn on speaker

		WriteDSP(0x41);

		WriteDSP(shm->speed>>8);
		WriteDSP(shm->speed&0xff);

		WriteDSP(0xb6);	// 16-bit output
		WriteDSP(0x30);	// stereo
		WriteDSP((shm->samples-1) & 0xff);	// # of samples - 1
		WriteDSP((shm->samples-1) >> 8);
	}
Пример #3
0
unsigned int InitAudio(unsigned int Rate,unsigned int Latency)
{
  static const int PagePort[8] = { 0x87,0x83,0x81,0x82,-1,0x8B,0x89,0x8A };
  int J,TotalBuf;
  char *P;

  /* Disable audio if was initialized */
  TrashAudio();

  /* If turning audio off, drop out */
  if(!Rate) return(1);

  /* If Rate is out of range, fall out */
  if((Rate<8192)||(Rate>44100)) return(0);

  /* Default values */
  SBPort    = 0x220;
  SBIRQ     = 7;
  SBDMA     = 1;
  SBIRQBusy = 0;
  SBWrite   = 0;
  SBRead    = 0;

  /* Get SoundBlaster Port#,IRQ#,DMA# */
  if(P=getenv("BLASTER"))
    while(*P)
      switch(toupper(*P++))
      {
        case 'A': SBPort=strtol(P,0,16);break;
        case 'D': SBDMA=strtol(P,0,16);break;
        case 'I': SBIRQ=strtol(P,0,16);break;
      }

  /* IRQ# = 0,1,2,3,4,5,6,7, DMA# = 0,1,2,3 */
  if((SBIRQ>7)||(SBDMA>3)) return(0);

  /* Reset DSP */
  outp(SBPort+0x06,0x01); /* Set the reset flag   */
  delay(100);             /* Wait for 100ms       */
  outp(SBPort+0x06,0x00); /* Clear the reset flag */

  /* Wait for READY status */
  for(J=100;J&&!(inp(SBPort+0x0E)&0x80);J--);
  if(!J) return(0);
  for(J=100;J&&(ReadDSP()!=0xAA);J--);
  if(!J) return(0);

  /* Allocate low memory for DMA buffer */
  TotalBuf=(Rate*Latency/1000/SND_BUFSIZE)*SND_BUFSIZE;
  if(TotalBuf<SND_BUFSIZE) TotalBuf=SND_BUFSIZE;
  SBBuffers=TotalBuf/SND_BUFSIZE;
  SBSegment=GetSegment(TotalBuf*sizeof(sample)*2/16+4);
  if(!SBSegment) return(0);
  J=SBSegment*16;
  SBBuffer=(unsigned char *)J;
  if((J>>16)!=((J+TotalBuf-1)>>16)) SBBuffer+=TotalBuf;
  memset(SBBuffer,0,TotalBuf*sizeof(sample));

  /* Interrupts off */
  _disable();

  /* Save old interrupt vector */
  IRQ5Old=(void (interrupt *)())_dos_getvect(SBIRQ+8);
  /* Install new interrupt vector */
  _dos_setvect(SBIRQ+8,IRQ5Handler);
  /* Enable the SoundBlaster IRQ */
  outp(0x21,inp(0x21)&~(1<<SBIRQ));

  /* Disable DMA channel */
  outp(0x0A,SBDMA|0x04);
  /* Clear byte pointer flip-flop */
  outp(0x0C,0x00);
  /* Auto-initialized playback mode */
  outp(0x0B,SBDMA|0x58);
  /* Write DMA offset and transfer length */
  J=SBDMA<<1;
  outp(J,(int)SBBuffer&0xFF);
  outp(J,((int)SBBuffer>>8)&0xFF);
  outp(J+1,(TotalBuf-1)&0xFF);
  outp(J+1,((TotalBuf-1)>>8)&0xFF);
  /* Write DMA page */
  outp(PagePort[SBDMA],((int)SBBuffer>>16)&0xFF);
  /* Enable DMA channel */
  outp(0x0A,SBDMA);

  /* Enable interrupts */
  _enable();

  /* Set sampling rate */
  WriteDSP(0x40);
  WriteDSP((65536L-(256000000L/Rate))/256);
  /* Set DMA transfer size */
  WriteDSP(0x48);
  WriteDSP((SND_BUFSIZE-1)&0xFF);
  WriteDSP((SND_BUFSIZE-1)>>8);
  /* Run auto-initialized 8bit DMA */
  WriteDSP(0x90);
  /* Speaker enabled */
  WriteDSP(0xD1);

  /* Done */
  return(SndRate=Rate);
}