summaryrefslogtreecommitdiff
path: root/src/Interrupts.c
blob: ce407cff2917b1701b2a82d6e4f36ac5b123ecc5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*******************************************************************//**
*
* \file     Interrupts.c
*
* \author   Xavier Del Campo
*
* \brief    Implementation of Interrupts module.
*
************************************************************************/

/* *************************************
 * Includes
 * *************************************/

#include "Interrupts.h"
#include <psx.h>
#include <stdint.h>
#include <stddef.h>

/* *************************************
 * Defines
 * *************************************/

#ifndef I_MASK
/*******************************************************************//**
*
* \brief    Interrupt mask register.
*
*           According to NoCash specifications, I_MASK bits are
*           structured as follows:
*
*           \arg    Bit 0       IRQ0 VBLANK (PAL=50Hz, NTSC=60Hz)
*           \arg    Bit 1       IRQ1 GPU
*           \arg    Bit 2       IRQ2 CDROM
*           \arg    Bit 3       IRQ3 DMA
*           \arg    Bit 4       IRQ4 TMR0  Timer 0 aka Root Counter 0
*           \arg    Bit 5       IRQ5 TMR1  Timer 1 aka Root Counter 1
*           \arg    Bit 6       IRQ6 TMR2  Timer 2 aka Root Counter 2
*           \arg    Bit 7       IRQ7 Controller and Memory Card
*           \arg    Bit 8       IRQ8 SIO
*           \arg    Bit 9       IRQ9 SPU
*           \arg    Bit 10      IRQ10 Controller - Lightpen Interrupt
*           \arg    Bits 11-15  Not used (always zero)
*           \arg    Bits 16-31  Garbage
*
************************************************************************/
#define I_MASK  (*(volatile unsigned int*)0x1F801074)
#endif /* I_MASK */

/* *************************************
 * Types definition
 * *************************************/

/* *************************************
 * Global variables definition
 * *************************************/

/* *************************************
 * Local variables definition
 * *************************************/

/* *************************************
 *  Local prototypes declaration
 * *************************************/

/* *************************************
 * Functions definition
 * *************************************/

/*******************************************************************//**
*
* \brief    Enables an interrupt source given by intSource.
*
* \param    intSource
*               HW interrupt source.
*
* \see      \ref InterruptSource for a list of possible HW interrupt causes.
*
************************************************************************/
void InterruptsEnableInt(const enum InterruptSource intSource)
{
    if (intSource < MAX_INTERRUPT_SOURCES)
    {
        /* Disable interrupts while I_MASK is modified. */
        EnterCriticalSection();

        /* Set bit for selected interrupt source. */
        I_MASK |= 1 << intSource;

        /* Re-enable interrupts. */
        ExitCriticalSection();
    }
    else
    {
        /* Invalid selected InterruptSource instance. Exit. */
    }
}

/*******************************************************************//**
*
* \brief    Disables an interrupt source given by intSource.
*
* \param    intSource
*               HW interrupt source.
*
* \see      \ref InterruptSource for a list of possible HW interrupt causes.
*
************************************************************************/
void InterruptsDisableInt(const enum InterruptSource intSource)
{
    if (intSource < MAX_INTERRUPT_SOURCES)
    {
        /* Disable interrupts while I_MASK is modified. */
        EnterCriticalSection();

        /* Remove bit for selected interrupt source. */
        I_MASK &= ~(1 << intSource);

        /* Re-enable interrupts while I_MASK is modified. */
        ExitCriticalSection();
    }
    else
    {
        /* Invalid selected InterruptSource instance. Exit. */
    }
}