libdragon
Files | Data Structures | Macros | Enumerations | Functions | Variables

N64 interrupt registering and servicing routines. More...

Files

file  interrupt.c
 Interrupt Controller.
 
file  interrupt.h
 Interrupt Controller.
 

Data Structures

struct  _callback_link
 Structure of an interrupt callback. More...
 

Macros

#define MI_INTR_SP   0x01
 SP interrupt bit.
 
#define MI_INTR_SI   0x02
 SI interrupt bit.
 
#define MI_INTR_AI   0x04
 AI interrupt bit.
 
#define MI_INTR_VI   0x08
 VI interrupt bit.
 
#define MI_INTR_PI   0x10
 PI interrupt bit.
 
#define MI_INTR_DP   0x20
 DP interrupt bit.
 
#define MI_MASK_SP   0x01
 SP mask bit.
 
#define MI_MASK_SI   0x02
 SI mask bit.
 
#define MI_MASK_AI   0x04
 AI mask bit.
 
#define MI_MASK_VI   0x08
 VI mask bit.
 
#define MI_MASK_PI   0x10
 PI mask bit.
 
#define MI_MASK_DP   0x20
 DP mask bit.
 
#define MI_MASK_CLR_SP   0x0001
 Clear SP mask.
 
#define MI_MASK_SET_SP   0x0002
 Set SP mask.
 
#define MI_MASK_CLR_SI   0x0004
 Clear SI mask.
 
#define MI_MASK_SET_SI   0x0008
 Set SI mask.
 
#define MI_MASK_CLR_AI   0x0010
 Clear AI mask.
 
#define MI_MASK_SET_AI   0x0020
 Set AI mask.
 
#define MI_MASK_CLR_VI   0x0040
 Clear VI mask.
 
#define MI_MASK_SET_VI   0x0080
 Set VI mask.
 
#define MI_MASK_CLR_PI   0x0100
 Clear PI mask.
 
#define MI_MASK_SET_PI   0x0200
 Set PI mask.
 
#define MI_MASK_CLR_DP   0x0400
 Clear DP mask.
 
#define MI_MASK_SET_DP   0x0800
 Set DP mask.
 
#define PI_CLEAR_INTERRUPT   0x02
 Bit to set to clear the PI interrupt.
 
#define SI_CLEAR_INTERRUPT   0
 Bit to set to clear the SI interrupt.
 
#define SP_CLEAR_INTERRUPT   0x08
 Bit to set to clear the SP interrupt.
 
#define DP_CLEAR_INTERRUPT   0x0800
 Bit to set to clear the DP interrupt.
 
#define AI_CLEAR_INTERRUPT   0
 Bit to set to clear the AI interrupt.
 

Enumerations

enum  interrupt_state_t { INTERRUPTS_UNINITIALIZED , INTERRUPTS_DISABLED , INTERRUPTS_ENABLED }
 State of interrupts on the system. More...
 

Functions

void __MI_handler (void)
 Handle an MI interrupt. More...
 
void __TI_handler (void)
 Handle a timer interrupt.
 
void __CART_handler (void)
 Handle a CART interrupt.
 
void register_AI_handler (void(*callback)())
 Register an AI callback. More...
 
void unregister_AI_handler (void(*callback)())
 Unregister an AI callback. More...
 
void register_VI_handler (void(*callback)())
 Register a VI callback. More...
 
void unregister_VI_handler (void(*callback)())
 Unregister a VI callback. More...
 
void register_PI_handler (void(*callback)())
 Register a PI callback. More...
 
void unregister_PI_handler (void(*callback)())
 Unegister a PI callback. More...
 
void register_DP_handler (void(*callback)())
 Register a DP callback. More...
 
void unregister_DP_handler (void(*callback)())
 Unregister a DP callback. More...
 
void register_SI_handler (void(*callback)())
 Register a SI callback. More...
 
void unregister_SI_handler (void(*callback)())
 Unegister a SI callback. More...
 
void register_SP_handler (void(*callback)())
 Register a SP callback. More...
 
void unregister_SP_handler (void(*callback)())
 Unegister a SP callback. More...
 
void register_TI_handler (void(*callback)())
 Register a timer callback. More...
 
void unregister_TI_handler (void(*callback)())
 Unregister a timer callback. More...
 
void register_CART_handler (void(*callback)())
 Register a CART interrupt callback. More...
 
void unregister_CART_handler (void(*callback)())
 Unregister a CART interrupt callback. More...
 
void set_AI_interrupt (int active)
 Enable or disable the AI interrupt. More...
 
void set_VI_interrupt (int active, unsigned long line)
 Enable or disable the VI interrupt. More...
 
void set_PI_interrupt (int active)
 Enable or disable the PI interrupt. More...
 
void set_DP_interrupt (int active)
 Enable or disable the DP interrupt. More...
 
void set_SI_interrupt (int active)
 Enable or disable the SI interrupt. More...
 
void set_SP_interrupt (int active)
 Enable or disable the SP interrupt. More...
 
void set_TI_interrupt (int active)
 Enable the timer interrupt. More...
 
void set_CART_interrupt (int active)
 Enable the CART interrupt. More...
 
void __init_interrupts ()
 Initialize the interrupt controller.
 
void disable_interrupts ()
 Disable interrupts systemwide. More...
 
void enable_interrupts ()
 Enable interrupts systemwide. More...
 
interrupt_state_t get_interrupts_state ()
 Return the current state of interrupts. More...
 

Variables

uint32_t interrupt_disabled_tick = 0
 tick at which interrupts were disabled. More...
 
struct callback_link * AI_callback = 0
 Linked list of AI callbacks.
 
struct callback_link * VI_callback = 0
 Linked list of VI callbacks.
 
struct callback_link * PI_callback = 0
 Linked list of PI callbacks.
 
struct callback_link * DP_callback = 0
 Linked list of DP callbacks.
 
struct callback_link * SI_callback = 0
 Linked list of SI callbacks.
 
struct callback_link * SP_callback = 0
 Linked list of SP callbacks.
 
struct callback_link * TI_callback = 0
 Linked list of TI callbacks.
 
struct callback_link * CART_callback = 0
 Linked list of CART callbacks.
 

Detailed Description

N64 interrupt registering and servicing routines.

The N64 interrupt controller provides a software interface to register for interrupts from the various systems in the N64. Most interrupts on the N64 coordinate through the MIPS interface (MI) to allow interrupts to be handled at one spot. A notable exception is the timer interrupt which is generated by the MIPS r4300 itself and not the N64 hardware.

The interrupt controller is automatically initialized before main is called. By default, all interrupts are enabled and any registered callback can be called when an interrupt occurs. Each of the N64-generated interrupts is maskable using the various set accessors.

Interrupts can be enabled or disabled as a whole on the N64 using enable_interrupts and disable_interrupts. It is assumed that once the interrupt system is activated, these will always be called in pairs. Calling enable_interrupts without first calling disable_interrupts is considered a violation of this assumption and should be avoided. Calling disable_interrupts when interrupts are already disabled will have no effect. Calling enable_interrupts again to restore from a critical section will not enable interrupts if interrupts were not enabled when calling disable_interrupts. In this manner, it is safe to nest calls to disable and enable interrupts.

Enumeration Type Documentation

◆ interrupt_state_t

State of interrupts on the system.

Enumerator
INTERRUPTS_UNINITIALIZED 

Interrupt controller has not been initialized.

INTERRUPTS_DISABLED 

Interrupts are currently disabled.

INTERRUPTS_ENABLED 

Interrupts are currently enabled.

Function Documentation

◆ __MI_handler()

void __MI_handler ( void  )

Handle an MI interrupt.

Note
This function handles most of the interrupts on the system as they come through the MI.

◆ register_AI_handler()

void register_AI_handler ( void(*)()  callback)

Register an AI callback.

Parameters
[in]callbackFunction to call when an AI interrupt occurs

◆ unregister_AI_handler()

void unregister_AI_handler ( void(*)()  callback)

Unregister an AI callback.

Parameters
[in]callbackFunction that should no longer be called on AI interrupts

◆ register_VI_handler()

void register_VI_handler ( void(*)()  callback)

Register a VI callback.

Parameters
[in]callbackFunction to call when a VI interrupt occurs

◆ unregister_VI_handler()

void unregister_VI_handler ( void(*)()  callback)

Unregister a VI callback.

Parameters
[in]callbackFunction that should no longer be called on VI interrupts

◆ register_PI_handler()

void register_PI_handler ( void(*)()  callback)

Register a PI callback.

Parameters
[in]callbackFunction to call when a PI interrupt occurs

◆ unregister_PI_handler()

void unregister_PI_handler ( void(*)()  callback)

Unegister a PI callback.

Parameters
[in]callbackFunction that should no longer be called on PI interrupts

◆ register_DP_handler()

void register_DP_handler ( void(*)()  callback)

Register a DP callback.

Parameters
[in]callbackFunction to call when a DP interrupt occurs

◆ unregister_DP_handler()

void unregister_DP_handler ( void(*)()  callback)

Unregister a DP callback.

Parameters
[in]callbackFunction that should no longer be called on DP interrupts

◆ register_SI_handler()

void register_SI_handler ( void(*)()  callback)

Register a SI callback.

Parameters
[in]callbackFunction to call when a SI interrupt occurs

◆ unregister_SI_handler()

void unregister_SI_handler ( void(*)()  callback)

Unegister a SI callback.

Parameters
[in]callbackFunction that should no longer be called on SI interrupts

◆ register_SP_handler()

void register_SP_handler ( void(*)()  callback)

Register a SP callback.

Parameters
[in]callbackFunction to call when a SP interrupt occurs

◆ unregister_SP_handler()

void unregister_SP_handler ( void(*)()  callback)

Unegister a SP callback.

Parameters
[in]callbackFunction that should no longer be called on SP interrupts

◆ register_TI_handler()

void register_TI_handler ( void(*)()  callback)

Register a timer callback.

The callback will be used when the timer interrupt is triggered by the CPU. This happens when the COP0 COUNT register reaches the same value of the COP0 COMPARE register.

This function is useful only if you want to do your own low level programming of the internal CPU timer and handle the interrupt yourself. In this case, also remember to activate the timer interrupt using set_TI_interrupt.

Note
If you use the timer library (timer_init and new_timer), you do not need to call this function, as timer interrupt are already handled by the timer library.
Parameters
[in]callbackFunction to call when a timer interrupt occurs

◆ unregister_TI_handler()

void unregister_TI_handler ( void(*)()  callback)

Unregister a timer callback.

Note
If you use the timer library (timer_init and new_timer), you do not need to call this function, as timer interrupt are already handled by the timer library.
Parameters
[in]callbackFunction that should no longer be called on timer interrupts

◆ register_CART_handler()

void register_CART_handler ( void(*)()  callback)

Register a CART interrupt callback.

The callback will be called when a CART interrupt is triggered. CART interrupts are interrupts triggered by devices attached to the PI bus (aka CART bus), for instance the 64DD, or the modem cassette.

CART interrupts are disabled by default in libdragon. Use set_CART_interrupt to enable/disable them.

Notice that there is no generic way to acknowledge those interrupts, so if you activate CART interrupts, make also sure to register an handler that acknowledge them, otherwise the interrupt will deadlock the console.

Parameters
[in]callbackFunction that should no longer be called on CART interrupts

◆ unregister_CART_handler()

void unregister_CART_handler ( void(*)()  callback)

Unregister a CART interrupt callback.

Parameters
[in]callbackFunction that should no longer be called on CART interrupts

◆ set_AI_interrupt()

void set_AI_interrupt ( int  active)

Enable or disable the AI interrupt.

Parameters
[in]activeFlag to specify whether the AI interrupt should be active

◆ set_VI_interrupt()

void set_VI_interrupt ( int  active,
unsigned long  line 
)

Enable or disable the VI interrupt.

Parameters
[in]activeFlag to specify whether the VI interrupt should be active
[in]lineThe vertical line that causes this interrupt to fire. Ignored when setting the interrupt inactive

◆ set_PI_interrupt()

void set_PI_interrupt ( int  active)

Enable or disable the PI interrupt.

Parameters
[in]activeFlag to specify whether the PI interrupt should be active

◆ set_DP_interrupt()

void set_DP_interrupt ( int  active)

Enable or disable the DP interrupt.

Parameters
[in]activeFlag to specify whether the DP interrupt should be active

◆ set_SI_interrupt()

void set_SI_interrupt ( int  active)

Enable or disable the SI interrupt.

Parameters
[in]activeFlag to specify whether the SI interrupt should be active

◆ set_SP_interrupt()

void set_SP_interrupt ( int  active)

Enable or disable the SP interrupt.

Parameters
[in]activeFlag to specify whether the SP interrupt should be active

◆ set_TI_interrupt()

void set_TI_interrupt ( int  active)

Enable the timer interrupt.

Note
If you use the timer library (timer_init and new_timer), you do not need to call this function, as timer interrupt is already handled by the timer library.
Parameters
[in]activeFlag to specify whether the timer interrupt should be active
See also
register_TI_handler

◆ set_CART_interrupt()

void set_CART_interrupt ( int  active)

Enable the CART interrupt.

Parameters
[in]activeFlag to specify whether the CART interrupt should be active
See also
register_CART_handler

◆ disable_interrupts()

void disable_interrupts ( )

Disable interrupts systemwide.

Note
If interrupts are already disabled on the system or interrupts have not been initialized, this function will not modify the system state.

◆ enable_interrupts()

void enable_interrupts ( )

Enable interrupts systemwide.

Note
If this is called inside a nested disable call, it will have no effect on the system. Therefore it is safe to nest disable/enable calls. After the last nested interrupt is enabled, systemwide interrupts will be reenabled.

◆ get_interrupts_state()

interrupt_state_t get_interrupts_state ( )

Return the current state of interrupts.

Return values
INTERRUPTS_UNINITIALIZEDif the interrupt system has not been initialized yet.
INTERRUPTS_DISABLEDif interrupts have been disabled for some reason.
INTERRUPTS_ENABLEDif interrupts are currently enabled.

Variable Documentation

◆ interrupt_disabled_tick

uint32_t interrupt_disabled_tick = 0

tick at which interrupts were disabled.

Time at which interrupts were disabled.