1 /* MikMod sound library
2 (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of
8 the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 /*==============================================================================
25 Driver for SoundBlaster/Pro/16/AWE32 under DOS
27 ==============================================================================*/
31 Written by Andrew Zabolotny <bit@eltech.ru>
48 #include "mikmod_internals.h"
52 static void SB_CommandLine(const CHAR *cmdline)
56 if ((ptr=MD_GetAtom("port",cmdline,0)) != NULL) {
57 sb.port = strtol(ptr, &end, 16);
60 if ((ptr=MD_GetAtom("irq",cmdline,0)) != NULL) {
61 sb.irq = strtol(ptr, &end, 10);
64 if ((ptr=MD_GetAtom("dma",cmdline,0)) != NULL) {
65 sb.dma8 = strtol(ptr, &end, 10);
68 if ((ptr=MD_GetAtom("hidma",cmdline,0)) != NULL) {
69 sb.dma16 = strtol(ptr, &end, 10);
74 static BOOL SB_IsThere(void)
79 static int SB_Init(void)
82 _mm_errno = MMERR_INVALID_DEVICE;
86 /* Adjust md_mode according to sound card capabilities */
87 if (!(sb.caps & SBMODE_STEREO))
88 md_mode &= ~DMODE_STEREO;
89 if (!(sb.caps & SBMODE_16BITS))
90 md_mode &= ~DMODE_16BITS;
92 if (md_mixfreq < 4000)
94 if (md_mode & DMODE_STEREO) {
95 if (md_mixfreq > sb.maxfreq_stereo)
96 md_mixfreq = sb.maxfreq_stereo;
98 if (md_mixfreq > sb.maxfreq_mono)
99 md_mixfreq = sb.maxfreq_mono;
105 static void SB_Exit(void)
111 /* The last buffer byte filled with sound */
112 static unsigned int buff_tail = 0;
114 static void SB_Callback(void)
116 unsigned int dma_size, dma_pos;
117 ULONG (*mixer)(SBYTE *buf, ULONG todo);
119 sb_query_dma(&dma_size, &dma_pos);
120 /* There isn't much sense in filling less than 256 bytes */
123 /* If nothing to mix, quit */
124 if (buff_tail == dma_pos)
127 if (Player_Paused_internal())
128 mixer = VC_SilenceBytes;
130 mixer = VC_WriteBytes;
132 /* If DMA pointer still didn't wrapped around ... */
133 if (dma_pos > buff_tail) {
134 buff_tail += mixer ((SBYTE *)(sb.dma_buff->linear + buff_tail), dma_pos - buff_tail);
135 /* If we arrived right to the DMA buffer end, jump to the beginning */
136 if (buff_tail >= dma_size)
139 /* If wrapped around, fill first to the end of buffer */
140 mixer ((SBYTE *)(sb.dma_buff->linear + buff_tail), dma_size - buff_tail);
141 /* Now fill from buffer beginning to current DMA pointer */
142 buff_tail = mixer ((SBYTE *)sb.dma_buff->linear, dma_pos);
146 static void SB_Update(void)
148 /* Do nothing: the real update is done during SB interrupts */
151 static int SB_PlayStart (void)
156 /* Enable speaker output */
159 /* Set our routine to be called during SB IRQs */
161 sb.timer_callback = SB_Callback;
163 /* Start cyclic DMA transfer */
164 if (!sb_start_dma(((md_mode & DMODE_16BITS) ? SBMODE_16BITS | SBMODE_SIGNED : 0) |
165 ((md_mode & DMODE_STEREO) ? SBMODE_STEREO : 0), md_mixfreq))
167 _mm_errno = MMERR_DOSSB_STARTDMA;
174 static int SB_Reset(void)
181 static void SB_PlayStop(void)
183 sb.timer_callback = NULL;
193 "Sound Blaster Orig/2.0/Pro/16 v1.0",
196 "port:c:220,230,240,250,260,270,280,32C,530,604,E80,F40,220:Sound Blaster base I/O port\n"
197 "irq:c:2,3,5,7,10,5:Sound Blaster IRQ\n"
198 "dma:c:0,1,3,1:Sound Blaster 8 bit DMA channel\n"
199 "hidma:c:5,6,7,5:Sound Blaster 16 bit DMA channel (SB16/AWE32 only)\n",
217 VC_VoiceSetFrequency,
218 VC_VoiceGetFrequency,
230 #include "mikmod_internals.h"