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 Windows Sound System under DOS
27 ==============================================================================*/
31 Written by Andrew Zabolotny <bit@eltech.ru>
48 #include "mikmod_internals.h"
52 static void WSS_CommandLine(const CHAR *cmdline)
56 if ((ptr=MD_GetAtom("port",cmdline,0)) != NULL) {
57 wss.port = strtol(ptr, &end, 16);
60 if ((ptr=MD_GetAtom("irq",cmdline,0)) != NULL) {
61 wss.irq = strtol(ptr, &end, 10);
64 if ((ptr=MD_GetAtom("dma",cmdline,0)) != NULL) {
65 wss.dma = strtol(ptr, &end, 10);
70 static BOOL WSS_IsThere(void)
75 static int WSS_Init(void)
78 _mm_errno = MMERR_INVALID_DEVICE;
82 /* Adjust mixing frequency according to card capabilities */
83 md_mixfreq = wss_adjust_freq(md_mixfreq);
88 static void WSS_Exit(void)
94 /* The last buffer byte filled with sound */
95 static unsigned int buff_tail = 0;
97 static void WSS_Callback(void)
99 unsigned int dma_size, dma_pos;
100 ULONG (*mixer)(SBYTE *buf, ULONG todo);
102 wss_query_dma(&dma_size, &dma_pos);
103 /* There isn't much sense in filling less than 256 bytes */
106 /* If nothing to mix, quit */
107 if (buff_tail == dma_pos)
110 if (Player_Paused_internal())
111 mixer = VC_SilenceBytes;
113 mixer = VC_WriteBytes;
115 /* If DMA pointer still didn't wrapped around ... */
116 if (dma_pos > buff_tail) {
117 buff_tail += mixer ((SBYTE *)(wss.dma_buff->linear + buff_tail), dma_pos - buff_tail);
118 /* If we arrived right to the DMA buffer end, jump to the beginning */
119 if (buff_tail >= dma_size)
122 /* If wrapped around, fill first to the end of buffer */
123 mixer ((SBYTE *)(wss.dma_buff->linear + buff_tail), dma_size - buff_tail);
124 /* Now fill from buffer beginning to current DMA pointer */
125 buff_tail = mixer ((SBYTE *)wss.dma_buff->linear, dma_pos);
129 static void WSS_Update(void)
131 /* Do nothing: the real update is done during SB interrupts */
134 static int WSS_PlayStart(void)
139 /* Set our routine to be called during WSS IRQs */
141 wss.timer_callback = WSS_Callback;
143 /* Start cyclic DMA transfer */
144 if (!wss_start_dma(((md_mode & DMODE_16BITS) ? WSSMODE_16BITS | WSSMODE_SIGNED : 0) |
145 ((md_mode & DMODE_STEREO) ? WSSMODE_STEREO : 0), md_mixfreq))
147 _mm_errno = MMERR_DOSWSS_STARTDMA;
151 /* Enable speaker output */
157 static int WSS_Reset(void)
164 static void WSS_PlayStop(void)
166 wss.timer_callback = NULL;
175 "Windows Sound System",
176 "Windows Sound System (CS423*,ESS*) v1.0",
179 "port:c:32C,530,604,E80,F40,530:Windows Sound System base I/O port\n"
180 "irq:c:2,3,5,7,10,5:Windows Sound System IRQ\n"
181 "dma:c:0,1,3,0:Windows Sound System DMA channel\n",
199 VC_VoiceSetFrequency,
200 VC_VoiceGetFrequency,
210 #else /* ifdef DRV_WSS */
212 #include "mikmod_internals.h"