/*

Name:
DRV_SBP.C

Description:
Mikmod driver for output on Creative Labs Soundblasters, SB Pros,
and compatibles (through DSP)

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_SBPRO  = "Sound Blaster Pro not found.  Check your 'BLASTER' env. variable";
static CHAR *ERROR_DETECTING_SB  = "Sound Blaster not found.  Check your 'BLASTER' env. variable";


static BOOL SBPro_Detect(void)
{
   if(!SB_IsThere() || (sb_lodma==0xff) || (sb_ver<0x300 || sb_ver>=0x400)) return 0;
   return 1;
}


static BOOL SBMono_Detect(void)
{
   if(!SB_IsThere() || sb_ver>=0x300) return 0;
   return 1;
}


static BOOL SBPro_Init(void)
{
    if(!SB_IsThere() || (sb_ver<0x300 || sb_ver>=0x400))
    {   _mm_error = ERROR_DETECTING_SBPRO;
        return 1;
    }

    return SB_Init();
}


static BOOL SBMono_Init(void)
{
    if(!SB_IsThere() || sb_ver>=0x300)
    {   _mm_error = ERROR_DETECTING_SB;
        return 1;
    }

    return SB_Init();
}


static void SBPro_PlayStart(void)
{
    VC_PlayStart();

    MIrq_OnOff(sb_irq,1);

    if(sb_ver>=0x300)
    {   if(md_mode & DMODE_STEREO)
            SB_MixerStereo();
        else
            SB_MixerMono();
    }

    // clear the dma buffer

    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(0x40);
    SB_WriteDSP(SB_TIMECONSTANT);

    if(sb_ver<0x200)
    {   SB_WriteDSP(0x14);
        SB_WriteDSP(0xff);
        SB_WriteDSP(0xfe);
    } else if(sb_ver==0x200)
    {   SB_WriteDSP(0x48);
        SB_WriteDSP(0xff);
        SB_WriteDSP(0xfe);
        SB_WriteDSP(0x1c);
    } else
    {   SB_WriteDSP(0x48);
        SB_WriteDSP(0xff);
        SB_WriteDSP(0xfe);
        SB_WriteDSP(0x90);
    }
}


MDRIVER drv_sb =
{   NULL,
    "Soundblaster & compatibles",
    "MikMod Soundblaster Driver v3.0",
    SBMono_Detect,
    VC_SampleLoad,
    VC_SampleUnload,
    VC_SampleSpace,
    VC_SampleLength,
    SBMono_Init,
    SB_Exit,
    VC_SetNumChannels,
    SBPro_PlayStart,
    SB_PlayStop,
    SB_Update,
    VC_VoiceSetVolume,
    VC_VoiceSetFrequency,
    VC_VoiceSetPanning,
    VC_VoicePlay,
    VC_VoiceStop,
    VC_VoiceStopped,
    VC_VoiceReleaseSustain,
    VC_VoiceGetPosition,
    VC_RealVolume
};


MDRIVER drv_sbpro =
{   NULL,
    "Soundblaster Pro",
    "MikMod Soundblaster Pro Driver v3.0",
    SBPro_Detect,
    VC_SampleLoad,
    VC_SampleUnload,
    VC_SampleSpace,
    VC_SampleLength,
    SBPro_Init,
    SB_Exit,
    VC_SetNumChannels,
    SBPro_PlayStart,
    SB_PlayStop,
    SB_Update,
    VC_VoiceSetVolume,
    VC_VoiceSetFrequency,
    VC_VoiceSetPanning,
    VC_VoicePlay,
    VC_VoiceStop,
    VC_VoiceStopped,
    VC_VoiceReleaseSustain,
    VC_VoiceGetPosition,
    VC_RealVolume
};

