Great job Darrel! It just keeps getting better and better.

Here is the tested version of the code incorporating your changes:
Code:
DEFINE LOADER_USED 1
DEFINE OSC 40       ' change to suit oscillator speed
setSPBRG con 129    ' 19200 baudrate w/ 40Mhz OSC
                    ' (change to suit requirements)

temp var byte       ' temporary storage for character

    Goto main
' Send String Macro (must be located prior to Main)
ASM
SendStr  macro Astring
    call _prntSTR
    data Astring,0
    endm
ENDASM

'=======================================
Main:
   CALL USART_Init  ' initialize hardware USART

' send messages through RS232
' format #1
@ SendStr "This is a string" 
@ SendStr "yet another string again"
@ SendStr "and one more time!"

' format #2
ASM
  SendStr "This is a string" 
  SendStr "yet another string again"
  SendStr "and one more time!"
ENDASM

Done:
   Goto Done        ' loop forever

'=======================================

' USART initialization and print string code (locate anywhere)
asm
_USART_Init
    movlw   B'00100100'     ; initialize USART
    movwf   TXSTA           ; 8-bit, Async, High Speed
    movlw   _setSPBRG       ; pass constant to SPBRG to
    movwf   SPBRG           ; determine baudrate to be used
    movlw   B'10010000'     ; enable USART
    movwf   RCSTA
    return

_prntSTR
;copy return address to TBLPTR and then pop it off the stack
    movf    TOSU,W
    movwf   TBLPTRU
    movf    TOSH,W
    movwf   TBLPTRH
    movf    TOSL,W
    movwf   TBLPTRL
    POP

;TBLPTR should now be pointing to 1st character in string
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...
    movf    _temp,W         ; move character into TXREG and...
    movwf   TXREG           ; send it!
    btfss   TXSTA,TRMT      ; has it been transmitted?
    goto    $-2             ; If not, keep checking
    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
    movlw   "\r"            ; move carriage return into TXREG and...
    movwf   TXREG           ; send it!
    btfss   TXSTA,TRMT      ; has it been transmitted?
    goto    $-2             ; If not, keep checking	
    movlw   "\n"            ; move line feed into TXREG and...
    movwf   TXREG           ; send it!
    btfss   TXSTA,TRMT      ; has it been transmitted?
    goto    $-2             ; If not, keep checking

;use incremented value of TBLPTR as new return address (push it)
    PUSH
    movf   TBLPTRU,W
    movwf   TOSU
    movf   TBLPTRH,W
    movwf   TOSH
    movf   TBLPTRL,W
    movwf   TOSL
    return                  ;finished with message, return to caller
endasm
So now we have a single line RS232 messaging system that will work properly, assuming you don't use any interrupts in the rest of your code (that's right, this will probably fail with interrupts enabled).

Now to get the interrupt compatible version we'll need an efficient way to disable global interrupts when doing the stack manipulations. Since there are 2 levels of interrupts (GIEL and GIEH) possible on an 18 series pic it's a little more complicated. Before I dive into this does anyone have a good suggestion or example code?

Thanks,