A solution would be to:

1. Start TIMER1 and enable interrupts.
2. Wait for a "!" then grab the message then disable interrupts.
3. If TIMER1 overflows and the interrupt occurs - execute the "Lost_Signal" code.
That approach works. I've done this in an old project for a momentary RF decoder.

This is just a small chunk, but it shows enough to get the point across...;o}
Code:
ASM
RESET_VT
    movwf  wsave       ; Save W
    swapf  STATUS,W    ; Swap STATUS to W (swap avoids changing STATUS)
    clrf   STATUS      ; Clear STATUS
    movwf  ssave       ; Save swapped STATUS
    movf   PCLATH,W    ; Move PCLATH to W
    movwf  psave       ; Save PCLATH
    movf   FSR,W       ; Move FSR to W
    movwf  fsave       ; Save FSR
    
    ; Do interrupt stuff here
    bcf   T1CON,TMR1ON ; Stop Timer1
    clrf  TMR1L        ; Clear low byte
    clrf  TMR1H        ; Clear high byte
    bcf   PIR1,TMR1IF  ; Clear Timer1 interrupt flag bit
    clrf  GPIO         ; Clear outputs on button release
    clrf  MATCH        ; Clear match variable
    
    ; Restore FSR, PCLATH, STATUS and W registers
    movf  fsave,W      ; retrieve FSR value
    movwf FSR          ; Restore it to FSR
    movf  psave,W      ; Retrieve PCLATH value
    movwf PCLATH       ; Restore it to PCLATH
    swapf ssave,W      ; Get swapped STATUS value (swap to avoid changing STATUS)
    movwf STATUS       ; Restore it to STATUS
    swapf wsave,F      ; Swap the stored W value
    swapf wsave,W      ; Restore it to W (swap to avoid changing STATUS)
    bsf   T1CON,TMR1ON ; Re-enable Timer1 before exiting interrupt handler
    retfie             ; Return from the interrupt
ENDASM
 
MAIN:         
    ' Fire up Timer1 before entry to serial input routine
    T1CON.0 = 1
    
    ' at 4MHz Timer1 overflows in ~65.5mS if no Synch byte
    ' and serial data arrive before over-flow.
    
    ' Wait for Synch byte, then get new inbound data & checksum
    SERIN2 D_IN,BAUD,[WAIT(Synch),DAT_IN1,DAT_IN2,CHK_SUM]
    
    T1CON.0 = 0    ' Stop Timer1 once data has been received
    TMR1L = 0      ' Clear low byte
    TMR1H = 0      ' Clear high byte
    
    ' / **** Begin data validation **** /
You'll want to use an assembly interrupt since on interrupt would hang waiting for the
SERIN2 routine to finish.