/*
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "dosexe.h"
#include "wine/debug.h"
#include "wingdi.h"
#include "mmsystem.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 BOOL end_sound_loop = FALSE;
static BOOL dma_enable = FALSE;

/* 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 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,(LPVOID *)&lpbuf1,&dwsize1,(LPVOID *)&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 = FALSE;
        }
    }
    return 0;
}

static BOOL SB_Init(void)
{
    HRESULT result;

    if (!lpdsound) {
        result = DirectSoundCreate(NULL,&lpdsound,NULL);
        if (result != DS_OK) {
            ERR("Unable to initialize Sound Subsystem err = %x !\n",result);
            return FALSE;
        }

        /* 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 FALSE;
        }
        */

        /* 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 FALSE;
        }

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

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

static void SB_Reset(void)
{
    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 Identification */
    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 autodetection */
        DSP_OutBuffer[0] = 0x00;
}

/* Find a standard sampling rate for DirectSound */
static 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 = TRUE;
                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 = FALSE;
                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 = TRUE;
	        }
                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;
}
