Here's some skeletal code from my interrupts page:
ISR (PCINT0_vect)
{
// handle pin change interrupt for D8 to D13 here
} // end of PCINT0_vect
ISR (PCINT1_vect)
{
// handle pin change interrupt for A0 to A5 here
} // end of PCINT1_vect
ISR (PCINT2_vect)
{
// handle pin change interrupt for D0 to D7 here
} // end of PCINT2_vect
void setup ()
{
// pin change interrupt (example for D9)
PCMSK0 |= _BV (PCINT1); // want pin 9
PCIFR |= _BV (PCIF0); // clear any outstanding interrupts
PCICR |= _BV (PCIE0); // enable pin change interrupts for D8 to D13
}
In this particular case we only get an interrupt on pin 9. However you note there are three ISRs for all of the pins (the ranges are in the comments). You still need to work out if it is rising or falling, and if you wanted D9
and D10 you would need to work out which one had caused it. I'm not certain what would happen if, while processing (say) an interrupt for D9 a change in D10 occurred while you were in the ISR. Judging by the datasheet (page 73) if a further change occurred while processing one, it would be queued for the future. I can imagine a race condition here. Say you had D9 and D10 both triggering PC interrupts. D9 changes and you enter the ISR. D10 then changes while you are in the ISR. The ISR notices that both have changed and reacts accordingly. However the D10 interrupt is still remembered for next time, and you may enter the ISR again a moment later and find no changes. This isn't necessarily a disaster. You would just need to allow for it.