📄 drv_sb.c
字号:
/* MikMod sound library (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for complete list. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//*============================================================================== $Id: drv_sb.c,v 1.4 2004/02/10 17:52:18 raph Exp $ Driver for SoundBlaster/Pro/16/AWE32 under DOS==============================================================================*//* Written by Andrew Zabolotny <bit@eltech.ru>*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#ifdef DRV_SB#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#include "mikmod_internals.h"#include "dossb.h"static void SB_CommandLine(CHAR *cmdline){ char *ptr, *end; if ((ptr=MD_GetAtom("port",cmdline,0))) { sb.port = strtol(ptr, &end, 16); free(ptr); } if ((ptr=MD_GetAtom("irq",cmdline,0))) { sb.irq = strtol(ptr, &end, 10); free(ptr); } if ((ptr=MD_GetAtom("dma",cmdline,0))) { sb.dma8 = strtol(ptr, &end, 10); free(ptr); } if ((ptr=MD_GetAtom("hidma",cmdline,0))) { sb.dma16 = strtol(ptr, &end, 10); free(ptr); }}static BOOL SB_IsThere(void){ return sb_detect();}static BOOL SB_Init(void){ if (!sb_open()) { _mm_errno = MMERR_INVALID_DEVICE; return 1; } /* Adjust md_mode according to sound card capabilities */ if (!(sb.caps & SBMODE_STEREO)) md_mode &= ~DMODE_STEREO; if (!(sb.caps & SBMODE_16BITS)) md_mode &= ~DMODE_16BITS; if (md_mixfreq < 4000) md_mixfreq = 4000; if (md_mode & DMODE_STEREO) { if (md_mixfreq > sb.maxfreq_stereo) md_mixfreq = sb.maxfreq_stereo; } else { if (md_mixfreq > sb.maxfreq_mono) md_mixfreq = sb.maxfreq_mono; } return VC_Init();}static void SB_Exit(void){ VC_Exit(); sb_close();}/* The last buffer byte filled with sound */static unsigned int buff_tail = 0;static void SB_Callback(void){ unsigned int dma_size, dma_pos; ULONG (*mixer)(SBYTE *buf, ULONG todo); sb_query_dma(&dma_size, &dma_pos); /* There isn't much sense in filling less than 256 bytes */ dma_pos &= ~255; /* If nothing to mix, quit */ if (buff_tail == dma_pos) return; if (Player_Paused_internal()) mixer = VC_SilenceBytes; else mixer = VC_WriteBytes; /* If DMA pointer still didn't wrapped around ... */ if (dma_pos > buff_tail) { buff_tail += mixer (sb.dma_buff->linear + buff_tail, dma_pos - buff_tail); /* If we arrived right to the DMA buffer end, jump to the beginning */ if (buff_tail >= dma_size) buff_tail = 0; } else { /* If wrapped around, fill first to the end of buffer */ mixer (sb.dma_buff->linear + buff_tail, dma_size - buff_tail); /* Now fill from buffer beginning to current DMA pointer */ buff_tail = mixer (sb.dma_buff->linear, dma_pos); }}static void SB_Update(void){ /* Do nothing: the real update is done during SB interrupts */}static BOOL SB_PlayStart (void){ if (VC_PlayStart()) return 1; /* Enable speaker output */ sb_output(TRUE); /* Set our routine to be called during SB IRQs */ buff_tail = 0; sb.timer_callback = SB_Callback; /* Start cyclic DMA transfer */ if (!sb_start_dma(((md_mode & DMODE_16BITS) ? SBMODE_16BITS | SBMODE_SIGNED : 0) | ((md_mode & DMODE_STEREO) ? SBMODE_STEREO : 0), md_mixfreq)) { _mm_errno = MMERR_DOSSB_STARTDMA; return 1; } return 0;}static BOOL SB_Reset(void){ sb_reset(); VC_Exit(); return VC_Init();}static void SB_PlayStop(void){ sb.timer_callback = NULL; sb_output(FALSE); sb_stop_dma(); VC_PlayStop();}MDRIVER drv_sb ={ NULL, "Sound Blaster", "Sound Blaster Orig/2.0/Pro/16 v1.0", 0, 255, "sb", "port:c:220,230,240,250,260,270,280,32C,530,604,E80,F40,220:Sound Blaster base I/O port\n" "irq:c:2,3,5,7,10,5:Sound Blaster IRQ\n" "dma:c:0,1,3,1:Sound Blaster 8 bit DMA channel\n" "hidma:c:5,6,7,5:Sound Blaster 16 bit DMA channel (SB16/AWE32 only)\n", SB_CommandLine, SB_IsThere, VC_SampleLoad, VC_SampleUnload, VC_SampleSpace, VC_SampleLength, SB_Init, SB_Exit, SB_Reset, VC_SetNumVoices, SB_PlayStart, SB_PlayStop, SB_Update, NULL, VC_VoiceSetVolume, VC_VoiceGetVolume, VC_VoiceSetFrequency, VC_VoiceGetFrequency, VC_VoiceSetPanning, VC_VoiceGetPanning, VC_VoicePlay, VC_VoiceStop, VC_VoiceStopped, VC_VoiceGetPosition, VC_VoiceRealVolume};#else // DRV_SBMISSING(drv_sb);#endif/* ex:set ts=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -