/*

Name:
DRV_SB16.C

Description:
Mikmod driver for output on Creative Labs Soundblaster 16's and
compatables.

Portability:

MSDOS:  BC(y)   Watcom(y)   DJGPP(y)
Win95:  n
Os2:    n
Linux:  n

(y) - yes
(n) - no (not possible or not useful)
(?) - may be possible, but not tested

*/


#include <dos.h>
#include <conio.h>
#ifndef __DJGPP__
#include <mem.h>
#endif

#include "mikmod.h"
#include "mirq.h"
#include "sb.h"


static CHAR *ERROR_DETECTING_SB16  = "Sound Blaster 16 not found.  Check your 'BLASTER' env. variable";


static BOOL SB16_Detect(void)
{
   if(!SB_IsThere() || sb_ver<0x400) return 0;
   return 1;
}


static BOOL SB16_Init(void)
{
    if(!SB_IsThere() || sb_lodma==0xff || sb_ver<0x400)
    {   _mm_error = ERROR_DETECTING_SB16;
        return 1;
    }

    return SB_Init();
}


static void SB16_PlayStart(void)
{
    VC_PlayStart();

    MIrq_OnOff(sb_irq,1);

    // clear the dma buffer

    SB_MixerStereo();
    VC_SilenceBytes(SB_DMABUF,md_dmabufsize);
    MDma_Commit(SB_DMAMEM,0,md_dmabufsize);

    if(!MDma_Start(sb_dma,SB_DMAMEM,md_dmabufsize,INDEF_WRITE)) return;

    SB_SpeakerOn();
    SB_WriteDSP(0x41);

    printf("mdmix = %d\n",md_mixfreq);
    SB_WriteDSP(md_mixfreq>>8);
    SB_WriteDSP(md_mixfreq&0xff);

    if(md_mode & DMODE_16BITS)
    {   SB_WriteDSP(0xb6);
        SB_WriteDSP((md_mode & DMODE_STEREO) ? 0x30 : 0x10);
    } else
    {   SB_WriteDSP(0xc6);
        SB_WriteDSP((md_mode & DMODE_STEREO) ? 0x20 : 0x00);
    }

    SB_WriteDSP(0xff);
    SB_WriteDSP(0xef);
}


MDRIVER drv_sb16 =
{   NULL,
    "Soundblaster 16",
    "MikMod Soundblaster 16 Driver v3.0",
    SB16_Detect,
    VC_SampleLoad,
    VC_SampleUnload,
    VC_SampleSpace,
    VC_SampleLength,
    SB16_Init,
    SB_Exit,
    VC_SetNumChannels,
    SB16_PlayStart,
    SB_PlayStop,
    SB_Update,
    VC_VoiceSetVolume,
    VC_VoiceSetFrequency,
    VC_VoiceSetPanning,
    VC_VoicePlay,
    VC_VoiceStop,
    VC_VoiceStopped,
    VC_VoiceReleaseSustain,
    VC_VoiceGetPosition,
    VC_RealVolume
};

