That's great Michael, glad you liked it. And it's good to have willing particpants around.

And, if you wanted more macro's... then I'm sure to make you happy today.

Oh boy, where to start.... I guess I'll start at the end result.

What this does is to allow the strings to be sent to up to 7 different "Destinations". Those destinations can be easily defined like this.
Code:
@  Make_Destination  HSER, _HSER_Send
This creates a Destination named "HSER", and everytime the program needs to send a character, it will call the _HSER_Send subroutine.

Each destination needs it's own subroutine to actually send the data. The character is placed in the temp variable before calling it. Here's one for HSER.
Code:
HSER_Send:
     While PIR1.4 = 0 : Wend
     TXREG = temp 
return
To make another Destination for the LCD, is just as easy...
Code:
@  Make_Destination  LCD,  _LCD_Send

LCD_Send:
    LCDOUT temp
Return
Now when using the SendStr macro, you can tell it which destination you want it to go to.

@ SendStr "This is a string", HSER
@ SendStr "1 for the LCD", LCD

You can even combine them to send the data to multiple Destinations.

@ SendStr "This is a string", HSER + LCD

Destination #8 is reserved for a CR,LF option that can be used like this...

@ SendStr "This is a string", HSER + CRLF

Of course, here's the one you were after...
Code:
@  Make_Destination  I2C,  _I2C_Send

I2C_Send:
     ' However you need to do it here...
RETURN
In order to make this work, I ripped up your code pretty bad. Sorry!

For instance, I got rid of the whole Pushing and Popping stuff. I hated to do that, but at least it solves the interrupt problem. The TBLPTR is now loaded from the SendStr macro so that it doesn't need to use the stack to get the address. Major changes to the prntSTR section too. It had all the USART stuff in there that had to come out. The Make_Destination and Director macro's are the real difference that allows the data to be re-directed. I'm sure there will be some questions on them, but for now I'll let you try to figure it out first.

Here's the whole thing.
Code:
SER2_TX      VAR  PORTE.0
SER2_Baud    CON  396
TRISB.6 = 1   ' Set USART TX pin to Output

temp         var  byte
Destination  VAR  BYTE

@CRLF = 0x080    ; Reserve destination #8 for CR,LF after string

'--[ Initialise USART for specified baud rate at current OSC speed ]------------
asm
USART_Init  macro  Baud
    clrf    TXSTA, 0
_SPBRG = (OSC * 1000000) / 16 / Baud - 1     ; calc SPBRG @ High baud rate
    if _SPBRG > 255                          ; if SPBRG is too high
_SPBRG = (OSC * 1000000) / 64 / Baud - 1     ; calc for Low baud rate
        bcf   TXSTA, BRGH, 0                 ; Set BRGH to Low Speed
        if _SPBRG > 255
_SPBRG = 255
        endif
    else                                     
        bsf   TXSTA, BRGH, 0                 ; Set BRGH to High Speed
    endif
    bsf     TXSTA, TXEN, 0                   ; Set Transmit Enable bit
    movlw   _SPBRG          
    movwf   SPBRG, 0                         ; load the calulated SPBRG
    movlw   B'10010000'                      ; enable USART
    movwf   RCSTA, 0
    endm
ENDASM

;----[Make_Destination]---- Compile Time Only - Does not use any Code space ----
ASM
DestinationCount = 0                              ; Global

Make_Destination  macro Nam, Sub
Nam = 1 << DestinationCount                       ; Generate a unique ID
Destination#v(DestinationCount) = Sub             ; Save Subroutines Address
DestinationCount += 1                             
    endm
ENDASM

;----[SendStr] -----------------------------------------------------------------
ASM
SendStr  macro Astring, Dest
  local TheStringData, BypassData
    goto   BypassData                             ; Jump over the data
TheStringData    
    data   Astring,0                              ; Place String Data here
BypassData
    MOVE?CB   Dest, _Destination
    MOVE?CB   low TheStringData, TBLPTRL          ; Load the address of 
    MOVE?CB   low (TheStringData >> 8), TBLPTRH   ;  TheStringData into
    MOVE?CB   low (TheStringData >> 16), TBLPTRU  ;      TABLPTR
    L?CALL    prntSTR
    if (Dest && CRLF) > 0
        L?CALL  _Send_CRLF
    endif
    endm
ENDASM

;----[ This macro will call each of the specified Destinations in sequence ]----
ASM    
Director  macro
  local counter
counter = 0
      while counter < DestinationCount
          btfsc  _Destination, counter
          CALL   Destination#v(counter)
counter += 1          
      endw
    endm    
ENDASM


;---[ These define the Destinations that will be called to output each byte ]---
;                                                     There is currently a  
;                    Name, _Subroutine                MAXimum of 7 destinations
@  Make_Destination  HSER, _HSER_Send
@  Make_Destination  SER2, _SER2_Send
@  Make_Destination  LCD,  _LCD_Send
@  Make_Destination  I2C,  _I2C_Send


Main:
@ USART_Init 19200
@ SendStr "This is a string", HSER + CRLF
@ SendStr "yet another string again", (HSER  + SER2 + CRLF)
@ SendStr "and one more time!", I2C
@ SendStr "1 for the LCD", LCD

Done:
   Goto Done

;-------------------------------------------------------------------------------
HSER_Send:
     While PIR1.4 = 0 : Wend
     TXREG = temp 
return

;-------------------------------------------------------------------------------
SER2_Send:
    SEROUT2  SER2_TX, SER2_Baud, [temp]
Return

;-------------------------------------------------------------------------------
LCD_Send:
    LCDOUT temp
Return

;-------------------------------------------------------------------------------
I2C_Send:
     ' However you need to do it here...
RETURN

;----[prntStr]------------------------------------------------------------------
ASM
;--- TBLPTR should be pointing to 1st character in string before calling -------
prntSTR
Next_Char
    tblrd   *+              ; table read and post increment TBLPTR
    movff   TABLAT,_temp    ; fetch character from message string
    bra     Test_EOM        ; go test for EOM character
Continue                    ; If not EOM then...
    Director                ; Send the byte to each specified destination
    bra     Next_Char       ; fetch next message character from table
Test_EOM
    movlw   .0              ; check for EOM character
    cpfseq  _temp,W         ; compare temp with w, if temp = 0 then end			
    bra     Continue        ; no EOM, so continue
    return                  ;finished with message, return to caller
endasm

;---[Send Carriage Return, Line feed to the dest's specified in last SendStr]---
Send_CRLF:
    temp = 13
    @ Director
    temp = 10
    @ Director
RETURN

end
Note that prntSTR and Send_CRLF must be at the end of the program for the Director to work properly.

Well, have fun, and I hope this is closer to what you were looking for.

Best regards,
Darrel