5.9.1.1 Writing Single Vector or Compatibility Mode ISRs

If your project is using a single interrupt vector or you are using a device operating in Mid-range Compatibility mode, observe the following guidelines when writing the interrupt service routine (ISR).

Write only one ISR using the __interrupt() specifier. No arguments should be passed to this specifier. Use void as the ISR return type and for the parameter specification.

Inside the ISR body, determine the source of the interrupt by checking the interrupt flag and the interrupt enable for each source that is to be processed and make the relevant interrupt code conditional on those being set. These checks can be placed in any order, but those appearing earlier in the ISR will be processed sooner, potentially improving response times.

At the appropriate point in your main-line code, unmask the interrupt sources required by setting their interrupt enable bit in the corresponding SFR. Additionally, enable the global interrupt enable to allow interrupts to be generated.

An example of an ISR for a device using a single vector or operating in Mid-range Compatibility mode is shown below. Notice that the interrupt function checks for the source of the interrupt by looking at the interrupt enable bit (e.g., TMR0IE) and the interrupt flag bit (e.g., TMR0IF). Checking the interrupt enable flag is required since interrupt flags associated with a peripheral can be asserted even if the peripheral is not configured to generate an interrupt.
void __interrupt() tcInt(void) {
    if (TMR0IE && TMR0IF) {  // any timer 0 interrupts?
        TMR0IF=0;            // clear the interrupt flag
        ++tick_count;
    }
    if (TMR1IE && TMR1IF) {  // any timer 1 interrupts?
        TMR1IF=0;            // clear the interrupt flag
        tick_count += 100;
    }
    // process other interrupt sources here, if required
    return;
}