/****************************************************************************/
/* Copyright 2012 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
#include <string.h>
#include <stdio.h>
#include "cache.h"
#include "serial.h"
#include "sys_defs.h"

#define CACHE_SRCLEN 128
#define CACHE_IOLEN  32

unsigned int cacheValues[CACHE_VALLEN] = { 0 };
unsigned char cacheIOTypes[CACHE_IOLEN] = { 0 };
unsigned char cacheSources[CACHE_SRCLEN];

void cacheInit()
{
    memset(cacheSources, 0xFF, CACHE_SRCLEN);
}

void cacheSetEntry(unsigned char index, unsigned int value,
    unsigned char source, unsigned char iotype)
{    
    unsigned int ioIndex = index / 8;
    unsigned int ioShift = 7 - (index - 8 * ioIndex);
    unsigned int srcIndex = index / 2;
    
    cacheValues[index] = value;
    cacheSources[srcIndex] = (index % 2 == 0) ?
        (cacheSources[srcIndex] & 0x0F) + ((source << 4) & 0xF0) :
        (cacheSources[srcIndex] & 0xF0) + (source & 0x0F);
    
    switch (iotype)
    {
        case CACHE_IO_IN: case CACHE_IO_OUT:
            cacheIOTypes[ioIndex] ^= iotype << ioShift;
        break;
    }
}

void cacheGetEntry(unsigned char index, unsigned int* value,
    unsigned char* source, unsigned char* iotype)
{
    unsigned int ioIndex = index / 8;
    unsigned int ioShift = 7 - (index - 8 * ioIndex);
    unsigned int srcIndex = index / 2;
    
    if (value != NULL)
    {
        *value = cacheValues[index];
    }
    
    if (source != NULL)
    {
        *source = cacheSources[srcIndex];
        *source = (index % 2 == 0) ? (*source & 0xF0) >> 4 : *source & 0x0F;
    }
    
    if (iotype != NULL)
    {
        *iotype = (cacheIOTypes[ioIndex] >> ioShift) & 1;
    }
}

void cacheClear()
{
    memset(cacheValues, 0, CACHE_VALLEN);
    memset(cacheIOTypes, 0, CACHE_IOLEN);
    memset(cacheSources, 0xFF, CACHE_SRCLEN);
}