/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include "windef.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 %lx 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 %lx 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 = %lx\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 = %lx\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;
}
