/****************************************************************************/
/* Copyright 1991 to 1993, MBARI                                            */
/****************************************************************************/
/* Summary  : IBC CPU Microcontroller Board - Interrupt Controller Functions*/
/* Filename : pic.c                                                         */
/* Author   : Andrew Pearce                                                 */
/* Project  : New ROV IBC Based Data Concentrator                           */
/* Version  : 1.0                                                           */
/* Created  : 05/05/92                                                      */
/* Modified : 04/07/93                                                      */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/* $Header: /usr/tiburon/.cvsroot/micro/ibc/boards/cpu196/pic.c,v 1.2 1997/05/07 15:26:45 pean Exp $
 * $Log: pic.c,v $
 * Revision 1.2  1997/05/07 15:26:45  pean
 * Cleaned up Include files and makefile for new directory structure.
 *
 * Revision 1.1.1.1  1997/05/02 18:51:27  pean
 * Initial check in of IBC microcontroller software
 *
 * Revision 1.1  93/07/02  09:22:29  09:22:29  pean (Andrew Pearce)
 * Initial revision
 *
 */
/****************************************************************************/

#pragma model(196)
#pragma nosignedchar

#include "C:/C96/INCLUDE/80C196.h"      /* 80C196 Register mapping          */
#include "C:/C96/INCLUDE/stddef.h"      /* C Standard Definitions           */
#include "const.h"                      /* Misc. constants - TRUE/FALSE etc */
#include "types.h"                      /* MBARI style guide declarations   */
#include "microdef.h"                   /* Microcontroller Definitions      */
#include "microlib.h"                   /* Microcontroller Library decls.   */
#include "pic.h"                        /* Intel 82C59 Interrupt Controller */

Extern volatile Byte picBaseAddr;
Extern volatile Byte picNextAddr;
Extern volatile Byte picIntAckAddr;

struct
{
    VOIDFUNCPTR intrFuncPtr;            /* Interrupt Function pointer       */
    Word        intrParam;              /* Paramater to call function with  */
} PIC_intFuncTable[PIC_INTR_LEVELS];    /* PIC interrupt handler functions  */

/****************************************************************************/
/* Function    : initializePIC                                              */
/* Purpose     : Initialize 82C59A Peripheral Interrupt Controller          */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
initializePIC( Void )
{
    Int16 level;

    for (level = 0; level < PIC_INTR_LEVELS; level++)
    {
        PIC_intFuncTable[level].intrFuncPtr = (VOIDFUNCPTR) NULL;
        PIC_intFuncTable[level].intrParam = NULL;
    } /* for */

    PIC_ICW1 = PIC_LEVEL_TRIG | PIC_ADDR_INT_4 | PIC_SINGLE | PIC_ICW4_NEEDED;

    PIC_ICW2 = 0;                       /* Table address is not used 0      */
                                        /* ICW 3 should NOT be written      */
    PIC_ICW4 = PIC_NO_SFNM | PIC_NON_BUF | PIC_NORMAL_EOI | PIC_8086_MODE;

    PIC_OCW1 = PIC_INT_MASK_ALL;        /* Mask all interrupts              */
} /* initializePIC() */

/****************************************************************************/
/* Function    : PIC_intEnable                                              */
/* Purpose     : Enable PIC Interrupt Level                                 */
/* Inputs      : Interrupt level 0-7                                        */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
PIC_intEnable( Nat16 level )
{
    Byte mask;

    if (level < PIC_INTR_LEVELS)
    {
        mask = (Byte) ~(1 << (level & 0x0007));  /* Create bit mask         */

        int0Disable(EXTINT_MASK);       /* Disable external intr from PIC   */
                                        /* Read existing mask and AND mask  */
        PIC_OCW1 = PIC_IMASK & mask;

        int0Enable(EXTINT_MASK);        /* Enable external intr from PIC    */
    } /* if */
} /* PIC_intEnable() */

/****************************************************************************/
/* Function    : PIC_intDisable                                             */
/* Purpose     : Disable PIC Interrupt Level                                */
/* Inputs      : Interrupt level 0-7                                        */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
PIC_intDisable( Nat16 level )
{
    Byte mask;

    if (level < PIC_INTR_LEVELS)
    {
        mask = (Byte) (1 << (level & 0x0007));  /* Create bit mask          */

        int0Disable(EXTINT_MASK);       /* Disable external intr from PIC   */
                                        /* Read existing mask and OR mask   */
        PIC_OCW1 = PIC_IMASK | mask;
        int0Enable(EXTINT_MASK);        /* Enable external intr from PIC    */
    } /* if */
} /* PIC_intDisable() */

/****************************************************************************/
/* Function    : PIC_intStaus                                               */
/* Purpose     : Read interrupt status register from PIC                    */
/* Inputs      : None                                                       */
/* Outputs     : None                                                       */
/****************************************************************************/
    Byte
PIC_intStatus( Void )
{
    return(PIC_IRR);            /* Read PIC Interrupt Request Reg   */
} /* PIC_intStatus() */

/****************************************************************************/
/* Function    : PIC_intConnect                                             */
/* Purpose     : Connect function to PIC interrrupt level                   */
/* Inputs      : Interrupt level, function pointer, function parameter      */
/* Outputs     : None                                                       */
/****************************************************************************/
    Void
PIC_intConnect( Byte intLevel, VOIDFUNCPTR intrFuncPtr, Word intrParam )
{
    if (intLevel < PIC_INTR_LEVELS)
    {
        PIC_intFuncTable[intLevel].intrFuncPtr = intrFuncPtr;
        PIC_intFuncTable[intLevel].intrParam = intrParam;
    } /* if */
} /* PIC_intConnect() */

