Look at this document which states:-
Interrupt-on-change
This feature is similar to the external interrupt facility , except that a port change
interrupt will be triggered by any change (not just one type of
transition) on any of the pins for which it is enabled. This makes it
more flexible (being available on more pins), but also more difficult
to deal with correctly.
You ask for "context saving", but you don't seem to know what that term means in your context?
The meaning I am most familiar with is in the context of interrupts and task switching, where everything that the main program or a task relies on is saved in RAM, to be restored later. In most cases this amounts to pushing all registers on the stack, so they can be popped later.
Things can get difficult when there is context outside the CPU registers that can be used by the interrupt (or by other tasks), so it must be saved too. Think for instance of floating point coprocessor registers.
On a the old 12 and 14 bit core PICs context saving for an interrupt is a bit tricky, but it is explained in the datasheet, better read it there. Note that on these chips various memory-mapped registers can be context too, like the indirection register. If your interrupt routine uses such registers they must probably be saved (and restored) too.
Real context swapping for tasking switching is not possible on these PICs, because the stack can not be changed. There are some dirty tricks that achieve the same effect (like not using the hardware stack at all), but at a cost.
The 18F PICs and IIRC the enhanced midrange chips too have a stack that can be read and written, so real context switching is possible, but it is tedious. If you want multitasking, better look for a CPU that has a memory-mapped stack. (Nowadays a Cortex would be an obvious choice.)
Best Answer
There isn't a fundamental difference, it's more a question of degree — the amount of context that needs to be saved.
When an RTOS thread context switch occurs, all of the CPU state that any thread might use must be saved. This usually includes all of the CPU registers, including flag or status registers, so that when they're restored, the thread resumes as though nothing ever happened.
When an interrupt occurs, there's still a context switch, but only the context that the interrupt handler actually needs to use needs to be saved and then subsequently restored. If you write your interrupt handler in a high-level language, this will pretty much be equivalent to a full thread context switch, because there are no constraints on what resources such an interrupt handler might touch. However, if you write your interrupt handler in assembly language, you can keep track of exactly which registers it touches and save only those. This allows the execution of the interrupt handler to be extremely fast, reducing its impact on the rest of the system, and/or allowing it to handle interrupts at a higher rate.