X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=libs%2Fmikmod%2Fdrivers%2Fdrv_wss.c;fp=libs%2Fmikmod%2Fdrivers%2Fdrv_wss.c;h=a89d5ecb4b0572bcf811072d3d8fec080c413421;hp=0000000000000000000000000000000000000000;hb=cf94899f4f4d8535074db6421245b973d2fcde8c;hpb=8024ae981f39d370af5cceb3cb97f62820b0a120 diff --git a/libs/mikmod/drivers/drv_wss.c b/libs/mikmod/drivers/drv_wss.c new file mode 100644 index 0000000..a89d5ec --- /dev/null +++ b/libs/mikmod/drivers/drv_wss.c @@ -0,0 +1,217 @@ +/* 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$ + + Driver for Windows Sound System under DOS + +==============================================================================*/ + +/* + + Written by Andrew Zabolotny + +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef DRV_WSS + +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif + +#include "mikmod_internals.h" + +#include "doswss.h" + +static void WSS_CommandLine(const CHAR *cmdline) +{ + char *ptr, *end; + + if ((ptr=MD_GetAtom("port",cmdline,0)) != NULL) { + wss.port = strtol(ptr, &end, 16); + MikMod_free(ptr); + } + if ((ptr=MD_GetAtom("irq",cmdline,0)) != NULL) { + wss.irq = strtol(ptr, &end, 10); + MikMod_free(ptr); + } + if ((ptr=MD_GetAtom("dma",cmdline,0)) != NULL) { + wss.dma = strtol(ptr, &end, 10); + MikMod_free(ptr); + } +} + +static BOOL WSS_IsThere(void) +{ + return wss_detect(); +} + +static int WSS_Init(void) +{ + if (!wss_open()) { + _mm_errno = MMERR_INVALID_DEVICE; + return 1; + } + + /* Adjust mixing frequency according to card capabilities */ + md_mixfreq = wss_adjust_freq(md_mixfreq); + + return VC_Init(); +} + +static void WSS_Exit(void) +{ + VC_Exit(); + wss_close(); +} + +/* The last buffer byte filled with sound */ +static unsigned int buff_tail = 0; + +static void WSS_Callback(void) +{ + unsigned int dma_size, dma_pos; + ULONG (*mixer)(SBYTE *buf, ULONG todo); + + wss_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 ((SBYTE *)(wss.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 ((SBYTE *)(wss.dma_buff->linear + buff_tail), dma_size - buff_tail); + /* Now fill from buffer beginning to current DMA pointer */ + buff_tail = mixer ((SBYTE *)wss.dma_buff->linear, dma_pos); + } +} + +static void WSS_Update(void) +{ + /* Do nothing: the real update is done during SB interrupts */ +} + +static int WSS_PlayStart(void) +{ + if (VC_PlayStart()) + return 1; + + /* Set our routine to be called during WSS IRQs */ + buff_tail = 0; + wss.timer_callback = WSS_Callback; + + /* Start cyclic DMA transfer */ + if (!wss_start_dma(((md_mode & DMODE_16BITS) ? WSSMODE_16BITS | WSSMODE_SIGNED : 0) | + ((md_mode & DMODE_STEREO) ? WSSMODE_STEREO : 0), md_mixfreq)) + { + _mm_errno = MMERR_DOSWSS_STARTDMA; + return 1; + } + + /* Enable speaker output */ + wss_output(TRUE); + + return 0; +} + +static int WSS_Reset(void) +{ + wss_reset(); + VC_Exit(); + return VC_Init(); +} + +static void WSS_PlayStop(void) +{ + wss.timer_callback = NULL; + wss_output(FALSE); + wss_stop_dma(); + VC_PlayStop(); +} + +MDRIVER drv_wss = +{ + NULL, + "Windows Sound System", + "Windows Sound System (CS423*,ESS*) v1.0", + 0, 255, + "wss", + "port:c:32C,530,604,E80,F40,530:Windows Sound System base I/O port\n" + "irq:c:2,3,5,7,10,5:Windows Sound System IRQ\n" + "dma:c:0,1,3,0:Windows Sound System DMA channel\n", + + WSS_CommandLine, + WSS_IsThere, + VC_SampleLoad, + VC_SampleUnload, + VC_SampleSpace, + VC_SampleLength, + WSS_Init, + WSS_Exit, + WSS_Reset, + VC_SetNumVoices, + WSS_PlayStart, + WSS_PlayStop, + WSS_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 /* ifdef DRV_WSS */ + +#include "mikmod_internals.h" +MISSING(drv_wss); + +#endif + +/* ex:set ts=4: */