/*
 * DMA 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"

WINE_DEFAULT_DEBUG_CHANNEL(dma);

/* Internal registers of the 2 DMA chips wich control 8 DMA channels */
static DWORD DMA_BaseAddress[8];
static WORD  DMA_ByteCount[8];
static DWORD DMA_CurrentBaseAddress[8];
static WORD  DMA_CurrentByteCount[8];
static BYTE  DMA_Command[8];
static BYTE  DMA_Mask[2]={0x0F,0x0F};
static BYTE  DMA_Status[2]={0x00,0x00};
static BOOL  DMA_Toggle[2]={FALSE,FALSE};

/*
 * DMA_Transfer : Try to perform a transfer of reqlen elements (8 or 16 bits)
 * on the specified channel and return the elements transferred
 */
int DMA_Transfer(int channel,int reqlen,void* buffer)
{
    int i,size,ret=0;
    int opmode,increment,autoinit,trmode,dmachip;
    int regmode = DMA_Command[channel];
    char *p,*dmabuf;

    dmabuf = buffer;
    dmachip = (channel<4) ? 0 : 1;

    TRACE("DMA_Command = %x reqlen=%d\n",regmode,reqlen);

    /* Exit if channel is masked */
    if (DMA_Mask[dmachip]&(1<<(channel&3)))
        return 0;

    opmode = (regmode & 0xC0) >> 6;
    increment = !(regmode & 0x20);
    autoinit = regmode & 0x10;
    trmode = (regmode & 0x0C) >> 2;

    /* Transfer size : 8 bits for channels 0..3, 16 bits for channels 4..7 */
    size = (channel<4) ? 1 : 2;

    /* Process operating mode */
    switch(opmode)
    {
    case 0:
        /* Request mode */
        FIXME("Request Mode - Not Implemented\n");
        return 0;
    case 1:
        /* Single Mode */
        break;
    case 2:
        /* Request mode */
        FIXME("Block Mode - Not Implemented\n");
        return 0;
    case 3:
        /* Cascade Mode */
        ERR("Cascade Mode should not be used by regular apps\n");
        return 0;
    }

    /* Perform one the 4 transfer modes */
    if (trmode == 4) {
        /* Illegal */
        ERR("DMA Transfer Type Illegal\n");
        return 0;
    }

    ret = min(DMA_CurrentByteCount[channel],reqlen);

    /* Update DMA registers */
    DMA_CurrentByteCount[channel]-=ret;
    if (increment)
        DMA_CurrentBaseAddress[channel] += ret * size;
    else
        DMA_CurrentBaseAddress[channel] -= ret * size;

    switch(trmode)
    {
    case 0:
        /* Verification (no real transfer)*/
        TRACE("Verification DMA operation\n");
        break;
    case 1:
        /* Write */
        TRACE("Perform Write transfer of %d bytes at %x with count %x\n",ret,
            DMA_CurrentBaseAddress[channel],DMA_CurrentByteCount[channel]);
        if (increment)
            memcpy((void*)DMA_CurrentBaseAddress[channel],dmabuf,ret*size);
        else
            for(i=0,p=(char*)DMA_CurrentBaseAddress[channel];i<ret*size;i++)
                /* FIXME: possible endianness issue for 16 bits DMA */
                *(p-i) = dmabuf[i];
        break;
    case 2:
        /* Read */
        TRACE("Perform Read transfer of %d bytes at %x with count %x\n",ret,
            DMA_CurrentBaseAddress[channel],DMA_CurrentByteCount[channel]);
        if (increment)
            memcpy(dmabuf,(void*)DMA_CurrentBaseAddress[channel],ret*size);
        else
            for(i=0,p=(char*)DMA_CurrentBaseAddress[channel];i<ret*size;i++)
                /* FIXME: possible endianness issue for 16 bits DMA */
                dmabuf[i] = *(p-i);
        break;
    }

    /* Check for end of transfer */
    if (DMA_CurrentByteCount[channel]==0) {
        TRACE("DMA buffer empty\n");

        /* Update status register of the DMA chip corresponding to the channel */
        DMA_Status[dmachip] |= 1 << (channel & 0x3); /* Mark transfer as finished */
        DMA_Status[dmachip] &= ~(1 << ((channel & 0x3) + 4)); /* Reset soft request if any */

        if (autoinit) {
            /* Reload Current* register to their initial values */
            DMA_CurrentBaseAddress[channel] = DMA_BaseAddress[channel];
            DMA_CurrentByteCount[channel] = DMA_ByteCount[channel];
        }
    }

    return ret;
}


void DMA_ioport_out( WORD port, BYTE val )
{
    int channel,dmachip;

    switch(port)
    {
    case 0x00:
    case 0x02:
    case 0x04:
    case 0x06:
    case 0xC0:
    case 0xC4:
    case 0xC8:
    case 0xCC:
        /* Base Address*/
        channel = (port&0xC0)?((port-0xC0)>>2):(port>>1);
        dmachip = (channel<4) ? 0 : 1;
        if (!DMA_Toggle[dmachip])
            DMA_BaseAddress[channel]=(DMA_BaseAddress[channel] & ~0xFF)|(val & 0xFF);
        else {
            DMA_BaseAddress[channel]=(DMA_BaseAddress[channel] & (~(0xFF << 8)))|((val & 0xFF) << 8);
            DMA_CurrentBaseAddress[channel] = DMA_BaseAddress[channel];
            TRACE("Write Base Address = %x\n",DMA_BaseAddress[channel]);
        }
        DMA_Toggle[dmachip] = !DMA_Toggle[dmachip];
        break;

    case 0x01:
    case 0x03:
    case 0x05:
    case 0x07:
    case 0xC2:
    case 0xC6:
    case 0xCA:
    case 0xCE:
        /* Count*/
        channel = ((port-1)&0xC0)?(((port-1)-0xC0)>>2):(port>>1);
        dmachip = (channel<4) ? 0 : 1;
        if (!DMA_Toggle[dmachip])
            DMA_ByteCount[channel]=(DMA_ByteCount[channel] & ~0xFF)|((val+1) & 0xFF);
        else {
            DMA_ByteCount[channel]=(DMA_ByteCount[channel] & (~(0xFF << 8)))|(((val+1) & 0xFF) << 8);
            DMA_CurrentByteCount[channel] = DMA_ByteCount[channel];
            TRACE("Write Count = %x.\n",DMA_ByteCount[channel]);
        }
        DMA_Toggle[dmachip] = !DMA_Toggle[dmachip];
        break;

    /* Low Page Base Address */
    case 0x87: DMA_BaseAddress[0]=(DMA_BaseAddress[0] & (~0xFF << 16))|((val & 0xFF) << 16); break;
    case 0x83: DMA_BaseAddress[1]=(DMA_BaseAddress[1] & (~0xFF << 16))|((val & 0xFF) << 16); break;
    case 0x81: DMA_BaseAddress[2]=(DMA_BaseAddress[2] & (~0xFF << 16))|((val & 0xFF) << 16); break;
    case 0x82: DMA_BaseAddress[3]=(DMA_BaseAddress[3] & (~0xFF << 16))|((val & 0xFF) << 16); break;
    case 0x8B: DMA_BaseAddress[5]=(DMA_BaseAddress[5] & (~0xFF << 16))|((val & 0xFF) << 16); break;
    case 0x89: DMA_BaseAddress[6]=(DMA_BaseAddress[6] & (~0xFF << 16))|((val & 0xFF) << 16); break;
    case 0x8A: DMA_BaseAddress[7]=(DMA_BaseAddress[7] & (~0xFF << 16))|((val & 0xFF) << 16); break;

    /* Low Page Base Address (only 4 lower bits are significant) */
    case 0x487: DMA_BaseAddress[0]=(DMA_BaseAddress[0] & (~0xFF << 24))|((val & 0x0F) << 24); break;
    case 0x483: DMA_BaseAddress[1]=(DMA_BaseAddress[1] & (~0xFF << 24))|((val & 0x0F) << 24); break;
    case 0x481: DMA_BaseAddress[2]=(DMA_BaseAddress[2] & (~0xFF << 24))|((val & 0x0F) << 24); break;
    case 0x482: DMA_BaseAddress[3]=(DMA_BaseAddress[3] & (~0xFF << 24))|((val & 0x0F) << 24); break;
    case 0x48B: DMA_BaseAddress[5]=(DMA_BaseAddress[5] & (~0xFF << 24))|((val & 0x0F) << 24); break;
    case 0x489: DMA_BaseAddress[6]=(DMA_BaseAddress[6] & (~0xFF << 24))|((val & 0x0F) << 24); break;
    case 0x48A: DMA_BaseAddress[7]=(DMA_BaseAddress[7] & (~0xFF << 24))|((val & 0x0F) << 24); break;

    case 0x08:
    case 0xD0:
        /* Command */
        FIXME("Write Command (%x) - Not Implemented\n",val);
        break;

    case 0x0B:
    case 0xD6:
        /* Mode */
        TRACE("Write Mode (%x)\n",val);
        DMA_Command[((port==0xD6)?4:0)+(val&0x3)]=val;
        switch(val>>6)
        {
        case 0:
            /* Request mode */
            FIXME("Request Mode - Not Implemented\n");
            break;
        case 1:
            /* Single Mode */
            break;
        case 2:
            /* Block mode */
            FIXME("Block Mode - Not Implemented\n");
            break;
        case 3:
            /* Cascade Mode */
            ERR("Cascade Mode should not be used by regular apps\n");
            break;
        }
        break;

    case 0x0A:
    case 0xD4:
        /* Write Single Mask Bit */
        TRACE("Write Single Mask Bit (%x)\n",val);
        dmachip = (port==0x0A) ? 0 : 1;
        if (val&4)
            DMA_Mask[dmachip] |= 1<<(val&3);
        else
            DMA_Mask[dmachip] &= ~(1<<(val&3));
        break;

    case 0x0F:
    case 0xDE:
        /* Write All Mask Bits (only 4 lower bits are significant */
        FIXME("Write All Mask Bits (%x)\n",val);
        dmachip = (port==0x0F) ? 0 : 1;
        DMA_Mask[dmachip] = val & 0x0F;
        break;

    case 0x09:
    case 0xD2:
        /* Software DRQx Request */
        FIXME("Software DRQx Request (%x) - Not Implemented\n",val);
        break;

    case 0x0C:
    case 0xD8:
        /* Reset DMA Pointer Flip-Flop */
        TRACE("Reset Flip-Flop\n");
        DMA_Toggle[port==0xD8]=FALSE;
        break;

    case 0x0D:
    case 0xDA:
        /* Master Reset */
        TRACE("Master Reset\n");
        dmachip = (port==0x0D) ? 0 : 1;
        /* Reset DMA Pointer Flip-Flop */
        DMA_Toggle[dmachip]=FALSE;
        /* Mask all channels */
        DMA_Mask[dmachip] = 0x0F;
        break;

    case 0x0E:
    case 0xDC:
        /* Reset Mask Register */
        FIXME("Reset Mask Register\n");
        dmachip = (port==0x0E) ? 0 : 1;
        /* Unmask all channels */
        DMA_Mask[dmachip] = 0x00;
        break;
    }
}

BYTE DMA_ioport_in( WORD port )
{
    int channel,dmachip;
    BYTE res = 0;

    switch(port)
    {
    case 0x00:
    case 0x02:
    case 0x04:
    case 0x06:
    case 0xC0:
    case 0xC4:
    case 0xC8:
    case 0xCC:
        /* Base Address*/
        channel = (port&0xC0)?((port-0xC0)>>2):(port>>1);
        dmachip = (channel<4) ? 0 : 1;
        if (!DMA_Toggle[dmachip])
            res = DMA_CurrentBaseAddress[channel] & 0xFF;
        else {
            res = (DMA_CurrentBaseAddress[channel] & (0xFF << 8))>>8;
            TRACE("Read Current Base Address = %x\n",DMA_CurrentBaseAddress[channel]);
        }
        DMA_Toggle[dmachip] = !DMA_Toggle[dmachip];
        break;

    case 0x01:
    case 0x03:
    case 0x05:
    case 0x07:
    case 0xC2:
    case 0xC6:
    case 0xCA:
    case 0xCE:
        /* Count*/
        channel = ((port-1)&0xC0)?(((port-1)-0xC0)>>2):(port>>1);
        dmachip = (channel<4) ? 0 : 1;
        if (!DMA_Toggle[dmachip])
            res = DMA_CurrentByteCount[channel] & 0xFF;
        else {
            res = (DMA_CurrentByteCount[channel] & (0xFF << 8))>>8;
            TRACE("Read Current Count = %x.\n",DMA_CurrentByteCount[channel]);
        }
        DMA_Toggle[dmachip] = !DMA_Toggle[dmachip];
        break;

    /* Low Page Base Address */
    case 0x87: res = (DMA_BaseAddress[0]&(0xFF<<16))>>16; break;
    case 0x83: res = (DMA_BaseAddress[1]&(0xFF<<16))>>16; break;
    case 0x81: res = (DMA_BaseAddress[2]&(0xFF<<16))>>16; break;
    case 0x82: res = (DMA_BaseAddress[3]&(0xFF<<16))>>16; break;
    case 0x8B: res = (DMA_BaseAddress[5]&(0xFF<<16))>>16; break;
    case 0x89: res = (DMA_BaseAddress[6]&(0xFF<<16))>>16; break;
    case 0x8A: res = (DMA_BaseAddress[7]&(0xFF<<16))>>16; break;

    /* High Page Base Address */
    case 0x487: res = (DMA_BaseAddress[0]&(0xFF<<24))>>24; break;
    case 0x483: res = (DMA_BaseAddress[1]&(0xFF<<24))>>24; break;
    case 0x481: res = (DMA_BaseAddress[2]&(0xFF<<24))>>24; break;
    case 0x482: res = (DMA_BaseAddress[3]&(0xFF<<24))>>24; break;
    case 0x48B: res = (DMA_BaseAddress[5]&(0xFF<<24))>>24; break;
    case 0x489: res = (DMA_BaseAddress[6]&(0xFF<<24))>>24; break;
    case 0x48A: res = (DMA_BaseAddress[7]&(0xFF<<24))>>24; break;

    case 0x08:
    case 0xD0:
        /* Status */
        TRACE("Status Register Read\n");
        res = DMA_Status[(port==0x08)?0:1];

    case 0x0D:
    case 0xDA:
        /* Temporary */
        FIXME("Temporary Register Read- Not Implemented\n");
        break;
    }
    return res;
}
