You can always drive the leds like this charlieplex [12 led] example . the multiplexer is an interrupt driven background task that only uses about
2% of the processing time [if I remember correctly]. the isr could be done in asm if speed critical




Code:
'****************************************************************
'*  Name    : charlieplex.pbp                                        *
'*  Author  : richard                                   *
'*  Notice  :                                *
'*          :                                *
'*  Date    :                                          *
'*  Version :    16f1825     @3.3 volts                               *
'*  Notes   :       *
'*          :              *
'*            
'****************************************************************
  
#CONFIG
             __config        _CONFIG1,    _FOSC_INTOSC & _CP_OFF & _WDTE_ON  &  _PWRTE_ON  &  _MCLRE_ON  & _CLKOUTEN_OFF
              __config      _CONFIG2, _PLLEN_ON & _LVP_OFF
#ENDCONFIG

DEFINE OSC 32
 
 include "dt_ints-14.bas"
 Include "REENTERPBP.bas"
 

asm      
INT_LIST macro     
      INT_HANDLER TMR1_INT, _TOCK, PBP ,YES
      
      endm
       INT_CREATE
ENDASM       
      
       
   
     
@timer1 =TMR1L
leds var word
tmp var byte
x var byte
timer1         VAR WORD EXT
timer1=15543
T1CON=$31
@ INT_ENABLE  TMR1_INT
OSCCON=$70
ANSELA=0
ANSELC=0

   
mainloop:
leds=1365    
pause 1000 
leds=2730
pause 1000  
goto mainloop  
 
   
    
     
  
TOCK:
T1CON.0=0
timer1=timer1+64536
T1CON.0=1
if leds.0[x] then
    lookup x,[12,12,9,9,3,3,5,5,6,6,10,10],tmp
    TRISC =(TRISC&$f0)|tmp
    lookup x,[ 2, 1,4,2,8,4,8,2,8,1 ,4, 1],tmp
    latC =(latC&$f0)|tmp
endif
x=x+1
if x=12 then x=0
@ INT_RETURN