⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sb.c

📁 SFC游戏模拟器 snes9x 1.43 的原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
      sx_sb_dma_count++;      if (sx_sb_dma_count > 16) {	 sx_sb_bufnum = (_dma_todo(sx_sb_dma) > (unsigned)sx_sb_dma_size) ? 1 : 0;	 sx_sb_dma_count = 0;      }   }   if (!sx_sb_semaphore) {      sx_sb_semaphore = TRUE;      ENABLE();                              /* mix some more samples */      sx_sb_mix_some_samples(sx_sb_buf[sx_sb_bufnum], _dos_ds);      DISABLE();      sx_sb_semaphore = FALSE;   }    sx_sb_bufnum = 1 - sx_sb_bufnum;    if (sx_sb_16bit)                             /* acknowledge SB */      inportb(sx_sb_port+0x0F);   else      inportb(sx_sb_port+0x0E);   _eoi(sx_sb_irq);                            /* acknowledge interrupt */   return 0;}static END_OF_FUNCTION(sx_sb_interrupt);void sx_sb_mix_some_samples(unsigned long buf, unsigned short seg){    int i;    if (sx_sb_mute) {       _farsetsel(seg);       if (sx_sb_16bit) {          for (i=0; i<sx_sb_dma_mix_size; i++) {             _farnspokew(buf, 0x0);             buf += 2;          }       }       else {          for (i=0; i<sx_sb_dma_mix_size; i++) {             _farnspokeb(buf, 0x80);             buf++;          }       }    }    else {       extern void S9xMixSamples (unsigned char *, int);       S9xMixSamples ((unsigned char *) mixbuffer, sx_sb_dma_mix_size);              if (sx_sb_16bit)           movedata(_my_ds(), (int)mixbuffer, seg, buf, sx_sb_dma_mix_size << 1);       else           movedata(_my_ds(), (int)mixbuffer, seg, buf, sx_sb_dma_mix_size);    }}static END_OF_FUNCTION(sx_sb_mix_some_samples);/* sx_sb_start: *  Starts up the sound output. */static void sx_sb_start(){   sx_sb_bufnum = 0;   sx_sb_voice(1);   sx_sb_set_sample_rate(sx_sb_freq);   if ((sx_sb_hw_dsp_ver >= 0x300) && (sx_sb_dsp_ver < 0x400))      sx_sb_stereo_mode(sx_sb_stereo);   if (sx_sb_dsp_ver <= 0x200)      _dma_start(sx_sb_dma, sx_sb_buf[0], sx_sb_dma_size, FALSE, FALSE);   else      _dma_start(sx_sb_dma, sx_sb_buf[0], sx_sb_dma_size*2, TRUE, FALSE);   sx_sb_play_buffer(sx_sb_dma_size);}/* sx_sb_stop: *  Stops the sound output. */static void sx_sb_stop(){   /* halt sound output */   sx_sb_voice(0);   /* stop dma transfer */   _dma_stop(sx_sb_dma);   if (sx_sb_dsp_ver <= 0x0200)      sx_sb_write_dsp(0xD0);    sx_sb_reset_dsp(1);}/* sx_sb_detect: *  SB detection routine. Uses the BLASTER environment variable, *  or 'sensible' guesses if that doesn't exist. */int sx_sb_detect (int *stereo, int *bits16){   char *blaster = getenv("BLASTER");   char *msg;   int cmask;   int max_freq;   int default_freq;   /* parse BLASTER env */   if (blaster) {       while (*blaster) {	 while ((*blaster == ' ') || (*blaster == '\t'))	    blaster++;	 if (*blaster) {	    switch (*blaster) {	       case 'a': case 'A':		  if (sx_sb_port < 0)		     sx_sb_port = strtol(blaster+1, NULL, 16);		  break;	       case 'i': case 'I':		  if (sx_sb_irq < 0)		     sx_sb_irq = strtol(blaster+1, NULL, 10);		  break;	       case 'd': case 'D':		  sx_sb_dma8 = strtol(blaster+1, NULL, 10);		  break;	       case 'h': case 'H':		  sx_sb_dma16 = strtol(blaster+1, NULL, 10);		  break;	    }	    while ((*blaster) && (*blaster != ' ') && (*blaster != '\t'))	       blaster++;	 }      }   }   if (sx_sb_port < 0)      sx_sb_port = 0x220;   /* make sure we got a good port address */   if (sx_sb_reset_dsp(1) != 0) {       static int bases[] = { 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0 };      int i;      for (i=0; bases[i]; i++) {	 sx_sb_port = bases[i];	 if (sx_sb_reset_dsp(1) == 0)	    break;      }   }   /* check if the card really exists */   sx_sb_read_dsp_version();   if (sx_sb_hw_dsp_ver < 0) {      strcpy(allegro_error, "Sound Blaster not found");      return FALSE;   }   sx_sb_dsp_ver = sx_sb_hw_dsp_ver;   if (sx_sb_dsp_ver >= 0x400) {      /* read configuration from SB16 card */      if (sx_sb_irq < 0) {	 outportb(sx_sb_port+4, 0x80);	 cmask = inportb(sx_sb_port+5);	 if (cmask&1) sx_sb_irq = 2; /* or 9? */	 if (cmask&2) sx_sb_irq = 5;	 if (cmask&4) sx_sb_irq = 7;	 if (cmask&8) sx_sb_irq = 10;      }      if ((sx_sb_dma8 < 0) || (sx_sb_dma16 < 0)) {	 outportb(sx_sb_port+4, 0x81);	 cmask = inportb(sx_sb_port+5);	 if (sx_sb_dma8 < 0) {	    if (cmask&1) sx_sb_dma8 = 0;	    if (cmask&2) sx_sb_dma8 = 1;	    if (cmask&8) sx_sb_dma8 = 3;	 }	 if (sx_sb_dma16 < 0) {	    sx_sb_dma16 = sx_sb_dma8;	    if (cmask&0x20) sx_sb_dma16 = 5;	    if (cmask&0x40) sx_sb_dma16 = 6;	    if (cmask&0x80) sx_sb_dma16 = 7;	 }      }   }   /* if nothing else works */   if (sx_sb_irq < 0)      sx_sb_irq = 5;   if (sx_sb_dma8 < 0)      sx_sb_dma8 = 1;   if (sx_sb_dma16 < 0)      sx_sb_dma16 = 5;   /* figure out the hardware interrupt number */   sx_sb_int = _map_irq(sx_sb_irq);   /* what breed of SB? */   if (sx_sb_dsp_ver >= 0x400) {      msg = "SB 16";      max_freq = 45454;      default_freq = 22727;   }   else if (sx_sb_dsp_ver >= 0x300) {      msg = "SB Pro";      max_freq = 22727;      default_freq = 22727;   }   else if (sx_sb_dsp_ver >= 0x201) {      msg = "SB 2.0";      max_freq = 45454;      default_freq = 22727;   }   else if (sx_sb_dsp_ver >= 0x200) {      msg = "SB 1.5";      max_freq = 16129;      default_freq = 16129;   }   else {      msg = "SB 1.0";      max_freq = 16129;      default_freq = 16129;   }   /* set up the playback frequency */   if (sx_sb_freq <= 0)      sx_sb_freq = default_freq;#if 0   if (sx_sb_freq < 15000) {      sx_sb_freq = 11906;      sx_sb_dma_size = 128;   }   else if (MIN(sx_sb_freq, max_freq) < 20000) {      sx_sb_freq = 16129;      sx_sb_dma_size = 128;   }   else if (MIN(sx_sb_freq, max_freq) < 40000) {      sx_sb_freq = 22727;      sx_sb_dma_size = 256;   }   else {      sx_sb_freq = 45454;      sx_sb_dma_size = 512;   }#endif   if (sx_sb_dsp_ver <= 0x200)      sx_sb_dma_size *= 4;   sx_sb_dma_mix_size = sx_sb_dma_size;   /* can we handle 16 bit sound? */   if (sx_sb_dsp_ver >= 0x400) {       if (sx_sb_dma < 0)	 sx_sb_dma = sx_sb_dma16;      else	 sx_sb_dma16 = sx_sb_dma;      sx_sb_16bit = TRUE;      sx_sb_dma_size <<= 1;   }   else {       if (sx_sb_dma < 0)	 sx_sb_dma = sx_sb_dma8;      else	 sx_sb_dma8 = sx_sb_dma;      sx_sb_16bit = FALSE;   }      /* can we handle stereo? */   if (sx_sb_dsp_ver >= 0x300 && *stereo) {      sx_sb_dma_size <<= 1;      sx_sb_dma_mix_size <<= 1;      sx_sb_stereo = TRUE;   }   else {      sx_sb_stereo = FALSE;   }   *bits16 = sx_sb_16bit;   *stereo = sx_sb_stereo;      /* set up the card description */   sprintf(sx_sb_desc, "%s (%d hz) on port %X, using IRQ %d and DMA channel %d",			msg, sx_sb_freq, sx_sb_port, sx_sb_irq, sx_sb_dma);   return TRUE;}/* sx_sb_init: *  SB init routine: returns zero on success, -1 on failure. */int sx_sb_init (int *stereo, int *bits16, int *freq, int *dmamixsize){   sx_sb_dsp_ver = -1;      if (*dmamixsize < SB_DMA_BUFFER_SIZE)       *dmamixsize = SB_DMA_BUFFER_SIZE;   else if (*dmamixsize > 8191)       *dmamixsize = 8192;   sx_sb_dma_size = sx_sb_dma_mix_size = *dmamixsize;   if (*freq > 5000 && *freq <= 44100)       sx_sb_freq = *freq;   if (!sx_sb_detect (stereo, bits16))      return -1;   *dmamixsize = sx_sb_dma_mix_size;   mixbuffer = calloc(1, sx_sb_dma_mix_size * sizeof (short));   if (!mixbuffer)      return -1;   memset (mixbuffer, 0, sx_sb_dma_mix_size * sizeof (short));   _go32_dpmi_lock_data(mixbuffer, sx_sb_dma_mix_size*sizeof(short));   if (sx_sb_dsp_ver <= 0x200) {       /* two conventional mem buffers */      if ((_dma_allocate_mem(sx_sb_dma_size, &sx_sb_sel[0], &sx_sb_buf[0]) != 0) ||	  (_dma_allocate_mem(sx_sb_dma_size, &sx_sb_sel[1], &sx_sb_buf[1]) != 0))	 return -1;   }   else {                           /* auto-init dma, one big buffer */      if (_dma_allocate_mem(sx_sb_dma_size*2, &sx_sb_sel[0], &sx_sb_buf[0]) != 0)	 return -1;      sx_sb_sel[1] = sx_sb_sel[0];      sx_sb_buf[1] = sx_sb_buf[0] + sx_sb_dma_size;   }   sx_sb_lock_mem();#if 0   if (_mixer_init(sx_sb_dma_mix_size, sx_sb_freq, sx_sb_stereo, sx_sb_16bit, &digi_sb.voices) != 0)      return -1;#endif   sx_sb_mix_some_samples(sx_sb_buf[0], _dos_ds);   sx_sb_mix_some_samples(sx_sb_buf[1], _dos_ds);   _enable_irq(sx_sb_irq);   _install_irq(sx_sb_int, sx_sb_interrupt);   sx_sb_start();   sx_sb_in_use = TRUE;   return 0;}/* sx_sb_exit: *  SB driver cleanup routine, removes ints, stops dma, frees buffers, etc. */void sx_sb_exit (){   sx_sb_stop();   _remove_irq(sx_sb_int);   _restore_irq(sx_sb_irq);   __dpmi_free_dos_memory(sx_sb_sel[0]);   if (sx_sb_sel[1] != sx_sb_sel[0])      __dpmi_free_dos_memory(sx_sb_sel[1]);    free (mixbuffer);    mixbuffer = NULL;   sx_sb_hw_dsp_ver = sx_sb_dsp_ver = -1;   sx_sb_in_use = FALSE;}/* sx_sb_lock_mem: *  Locks all the memory touched by parts of the SB code that are executed *  in an interrupt context. */static void sx_sb_lock_mem(){   LOCK_VARIABLE(sx_sb_freq);   LOCK_VARIABLE(sx_sb_port);   LOCK_VARIABLE(sx_sb_dma);   LOCK_VARIABLE(sx_sb_irq);   LOCK_VARIABLE(sx_sb_int);   LOCK_VARIABLE(sx_sb_in_use);   LOCK_VARIABLE(sx_sb_16bit);   LOCK_VARIABLE(sx_sb_dsp_ver);   LOCK_VARIABLE(sx_sb_hw_dsp_ver);   LOCK_VARIABLE(sx_sb_dma_size);   LOCK_VARIABLE(sx_sb_dma_mix_size);   LOCK_VARIABLE(sx_sb_sel);   LOCK_VARIABLE(sx_sb_buf);   LOCK_VARIABLE(sx_sb_bufnum);   LOCK_VARIABLE(sx_sb_dma_count);   LOCK_VARIABLE(sx_sb_semaphore);   LOCK_FUNCTION(sx_sb_play_buffer);   LOCK_FUNCTION(sx_sb_interrupt);   LOCK_FUNCTION(sx_sb_mix_some_samples);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -