Hi Jeremy

We did that for Sony and the code for 16F84@4MHz written with CC5XFree
follows. see if u can figure it :-)
//=============cut--here=================================
/*
 * IR reception
 * 05/Sep/1999 JLS & CAE
 * jls@certi.ufsc.br
 * cae@certi.ufsc.br
 * CC5xFree v3.0E (www.bknd.com)
 */

/*
  Sony Data format: 12 bits

  Bit zero:

  400
  +--+   +...
  |  |   |
  +  +---+
      800

  Bit one:

  400
  +--+      +...
  |  |      |
  +  +------+
       1400

  Frame:
                400    400
  --+          +--+   +--+      +--+
    |        &nbs p; |  |   |  |      |  |
    +---2600---+  +---+  +------+  +...
                    800     1400

  Decoding algorithm:
  - Detect 2600us pulse,
  - measure next high pulse as P1 (400us)
  - measure next low  pulse as P2 (800/1400us)
  - store min(P1)
  - store max(P2)
  After all measurements:
  - calculate mean = (max-min)/2 + min
  - For all (P1,P2) measured:
    . Add P1+P2=P3
    . If P3< mean => bit is zero
    . If P3>=mean => bit is one

  Measures with Timer0 & Prescaler:16
    2600us = 162
    1400us = 87
     800us = 50
     400us = 25

     400+800  = 25+50 = 75
     400+1400 = 25+87 = 112
     mean ~= (112-75)/2+75 = 18+75 = 93
*/

#define         _16f84_
#include        <16f84.h>

#ifdef _12C508_
        bit     _TxOUT          @ GP0;
        bit     RxD_pin         @ GP1;
        bit     IR_input        @ GP2;
#else
        #define RP0              STATUS.5
        #pragma update_RP 0 &nbs p; /* OFF */
        #define DEF_TRISA        0
        #define DEF_TRISB        6
        bit     Rele            @ PORTA.1;

        bit     IR_input        @ PORTB.1;
        bit     RxD_pin         @ PORTB.2;
        bit     _TxOUT          @ PORTB.3;
        bit     LED             @ PORTB.4;
#endif

unsigned char size,x,y,med,min,max,rxBuf;

unsigned char r[4];
unsigned char buff[32];

void TxSerial (unsigned char txBuf);

/*----------------------------------------------------------------------- ---*/
void TxEnter (void) {
/*---------------------------------------------------------------------- ----*/
        TxSerial(0xD);
        TxSerial(0xA);
}

/*----------------------------------------------------------------------- ---*/
void TxHexAscii (unsigned char in) {
/*---------------------------------------------------------------------- ----*/
        unsigned char Hex;

        Hex = swap(in);  &nb sp;              ; // upper nibble
        Hex &= 0x0F;
        if (Hex<10) Hex += 0x30;
        else Hex += 0x37;
        TxSerial(Hex);
        Hex = in & 0x0F;
        if (Hex<0x0A) Hex += 0x30;
        else Hex += 0x37;
        TxSerial(Hex);
}

/*----------------------------------------------------------------------- ---*/
void Delay_uSeg (unsigned char timeout) {
/*---------------------------------------------------------------------- ----*/
        // delay = 3*timeout + 7uS (including call and return)

        while (1) {
                 timeout--;
                 if (timeout==0) {
                         nop();
                         nop();
                         return;
                 }
        }
}

/*----------------------------------------------------------------------- ---*/
void TxSerial (unsigned char txBuf) {
/*---------------------------------------------------------------------- ----*/

/*
 ;----------------------------------------------------------------- ----------*
 ; Transmit 1 start bit Lo, 8 data bits and 1 stop bit Hi at 9600 bps
 ; No Parity
 ; Byte time = 1.040 mS
 ; Bit  time = 104 uS (0.16% erro w/4.00 Mhz Internal RC)
 ; Input : W = byte to be transmitted
 ; Output: byte transmitted by serial pin
 ;----------------------------------------------------------------- ----------*
*/

    char idx;

        while (1)
        {
                 Carry = 0;           &nbs p;          // start bit
                 for (idx=10; idx; idx--)        // 3us
                 {
                         _TxOUT = Carry;         // 4us
                         Delay_uSeg(28);         // 91us (28*3+7)
                         Carry  = 1;          &nbs p;  // 1us
                         txBuf  = rr(txBuf);     // 1us
                         nop();            &n bsp;     // 1us
                 }             & nbsp;            &nb sp;    // 3us
                 return;
        }
}

/*----------------------------------------------------------------------- ---*/
void RxSerial (void) {
/*---------------------------------------------------------------------- ----*/

/*
 ;----------------------------------------------------------------- ----------*
 ; Receives 1 start bit Lo, 8 data bits and 1 stop bit Hi at 9600 bps
 ; No Parity
 ; Byte time = 1.040 mS
 ; Bit  time = 104 uS (0.16% erro w/4.00 Mhz Internal RC)
 ;
 ; False start bit check
 ;
 ; Start bit hunting timeout = 4*1.283ms
 ;
 ; Input  : none
 ; Output : Carry = 1 => success
 ;          rxBuf = input byte
 ;          Carry = 0 => error (timeout or stop bit=0)
 ;----------------------------------------------------------------- ----------*
*/
        char idx;

        rxBuf = 4;   &n bsp;            &nbs p;             // 5.135 ms timeout
        idx   = 0;

        while (1)
        {
                 while (RxD_pin)            ;      // input "high"
                 {
                         if ((-- idx)==0)
                         {
                          &n bsp;      if ((-- rxBuf)==0)
                          &n bsp;      {
                          &n bsp;            &nbs p; Carry = 0;
                          &n bsp;            &nbs p; return;
                          &n bsp;      }
                         }
                 }

            & nbsp;   Delay_uSeg(14);            ;      // 1/2 bit delay (14*3+7)
                 if (RxD_pin)
                         continue;             ;   // false start bit detection

            & nbsp;   rxBuf = 0x80;           & nbsp;       // 8 bits counter and reception buffer
                 nop();
                 nop();            &n bsp;             // timming adjustment

            & nbsp;   do
                 {
                         Delay_uSeg(30);         // (30*3+7)us
                         Carry = RxD_pin;        // bit read
                         rxBuf = rr(rxBuf);      // store and count
                 }
                 while (Carry==0);
                 Delay_uSeg(30);            ;      // 1 bit delay
                 nop();            &n bsp;             // timming adjustment
                 Carry = RxD_pin;          &nbs p;     // stop bit read
                 return;            & nbsp;            // 100 us availiable
        }
}
 

/*----------------------------------------------------------------------- ---*/
void main (void) {
/*---------------------------------------------------------------------- ----*/

#ifdef _12C508_
//      OSCCAL  = W;   &nbs p;                           &n bsp;     // OscCal Value - OTP part
        OSCCAL  = 0xB0; &nb sp;              ;             & nbsp;    // OscCal Value - Windowed part
        GPIO    = 0x00;
        TRIS    = 0x08;            & nbsp;            &nb sp;       // GP3 input
        OPTION  = 0b11000011;&nb sp;              ;             // Prescaler Timer0 1:16
#else
        INTCON  = 0;                &n bsp;            &nbs p;       // no interrupts
        PCLATH  = 0;                &n bsp;            &nbs p;       // bank 0
        PORTA   = 0;
        PORTB   = 0;
        RP0     = 1;            &nbs p;                        // RAM bank 1
        TRISA   = DEF_TRISA;
        TRISB   = DEF_TRISB;
        OPTION  = 0b11000011;&nb sp;              ;             // Prescaler Timer0 1:16
        RP0     = 0;            &nbs p;                        // RAM bank 0
#endif

        while (1)
        {
                 /* set vars to start */

            & nbsp;   FSR  = buff;          &nb sp;              ;    // pointer to buffer
                 x    = 12;         & nbsp;            &nb sp;       // only 12 bits
                 size = 0;             ;             & nbsp;     // word size in bits
                 min  = 255;          &nbs p;                   // min period
                 max  = 0;                         &n bsp;      // max period

            & nbsp;   /* start bit management */

            & nbsp;   while (IR_input==1);                     // wait for 0
                 /* 2600us start bit */
                 while (IR_input==0);                     // wait for 1

            & nbsp;   TMR0 = 0;             ;             & nbsp;     // start counter
                 do
                 {
                         /* measure high pulse */

            & nbsp;           INDF = 0;             ;           // period: default to zero
                         while (TMR0==0);          &nbs p;     // wait TMR0 advance
                         while (IR_input==1)          & nbsp;  // wait for 0
                         {
                          &n bsp;      if (TMR0==0)            // timer overflow (4096us) ?
                          &n bsp;            &nbs p; goto frame_end; // yes, exit
                         }
                         INDF = TMR0;           &n bsp;        // store period
                         TMR0 = 0;             ;           // start counter
                         med = INDF;           &nb sp;         // save high period
                         FSR++;            &n bsp;             // bump pointer
                         INDF = 0;             ;           // period: default to zero
                         size++;            & nbsp;            // inc bit counter

            & nbsp;           /* measure low pulse */

            & nbsp;           while (TMR0==0);          &nbs p;     // wait TMR0 advance
                         while (IR_input==0);             // wait for 1
                         INDF = TMR0;           &n bsp;        // store period
                         TMR0 = 0;             ;           // start counter
                         med += INDF;           &n bsp;        // total period
                         if (med>=max) max = med;        // find max
                         if (med<min)  min = med;        // find min
                         FSR++;            &n bsp;             // bump pointer
                         size++;            & nbsp;            // inc period counter
                         x--;            &nbs p;                // dec max bits
                 }
                 while (x);
frame_end:
                 LED = 1;
                 med  = max - min;
                 med /= 2;
                 med += min;

            & nbsp;   r[0] = 0;
                 r[1] = 0;
                 r[2] = 0;
                 r[3] = 0;

            & nbsp;   FSR  = buff;
                 FSR += size;
                 x = size/2;
                 do
                 {
                         Carry = 0;
                         r[3] = rl(r[3]);
                         r[2] = rl(r[2]);
                         r[1] = rl(r[1]);
                         r[0] = rl(r[0]);
                         FSR--;
                         max = INDF;
                         FSR--;
                         max += INDF;
                         if (max>=med) r[3]++;
                 } while (--x);

            & nbsp;   /* now r[0],r[1],r[2], r[3] has the frame */
                 /* Tx the periods and the encoded word */

            & nbsp;   TxHexAscii(size);
                 TxSerial(0x20);
                 TxHexAscii(med);
                 TxEnter();

            & nbsp;   for(x=0;x<size; x++)
                 {
                         TxHexAscii(buff[x]);
                         TxSerial(0x20);
                 }
                 TxEnter();

            & nbsp;   TxHexAscii(r[0]);
                 TxHexAscii(r[1]);
                 TxHexAscii(r[2]);
                 TxHexAscii(r[3]);

            & nbsp;   TxEnter();
                 LED = 0;
        }
}