/*
 * Soundblaster Emulation
 *
 * Copyright 2002 Christian Costa
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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
 */

#include "config.h"

#include "windef.h"
#include "dosexe.h"
#include "wine/debug.h"
#include "dsound.h"

WINE_DEFAULT_DEBUG_CHANNEL(sblaster);

/* Board Configuration */
/* FIXME: Should be in a config file */
#define SB_IRQ 5
#define SB_IRQ_PRI 11
#define SB_DMA 1

/* Soundblaster state */
static int SampleMode;         /* Mono / Stereo */
static int SampleRate;
static int SamplesCount;
static BYTE DSP_Command[256];  /* Store param numbers in bytes for each command */
static BYTE DSP_InBuffer[10];  /* Store DSP command bytes parameters from host */
static int InSize;             /* Nb of bytes in InBuffer */
static BYTE DSP_OutBuffer[10]; /* Store DSP information bytes to host */
static int OutSize;            /* Nb of bytes in InBuffer */
static int command;            /* Current command */
static int end_sound_loop = 0;
static int dma_enable = 0;

/* The maximum size of a dma transfer can be 65536 */
#define DMATRFSIZE 1024

/* DMA can perform 8 or 16-bit transfer */
static BYTE dma_buffer[DMATRFSIZE*2];

/* Direct Sound buffer config */
#define DSBUFLEN 4096 /* FIXME: Only this value seems to work */

/* Direct Sound playback stuff */
static HMODULE hmodule;
typedef HRESULT (WINAPI* fnDirectSoundCreate) (LPGUID,LPDIRECTSOUND*,LPUNKNOWN);
fnDirectSoundCreate lpDirectSoundCreate;
static LPDIRECTSOUND lpdsound;
static LPDIRECTSOUNDBUFFER lpdsbuf;
static DSBUFFERDESC buf_desc;
static WAVEFORMATEX wav_fmt;
static HANDLE SB_Thread;
static UINT buf_off;
extern HWND vga_hwnd;

/* SB_Poll performs DMA transfers and fills the Direct Sound Buffer */
static DWORD CALLBACK SB_Poll( void *dummy )
{
    HRESULT result;
    LPBYTE lpbuf1 = NULL;
    LPBYTE lpbuf2 = NULL;
    DWORD dwsize1 = 0;
    DWORD dwsize2 = 0;
    DWORD dwbyteswritten1 = 0;
    DWORD dwbyteswritten2 = 0;
    int size;

    /* FIXME: this loop must be improved */
    while(!end_sound_loop)
    {
        Sleep(10);

        if (dma_enable) {
            size = DMA_Transfer(SB_DMA,min(DMATRFSIZE,SamplesCount),dma_buffer);
        } else
            continue;

        result = IDirectSoundBuffer_Lock(lpdsbuf,buf_off,size,&lpbuf1,&dwsize1,&lpbuf2,&dwsize2,0);
        if (result != DS_OK) {
	  ERR("Unable to lock sound buffer !\n");
          continue;
        }

        dwbyteswritten1 = min(size,dwsize1);
        memcpy(lpbuf1,dma_buffer,dwbyteswritten1);
        if (size>dwsize1) {
            dwbyteswritten2 = min(size - dwbyteswritten1,dwsize2);
            memcpy(lpbuf2,dma_buffer+dwbyteswritten1,dwbyteswritten2);
        }
        buf_off = (buf_off + dwbyteswritten1 + dwbyteswritten2) % DSBUFLEN;

        result = IDirectSoundBuffer_Unlock(lpdsbuf,lpbuf1,dwbyteswritten1,lpbuf2,dwbyteswritten2);
        if (result!=DS_OK)
	    ERR("Unable to unlock sound buffer !\n");

        SamplesCount -= size;
        if (!SamplesCount) {
            DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL);
            dma_enable = 0;
        }
    }
    return 0;
}

BOOL SB_Init()
{
    HRESULT result;

    if (!lpdsound) {
        hmodule = LoadLibraryA("dsound.dll");
        if (!hmodule) {
            ERR("Can't load dsound.dll !\n");
            return 0;
        }
        lpDirectSoundCreate = (fnDirectSoundCreate)GetProcAddress(hmodule,"DirectSoundCreate");
        if (!lpDirectSoundCreate) {
            /* CloseHandle(hmodule); */
            ERR("Can't find DirectSoundCreate function !\n");
            return 0;
        }
        result = (*lpDirectSoundCreate)(NULL,&lpdsound,NULL);
        if (result != DS_OK) {
            ERR("Unable to initialize Sound Subsystem err = %lx !\n",result);
            return 0;
        }

        /* FIXME: To uncomment when :
           - SetCooperative level is correctly implemented
           - an always valid and non changing handle to a windows  (vga_hwnd) is available
             (this surely needs some work in vga.c)
        result = IDirectSound_SetCooperativeLevel(lpdsound,vga_hwnd,DSSCL_EXCLUSIVE|DSSCL_PRIORITY);
        if (result != DS_OK) {
            ERR("Can't set cooperative level !\n");
            return 0;
        }
        */

        /* Default format */
        wav_fmt.wFormatTag = WAVE_FORMAT_PCM;
        wav_fmt.nChannels = 1;
        wav_fmt.nSamplesPerSec = 22050;
        wav_fmt.nAvgBytesPerSec = 22050;
        wav_fmt.nBlockAlign = 1;
        wav_fmt.wBitsPerSample = 8;
        wav_fmt.cbSize = 0;

        memset(&buf_desc,0,sizeof(DSBUFFERDESC));
        buf_desc.dwSize = sizeof(DSBUFFERDESC);
        buf_desc.dwBufferBytes = DSBUFLEN;
        buf_desc.lpwfxFormat = &wav_fmt;
        result = IDirectSound_CreateSoundBuffer(lpdsound,&buf_desc,&lpdsbuf,NULL);
        if (result != DS_OK) {
            ERR("Can't create sound buffer !\n");
            return 0;
        }

        result = IDirectSoundBuffer_Play(lpdsbuf,0, 0, DSBPLAY_LOOPING);
        if (result != DS_OK) {
            ERR("Can't start playing !\n");
            return 0;
        }

        buf_off = 0;
        end_sound_loop = 0;
        SB_Thread = CreateThread(NULL, 0, SB_Poll, NULL, 0, NULL);
        TRACE("thread\n");
        if (!SB_Thread) {
            ERR("Can't create thread !\n");
            return 0;
        }
    }
    return 1;
}

void SB_Reset()
{
    int i;

    for(i=0;i<256;i++)
        DSP_Command[i]=0;

    /* Set Time Constant */
    DSP_Command[0x40]=1;
    /* Generate IRQ */
    DSP_Command[0xF2]=0;
    /* DMA DAC 8-bits */
    DSP_Command[0x14]=2;
    /* Generic DAC/ADC DMA (16-bit, 8-bit) */
    for(i=0xB0;i<=0xCF;i++)
        DSP_Command[i]=3;
    /* DSP Indentification */
    DSP_Command[0xE0]=1;

    /* Clear command and input buffer */
    command = -1;
    InSize = 0;

    /* Put a garbage value in the output buffer */
    OutSize = 1;
    if (SB_Init())
        /* All right, let's put the magic value for autodetection */
        DSP_OutBuffer[0] = 0xaa;
    else
        /* Something is wrong, put 0 to failed audetection */
        DSP_OutBuffer[0] = 0x00;
}

/* Find a standard sampling rate for DirectSound */
int SB_StdSampleRate(int SampleRate)
{
  if (SampleRate>((44100+48000)/2)) return 48000;
  if (SampleRate>((32000+44100)/2)) return 44100;
  if (SampleRate>((24000+32000)/2)) return 32000;
  if (SampleRate>((22050+24000)/2)) return 24000;
  if (SampleRate>((16000+22050)/2)) return 22050;
  if (SampleRate>((12000+16000)/2)) return 16000;
  if (SampleRate>((11025+12000)/2)) return 12000;
  if (SampleRate>((8000+11025)/2))  return 11025;
  return 8000;
}

void SB_ioport_out( WORD port, BYTE val )
{
    switch(port)
    {
    /* DSP - Reset */
    case 0x226:
        TRACE("Resetting DSP.\n");
        SB_Reset();
        break;
    /* DSP - Write Data or Command */
    case 0x22c:
        TRACE("val=%x\n",val);
        if (command == -1) {
          /* Clear input buffer and set the current command */
          command = val;
          InSize = 0;
        }
        if (InSize!=DSP_Command[command])
	   /* Fill the input buffer the command parameters if any */
           DSP_InBuffer[InSize++]=val;
        else {
	    /* Process command */
            switch(command)
            {
            case 0x10: /* SB */
                FIXME("Direct DAC (8-bit) - Not Implemented\n");
                break;
            case 0x14: /* SB */
                SamplesCount = DSP_InBuffer[1]+(val<<8)+1;
                TRACE("DMA DAC (8-bit) for %x samples\n",SamplesCount);
                dma_enable = 1;
                break;
            case 0x20:
                FIXME("Direct ADC (8-bit) - Not Implemented\n");
                break;
            case 0x24: /* SB */
                FIXME("DMA ADC (8-bit) - Not Implemented\n");
                break;
            case 0x40: /* SB */
                SampleRate = 1000000/(256-val);
                TRACE("Set Time Constant (%d <-> %d Hz => %d Hz)\n",DSP_InBuffer[0],
                    SampleRate,SB_StdSampleRate(SampleRate));
                SampleRate = SB_StdSampleRate(SampleRate);
                wav_fmt.nSamplesPerSec = SampleRate;
                wav_fmt.nAvgBytesPerSec = SampleRate;
                IDirectSoundBuffer_SetFormat(lpdsbuf,&wav_fmt);
                break;
	    /* case 0xBX/0xCX -> See below */
            case 0xD0: /* SB */
                TRACE("Halt DMA operation (8-bit)\n");
                dma_enable = 0;
                break;
            case 0xD1: /* SB */
                FIXME("Enable Speaker - Not Implemented\n");
                break;
            case 0xD3: /* SB */
                FIXME("Disable Speaker - Not Implemented\n");
                break;
            case 0xD4: /* SB */
                FIXME("Continue DMA operation (8-bit) - Not Implemented\n");
                break;
            case 0xD8: /* SB */
                FIXME("Speaker Status - Not Implemented\n");
                break;
	    case 0xE0: /* SB 2.0 */
                TRACE("DSP Identification\n");
                DSP_OutBuffer[OutSize++] = ~val;
                break;
            case 0xE1: /* SB */
               TRACE("DSP Version\n");
               OutSize=2;
               DSP_OutBuffer[0]=0; /* returns version 1.0 */
               DSP_OutBuffer[1]=1;
                break;
            case 0xF2: /* SB */
                TRACE("IRQ Request (8-bit)\n");
                DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL);
                break;
            default:
	      if (((command&0xF0)==0xB0)||((DSP_InBuffer[0]&0xF0)==0xC0)) {
		    /* SB16 */
                    FIXME("Generic DAC/ADC DMA (16-bit, 8-bit) - %d % d\n",command,DSP_InBuffer[1]);
                    if (command&0x02)
		        FIXME("Generic DAC/ADC fifo mode not supported\n");
                    if (command&0x04)
		        FIXME("Generic DAC/ADC autoinit dma mode not supported\n");
                    if (command&0x08)
		        FIXME("Generic DAC/ADC adc mode not supported\n");
                    switch(command>>4) {
                    case 0xB:
		        FIXME("Generic DAC/ADC 8-bit not supported\n");
                        SampleMode = 0;
                        break;
                    case 0xC:
		        FIXME("Generic DAC/ADC 16-bit not supported\n");
                        SampleMode = 1;
                        break;
                    default:
		        ERR("Generic DAC/ADC resolution unknown\n");
                        break;
                    }
                    if (DSP_InBuffer[1]&0x010)
		        FIXME("Generic DAC/ADC signed sample mode not supported\n");
                    if (DSP_InBuffer[1]&0x020)
		        FIXME("Generic DAC/ADC stereo mode not supported\n");
                    SamplesCount = DSP_InBuffer[2]+(val<<8)+1;
                    TRACE("Generic DMA for %x samples\n",SamplesCount);
                    dma_enable = 1;
	        }
                else
                    FIXME("DSP command %x not supported\n",val);
            }
            /* Empty the input buffer and end the command */
            InSize = 0;
            command = -1;
        }
    }
}

BYTE SB_ioport_in( WORD port )
{
    BYTE res = 0;

    switch(port)
    {
    /* DSP Read Data */
    case 0x22a:
        /* Value in the read buffer */
      if (OutSize)
          res = DSP_OutBuffer[--OutSize];
      else
	  /* return the last byte */
	  res = DSP_OutBuffer[0];
      break;
    /* DSP - Write Buffer Status */
    case 0x22c:
        /* DSP always ready for writing */
        res = 0x00;
        break;
    /* DSP - Data Available Status */
    /* DSP - IRQ Acknowledge, 8-bit */
    case 0x22e:
        /* DSP data availability check */
        if (OutSize)
            res = 0x80;
        else
	    res = 0x00;
        break;
    }
    return res;
}
