The code I gave was quite complete.
here is some uart code; for ease of use it is not interrupt driven.
This is FAR more simpler than an i2c slave.

a few more LOC are needed for a main() that calls initialization methods, set pin directions, and globally enable interrupts
you also need a DEFINE_INT..... as described in sdcc documentation.

Sebastien.

//-------------------------------------------------------------------------------------------
//initialize the serial port
void ser_setup()
{
    //configure the serial port
    TXSTAbits.SYNC = 0; //asynchronous mode
    RCSTAbits.SPEN = 1; //enable serial port
    RCSTAbits.CREN = 1; //enable receiver
    TRISCbits.TRISC6 = 0; //set txd as output
    TRISCbits.TRISC7 = 1; //set rxd as input

    TXSTAbits.BRGH = 1; //baud = fosc/(16(X+1)) X=(fosc/(16bauds))-1
    SPBRG = ...;
}

//-------------------------------------------------------------------------------------------
//Transmit a byte.
void ser_putchar(char car)
{
    TXREG = car;
    TXSTAbits.TXEN=1; //enable transmission
    //Wait for completion
    while(TXSTAbits.TRMT==0);
}

//-------------------------------------------------------------------------------------------
//read a byte
char ser_getchar()
{
    //wait until something is received
    while(PIR1bits.RCIF==0);
    return RCREG;
}

tested to work perfectly on pic18f452 and pic18f2620, will also probably work for other.

You just have to calculate proper BRGH value to get the correct baud rate

Sebastien