There's USART interrupt as well. Check out the USART/EUSART section of the datasheet.

A really easy and efficient way to start right now with interrupts is to use Darrel Taylor Instant Interrupts. Check out this link.
http://www.pbpgroup.com/modules/wfse...p?articleid=19

For your, and any, specific requirement, there's a load of different approach.. say one different per programmer

The basic skelleton:
Main program (Loop)
Interrupts.

Whatever happen in your Interrupts, you may set flags there and process them in your main loop.

OR you may process some dull duties in your main loop and force interrupts to happen in your main loop too.

To read I/Os and evaluate them, you may use something like that (Which assume some push button connected to gnd on PORTB<3:0> (b3, b2, b1, b0)
Code:
SomePushButton VAR BYTE
'
'
'
'
SomePushButton = PORTB & $0F ' read PORTB and keep only <3:0> bits (Bitwise AND)
SELECT CASE SomePushButton
     CASE %1110 ' PORTB.0
          ' code for PORTB.0 here
     CASE %1101 ' PORTB.1
          ' code for PORTB.1 here
     CASE %1011 ' PORTB.2
          ' code for PORTB.2 here
     CASE %0111 ' PORTB.3
          ' code for PORTB.3 here
     END SELECT