Here is a working 18F2455 I2C slave. It will receive or send any amount of bytes you choose. The slave will not work if USB is enable on the chip.

In this example the Master is sending 0 to 127 on byte(0), and fixed data on Bytes 1 and 2.

The Slave sends three bytes back, tests the received byte(0) and lights a couple of leds. When the master sends (Byte(0) = 4), the slave ends three different bytes back. I also have eight leds connected to the slave, four on PortB 4-7 and four on PortA 0-3. These leds display the value of the received Byte(0).



Slave code

Code:
'*  Date    : 3/17/2009                                         *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :  18F2550 Slave I2c                                *
'****************************************************************
asm     __CONFIG    _CONFIG1L, _PLLDIV_5_1L & _FCMEN_OFF_1H
        __CONFIG    _CONFIG1H, _FOSC_HS_1H    
        __CONFIG    _CONFIG2L, _VREGEN_OFF_2L
        __CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
        __CONFIG    _CONFIG3H, _PBADEN_OFF_3H
        __CONFIG    _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
endasm
DEFINE OSC 20          
Define I2C_SLOW 1     'At this clock speed this needed to be added to make it work.
DEFINE I2C_HOLD 1

ADCON1 = $F       'All digital
CMCON = 7         'PortA Digital


'--------------- Define used register flags -------------------

SSPIF               VAR PIR1.3    ' SSP (I2C) interrupt flag
SSPIE               VAR PIE1.3 
BF                  VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
R_W                 VAR SSPSTAT.2 ' SSP (I2C) Read/Write
D_A                 VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKP                 VAR SSPCON1.4  ' SSP (I2C) SCK Release Control
SSPEN               VAR SSPCON1.5  ' SSP (I2C) Enable
SSPOV               VAR SSPCON1.6  ' SSP (I2C) Receive Overflow Indicator
WCOL                VAR SSPCON1.7  ' SSP (I2C) Write Collision Detect
STAT_BF             VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
STAT_RW             VAR SSPSTAT.2 ' SSP (I2C) Read/Write
STAT_DA             VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKE                 VAR SSPSTAT.6 ' SSP (I2C) Data/Address
WrData              var byte
j                   var byte
'------------------- Rx Buffer defintion --------------------
RxBufferLEN         con 16           
RxBuffer            var byte[Rxbufferlen]
RxBufferIndex       var byte
RxCnt               var byte
rxcnt = 0
'------------------ Tx Buffer defintion ----------------------
TxBufferLEN         con 3
TxBuffer            var byte[txbufferlen]
TxBufferIndex       var byte
TxCnt               var byte
txcnt = 0
'------------------ Define vars ------------------------
rxinptr             var byte
rxoutptr            var byte
txinptr             var byte
txoutptr            var byte
rxinptr = 0
rxoutptr = 0
txinptr = 0
txoutptr = 0
I2Caddress          CON $02                  ' Make address = 2

result	            VAR		BYTE			' ADC result
DummyRead           var     byte
DataIn 	            VAR     BYTE[8]			' Data in 
DataOut	            VAR     BYTE[8]			' Data out array
readcnt	            VAR     BYTE            ' I2C read count
address             var     byte
StatMask            var     byte
StatMask = %00101101
readcnt = 0				' Zero counter
' PicBasic Pro I2C slave program 
' Alias pins
Led1    var PORTC.0
LED2    Var PORTC.1




scl     VAR     PORTB.1         ' I2C clock input
sda     VAR     PORTB.0         ' I2C data input
TRISB = %00000011
TRISC = %00000000
TRISA = %00000000
LATB = $F0
'PortA= $0F
PORTA = $0F      'leds off  on A port
PORTB = $F0       ' Leds off on B port


high LED1
high led2

' -------------- Initialize I2C slave mode ------------------------
SSPADD = I2Caddress ' Set our address
SSPCON1 = $36        ' Set to I2C slave with 7-bit address
SSPCON2 = %00000000   ' clear sspcon2
SSPCON2 = %00000001   'enable clock stretching
SSPSTAT = %00000000    ' clear sspstat
SSPIE = 1               'Enable MSSP interrupt enable bit
SSPIF = 0               'Clear MSSP interrupt flag
RxBufferIndex = 0
TxBufferIndex = 0
Temp            var  byte
RxIndex         var  byte
TxIndex         var  byte
Stat            var  byte

dataout[0] = 41     ' just some data to start with
dataout[1] = 122
dataout[2] = 103
dataout[3] = 4


'    '   Interrupt definition   
'    '   ====================
'        '   USB interrupt used to keep USB connection alive
INCLUDE "DT_INTS-18.bas"    ' Base Interrupt System
INCLUDE "ReEnterPBP-18.bas"     ' Include if using PBP interrupts

ASM
INT_LIST  macro    ; IntSource,         Label,  Type, ResetFlag?
        
        INT_Handler    SSP_INT,  _I2C_Int,   PBP,  yes
    endm
    INT_CREATE               ; Creates the interrupt processor
endasm


@ INT_ENABLE  SSP_INT     ; Master Synchronous Serial Port Interrupt Flag bit. The transmission/reception is complete

'----------------------[ Skip over subs ]--------------------------------------
goto Programstart

I2C_Int:

If R_W = 0 then                            'Write from master
    if D_A = 0 then                        ' It's address from master
       address = SSPBUF                    ' do nothing
       rxinptr = 0                          ' Clear counters
       rxoutptr = 0
    else
        WCOL = 0
        sspov = 0
        if bf = 1 then                     'There is data in buffer
           if rxcnt < rxbufferlen  then
              rxbuffer[rxinptr] = SSPBUF
              rxinptr = rxinptr + 1
              if rxinptr = rxbufferlen then rxinptr = 0
           endif   
           rxcnt = rxcnt + 1
           
        EndIF 
    endif
else                                   ' Read by master
    if SSPSTAT = %00001101 then        'last byte was an address byte.
           txinptr = 0                 'read BF
           txoutptr = 0
    endif
        dummyread = SSPBUF             'dummy read  empty buffer
        if bf = 0 then                 ' if buffer is empty
            if txcnt > 0 then          ' Is there a byte to transfer
               SSPBUF = txbuffer[txoutptr]   'get the byte and send it
               txoutptr = txoutptr + 1       
               if txoutptr = txbufferlen then txoutptr = 0
               txcnt = txcnt - 1
            else
            'no byte to send
            endif       
        endif
endif

sspif = 0
CKP = 1 

@ INT_RETURN
'-------------------[ end of interrupt ]--------------------------------------


' ************************************************************
' * main program loop -                                      *
' *                                                          *
' * ..                                                       *
' ************************************************************

ProgramStart: 

     if txcnt < txbufferlen  then
          
            TxBuffer[txinptr] = dataout[txinptr] 
            txinptr = txinptr + 1
            if txinptr = txbufferlen  then txinptr = 0

            txcnt = txcnt + 1
    endif
    if rxcnt != 0 then
       datain[rxoutptr] = rxbuffer[rxoutptr]
       rxoutptr = rxoutptr + 1
       if rxoutptr = rxbufferlen  then
          rxoutptr = 0
       endif
       rxcnt = rxcnt - 1


    endif
Select case datain[0]             'Test data from master byte 0
       case 0
          low led1                'turn on LED1
       case 1
          high led1               'turn off led1
          low led2                'turn on led2
       case 2
         low led1: low led2       'turn on both
       case 3
          high led1: high led2    'turn off both
       case 4                     'Change the data out to master
          dataout[0] = 44
          dataout[1] = 45
          dataout[2] = 46
       
end select
                                    'Eight leds for testing, 4 on Port b and four on Port a
portb = ~datain(0) <<4              'Lower nibble to RB4 to RB7
porta = ~(datain(0) & $F0)>>4       'upper nibble RA0 to RA3
goto ProgramStart 
 end
It seems the 18F chips are very sensitive to the correct timing. Also it is a good idea to read AN734B to understand the difference between I2C slave with 16F chips and 18F chips.

Hope this helps someone out

Dave