I've modified Darrel's sample code from this thread (switching to use TMR1 - I couldn't get TMR0 to work) and hooked up my LabX1 board with a PIC16F877A chip jumpered to 4Mhz. It would appear to work except for when the SYNC character appears twice and depending on where it yields a different result.

Code:
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
            'Based on Hserin with Darrel Taylor's Instant Interrupts
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
'    Program to echo incoming serial data.
'  RX SYNC byte, if good: ChipID byte, if good: COMMAND, if good: ADJUSTMENT

'   MPASM, LabX-1 , PBP2.47, Using PIC 16F877A @ 4mHz, 9600 Baud
'   Using Hardware USART and MAX232 to MCS Serial Communicator on PC

' ***************************************************************
' >>>>>>>>>>>>>>>>>    Slave IC ID: 1    <<<<<<<<<<<<<<<<<<<<<<<
' ***************************************************************

ChipID          CON "1"

DEFINE OSC 4

DEFINE HSER_RCSTA 90h ' enable serial port, 
DEFINE HSER_TXSTA 24h ' enable transmit, 
DEFINE HSER_BAUD 9600 ' set baudrate to 9600                   
DEFINE HSER_CLOERR  1 ' automatic clear overrun error  

TRISD  = %00000000    ' D to outputs for the LEDs
TRISC  = %10000000    ' PORTC.7 is the RX input, PORTC.6 is the TX output
ADCON1 = %00001111    ' Set up ADCON1 register no matter what yr doing!!!                      
        
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
INCLUDE "DT_INTS-14.bas"     ' Base Interrupt System
INCLUDE "ReEnterPBP.bas"     ' Include if using PBP interrupts

;-- Place a copy of these variables in your Main program -------------------
;--   The compiler will tell you which lines to un-comment                --
;--   Do Not un-comment these lines                                       --
;---------------------------------------------------------------------------
;wsave   VAR BYTE    $20     SYSTEM      ' location for W if in bank0
wsave   VAR BYTE    $70     SYSTEM      ' alternate save location for W 
                                         ' if using $70, comment wsave1-3

' --- IF any of these three lines cause an error ?? ------------------------
'       Comment them out to fix the problem ----
' -- Which variables are needed, depends on the Chip you are using -- 
wsave1  VAR BYTE    $A0     SYSTEM      ' location for W if in bank1
wsave2  VAR BYTE    $120    SYSTEM      ' location for W if in bank2
wsave3  VAR BYTE    $1A0    SYSTEM      ' location for W if in bank3
' --------------------------------------------------------------------------

':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    '   Variable definition
':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        
led0       var     PORTD.0
led1       var     PORTD.1
led2       var     PORTD.2
led7       var     PORTD.7

ERROR_LED  VAR led7            ' rename the LED's
LATE_LED   VAR led2
HEART_LED  VAR led0

LEDonDELAY CON 4

TxEndChar   CON "~"
SyncByte    CON "S"

CmdBuf      VAR BYTE
AdjBuf      VAR BYTE
SerialData  VAR BYTE
ERRORtime   VAR BYTE
LATEtime    VAR BYTE
HEARTtime   VAR BYTE

state       VAR BYTE         
  Sync      VAR state.0      ' sync byte received
  ForMe     VAR state.1      ' packet is for this device
  CmdRcvd   VAR state.2      ' command has been received
  AdjRcvd   VAR state.3      ' adjustment factor has been received
  ERROR     VAR state.4      ' sync received out of order
  LATE      VAR state.5      ' command received before last one was processed

state = 0                    ' Initialize default value

' ***************************************************************
' ASM Interrupt Definitions
' ***************************************************************

ASM
INT_LIST  macro    ; IntSource,           Label,  Type, ResetFlag?
        INT_Handler   TMR1_INT,      ReloadTMR1,   ASM,  no       ; MUST be first
        INT_Handler   TMR1_INT,      _T1handler,   PBP,  yes
        INT_Handler     RX_INT,        _GetBytes,  PBP,  no
    endm
    INT_CREATE     ; Creates the interrupt processor
ENDASM

;--- Change these to match the desired interrupt frequency -------------------
;--- See http://DarrelTaylor.com/DT_INTS-14/TimerTemplate.html for more Info.
@Freq       = 10                  ; Frequency of Interrupts in Hz
@Prescaler  = 2                   ; Timers Prescaler setting
T1CON = $10                       ; $30 = Prescaler 1:8, TMR1 OFF
; $00=1:1, $10=1:2, $20=1:4, $30=1:8 --  Must match @Prescaler value

' Enable interrupts
@ INT_ENABLE  RX_INT        ; enable USART RX_INT interrupts
@ INT_ENABLE  TMR1_INT      ; enable Timer 1 interrupts
GOSUB StartTimer            ; Start Timer 1 ('MotorRPM' will be saved on every
                            ; interrupt if dirty

Main:
;        High HEART_LED    ' Turn on LED connected to PORTD.0
;        Pause 500       ' Delay for .5 seconds

;        Low HEART_LED         ' Turn off LED connected to PORTD.0
;        Pause 500       ' Delay for .5 seconds

    IF (CmdRcvd AND AdjRcvd) THEN GOSUB ProcessCmdAdj    ' Process any incomming data

    IF ERROR THEN                          ' if there's been an Error
        HIGH ERROR_LED                     '   Turn ON ERROR LED
        ERROR = 0                          '   reset the error flag
        ERRORtime = LEDonDELAY             '   start countdown till LED-OFF
        HSEROUT ["Error",13,10]
    ENDIF
    IF LATE THEN                           ' if command took too long
        HIGH LATE_LED                      '   Turn ON LATE LED
        LATE = 0                           '   reset the LATE flag
        LATEtime = LEDonDELAY              '   start countdown till LED-OFF
        HSEROUT ["Late",13,10]
    ENDIF
GOTO Main

'*********** Process received command **************************************
ProcessCmdAdj:
    hserout ["Cmd: ",CmdBuf, _ ' send ChipID, Command, Adjustment and CR/LF
             " [",DEC CmdBuf,"]",", Adj:",AdjBuf,_
             " [",DEC AdjBuf,"]",13,10] 
;    hserout ["Cmd: ",CmdBuf, " [", _
;            DEC CmdBuf,"]",13,10]        
    CmdRcvd = 0                            ' indicate CMD & ADJ has been processed
    AdjRcvd = 0
RETURN

' ***************************************************************
' [TMR1_INT - interrupt handler]
' ***************************************************************
T1handler:
    IF ERRORtime > 0 THEN                  ' if the Error LED is ON
        ERRORtime = ERRORtime - 1          '   decrement the count
        IF ERRORtime = 0 THEN              '   when it reaches 0
            LOW ERROR_LED                  '   turn the Error LED OFF
        ENDIF
    ENDIF        
    IF LATEtime > 0 THEN                   ' if the LATE LED is ON
        LATEtime = LATEtime - 1            '   decrement the count
        IF LATEtime = 0 THEN               '   when it reaches 0
            LOW LATE_LED                   '   turn the LATE LED OFF
        ENDIF
    ENDIF
    HEARTtime = HEARTtime + 1              ' Toggle heartbeat ~.5sec
    IF HEARTtime = 7 THEN
        HEARTtime = 0
        TOGGLE HEART_LED
    ENDIF       
@ INT_RETURN

' ***************************************************************
' [RX_INT - interrupt handler]
' ***************************************************************
GetBytes: 

' Henrik's suggestion (http://www.picbasic.co.uk/forum/showthread.php?t=17685)
' I'd probably send equally sized packets each time, perhaps something like sync,
' ID, 8 bytes of data, checksum. The slave then waits for the sync, grabs x
' number of bytes into an array, evaluates the checksum and if OK checks the ID.
' If ID matches it acts on the data otherwise it does nothing.

' Darrel Taylor's code (http://www.picbasic.co.uk/forum/showthread.php?t=9932&p=65066#post65066)

    HSERIN [Serialdata]                    ' Get the serial data

    IF Serialdata = SyncByte THEN          ' if it's a Sync byte,
        IF Sync THEN ERROR = 1             '   last command was corrupted
        Sync = 1                           '   indicate Sync was rcvd
        ForMe = 0                          '   ID has not been rcvd
    ELSE
        IF Sync THEN
            IF !ForME THEN                 ' if we haven't rcvd the ID
                IF Serialdata = ChipID THEN'   and this byte matches the ID
                    ForMe = 1              '   indicate ID rcvd
                ELSE
                    Sync = 0               ' Not my packet
                    ForMe = 0              '   reset receive state    
                ENDIF                      '   and wait for next Sync
            ELSEIF !CmdRcvd THEN
                CmdBuf = serialdata        ' store the command
                IF CmdRcvd THEN LATE = 1   '   last command not finished
                CmdRcvd = 1                '   indicate a command was rcvd
                ;Sync = 0                   '   reset receive state
                ;ForMe = 0  
            ELSE
                AdjBuf = SerialData        ' store the command
                IF AdjRcvd THEN LATE = 1   '   last adjustment not finished
                AdjRcvd = 1                '   indicate an adjustment was rcvd
                Sync = 0                   '   reset receive state
                ForMe = 0                
            ENDIF
        ENDIF
    ENDIF

@ INT_RETURN

;---[TMR1 reload - interrupt handler]-----------------------------------------
ASM                               ; Calculate Timer Reload Constant
ReloadInst  = 8                   ; # of Intructions used to reload timer
  if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
MaxCount    = 65536 + (ReloadInst / Prescaler)
TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
    if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
        error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
    endif
  else
      error Invalid Prescaler
  endif
ENDASM

@Timer1 = TMR1L                   ; map timer registers to a word variable
Timer1       VAR WORD EXT
TimerReload  CON EXT              ; Get the External Constant
TMR1ON       VAR T1CON.0          ; Alias the Timers ON/OFF bit

;---Reload Timer1------
ASM
ReloadTMR1
    MOVE?CT  0, T1CON, TMR1ON     ;  1     stop timer
    MOVLW    LOW(TimerReload)     ;  1     Add TimerReload to the 
    ADDWF    TMR1L,F              ;  1     value in Timer1
    BTFSC    STATUS,C             ;  1/2
    INCF     TMR1H,F              ;  1
    MOVLW    HIGH(TimerReload)    ;  1
    ADDWF    TMR1H,F              ;  1
    MOVE?CT  1, T1CON, TMR1ON     ;  1     start timer
  INT_RETURN
ENDASM

;---Start/Stop controls -----
StartTimer:
    Timer1  = TimerReload         ; Load Timer
    TMR1ON = 1                    ; start timer
RETURN

StopTimer:
    TMR1ON = 0                    ; stop timer
RETURN
I need to capture a 3rd byte (the adjustment to the command feature on the indicated chip) but something's not right - I get strange text in the receive window of the MCS serial window.

Serial window config:
Name:  Serial_0.png
Views: 2645
Size:  60.9 KB
Proper sequence yields correct result:
Name:  Serial_1.png
Views: 2634
Size:  48.4 KB
Correct error msg:
Name:  Serial_1b.png
Views: 2610
Size:  52.3 KB
Weird error msg:
Name:  Serial_2.png
Views: 2656
Size:  57.2 KB
Weird error msg 2:
Name:  Serial_3.png
Views: 2667
Size:  48.6 KB

On a side note, any idea why some of the LEDs in the bargraph light up when they're not supposed to? Seems like every time I plug in the Lab X1, different ones light up.
Name:  photo.JPG
Views: 2543
Size:  176.4 KB