;;*****************************************************************************
;;*****************************************************************************
;;  Filename:   UART.asm
;;  Version: 5.3, Updated on 2012/3/2 at 9:15:34
;;  Generated by PSoC Designer 5.2.2551
;;
;;  DESCRIPTION:  UART User Module software implementation file for the
;;                22/24/25/26/27xxx families.
;;
;;
;;  NOTE: User Module APIs conform to the fastcall16 convention for marshalling
;;        arguments and observe the associated "Registers are volatile" policy.
;;        This means it is the caller's responsibility to preserve any values
;;        in the X and A registers that are still needed after the API functions
;;        returns. For Large Memory Model devices it is also the caller's 
;;        responsibility to perserve any value in the CUR_PP, IDX_PP, MVR_PP and 
;;        MVW_PP registers. Even though some of these registers may not be modified
;;        now, there is no guarantee that will remain the case in future releases.
;;-----------------------------------------------------------------------------
;;  Copyright (c) Cypress Semiconductor 2012. All Rights Reserved.
;;*****************************************************************************
;;*****************************************************************************


include "m8c.inc"
include "memory.inc"
include "UART.inc"

;-----------------------------------------------
;  Global Symbols
;-----------------------------------------------
;-------------------------------------------------------------------
;  Declare the functions global for both assembler and C compiler.
;
;  Note that there are two names for each API. First name is
;  assembler reference. Name with underscore is name refence for
;  C compiler.  Calling function in C source code does not require
;  the underscore.
;-------------------------------------------------------------------
export  UART_SetTxIntMode
export _UART_SetTxIntMode
export  UART_EnableInt
export _UART_EnableInt
export  UART_DisableInt
export _UART_DisableInt

export  UART_Start
export _UART_Start
export  UART_Stop
export _UART_Stop
export  UART_SendData
export _UART_SendData
export  UART_bReadTxStatus
export _UART_bReadTxStatus
export  UART_bReadRxData
export _UART_bReadRxData
export  UART_bReadRxStatus
export _UART_bReadRxStatus

export  UART_IntCntl
export _UART_IntCntl

export  UART_TxIntMode
export _UART_TxIntMode

export  UART_PutSHexByte
export _UART_PutSHexByte
export  UART_PutSHexInt
export _UART_PutSHexInt

export  UART_CPutString
export _UART_CPutString
export  UART_PutString
export _UART_PutString
export  UART_PutChar
export _UART_PutChar
export  UART_Write
export _UART_Write
export  UART_CWrite
export _UART_CWrite

export  UART_cGetChar
export _UART_cGetChar
export  UART_cReadChar
export _UART_cReadChar
export  UART_iReadChar
export _UART_iReadChar
export  UART_PutCRLF
export _UART_PutCRLF

IF (UART_RXBUF_ENABLE)
export  UART_CmdReset
export _UART_CmdReset
export  UART_bCmdCheck
export _UART_bCmdCheck
export  UART_bCmdLength
export _UART_bCmdLength
export  UART_bErrCheck
export _UART_bErrCheck

export  UART_szGetParam
export _UART_szGetParam
export  UART_szGetRestOfParams
export _UART_szGetRestOfParams
ENDIF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WARNING WARNING WARNING
; The following exports are for backwards compatibility only and should
; not be used for new designs. They may be eliminated in a future release.
; Their status is "NO FURTHER MAINTENANCE". 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
export  bUART_ReadTxStatus
export _bUART_ReadTxStatus
export  bUART_ReadRxData
export _bUART_ReadRxData
export  bUART_ReadRxStatus
export _bUART_ReadRxStatus
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;             END WARNING
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;-----------------------------------------------
; Variable Allocation
;-----------------------------------------------
IF (UART_RXBUF_ENABLE)
    
area UART_RAM (RAM, REL, CON)
    
 ptrParam:   BLK  1

ENDIF

area text (ROM,REL)

;-----------------------------------------------
;  EQUATES
;-----------------------------------------------
bfCONTROL_REG_START_BIT:        equ    1    ; Control register start bit
bfFUNCTION_REG_TX_INT_MODE_BIT: equ 0x10    ; the TX Int Mode bit

area UserModules (ROM, REL, CON)

;=============================================================================
;=============================================================================
;
;     Low-Level Commands
;
;=============================================================================
;=============================================================================

.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_EnableInt
;
;  DESCRIPTION:
;     Enables this UART's interrupt by setting the interrupt enable mask
;     bit associated with this User Module. Remember to call the global
;     interrupt enable function by using the macro: M8C_EnableGInt.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_EnableInt:
_UART_EnableInt:
   RAM_PROLOGUE RAM_USE_CLASS_1
   M8C_EnableIntMask UART_TX_INT_REG, UART_TX_INT_MASK
   M8C_EnableIntMask UART_RX_INT_REG, UART_RX_INT_MASK
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION

    
.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_DisableInt
;
;  DESCRIPTION:
;     Disables this UART's interrupt by clearing the interrupt enable mask bit
;     associated with this User Module.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_DisableInt:
_UART_DisableInt:
   RAM_PROLOGUE RAM_USE_CLASS_1
   M8C_DisableIntMask UART_TX_INT_REG, UART_TX_INT_MASK
   M8C_DisableIntMask UART_RX_INT_REG, UART_RX_INT_MASK
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_SetTxIntMode(BYTE bTxIntMode)
;
;  DESCRIPTION:
;     Sets the Tx Interrupt Mode bit in the Function Register.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     BYTE bTxIntMode - The TX Interrupt mode setting. Use defined masks.
;        Passed in the A register
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
;  THEORY of OPERATION OR PROCEDURE:
;     Sets the TX interrupt mode bit to define whether the interrupt occurs
;     on TX register empty or TX transmit complete
;
 UART_SetTxIntMode:
_UART_SetTxIntMode:
   RAM_PROLOGUE RAM_USE_CLASS_1
   M8C_SetBank1
   and   A, UART_INT_MODE_TX_COMPLETE
   jz    .SetModeRegEmpty
   or    REG[UART_TX_FUNC_REG], bfFUNCTION_REG_TX_INT_MODE_BIT
   M8C_SetBank0
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret

.SetModeRegEmpty:
   and   REG[UART_TX_FUNC_REG], ~bfFUNCTION_REG_TX_INT_MODE_BIT
   M8C_SetBank0
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_Start(BYTE bParity)
;
;  DESCRIPTION:
;     Sets the start bit and parity in the Control register of this user module.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     BYTE bParity - parity setting for the Transmitter and receiver. Use defined masks.
;        Passed in the A register.
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_Start:
_UART_Start:
   RAM_PROLOGUE RAM_USE_CLASS_1
   ; Note, Proxy Class 4 only if receive buffer used; otherwise Proxy Class 1.

   or    A, bfCONTROL_REG_START_BIT
   mov   REG[UART_TX_CONTROL_REG], A
   mov   REG[UART_RX_CONTROL_REG], A
IF ( UART_RXBUF_ENABLE )
   call  _UART_CmdReset
ENDIF
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_Stop
;
;  DESCRIPTION:
;     Disables UART operation.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_Stop:
_UART_Stop:
   RAM_PROLOGUE RAM_USE_CLASS_1
   and   REG[UART_TX_CONTROL_REG], ~bfCONTROL_REG_START_BIT
   and   REG[UART_RX_CONTROL_REG], ~bfCONTROL_REG_START_BIT
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_SendData
;
;  DESCRIPTION:
;     Initiates a transmission of data.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     BYTE  TxData - data to transmit. PASSED in A register.
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_SendData:
_UART_SendData:
   RAM_PROLOGUE RAM_USE_CLASS_1
   mov REG[UART_TX_BUFFER_REG], A
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_bReadTxStatus
;
;  DESCRIPTION:
;     Reads the Tx Status bits in the Control/Status register.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     BYTE  bTxStatus - transmit status data.  Use defined masks for detecting
;           status bits (returned in A)
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_bReadTxStatus:
_UART_bReadTxStatus:
 bUART_ReadTxStatus:                             ; For backwards compatibility only
_bUART_ReadTxStatus:                             ; For backwards compatibility only
   RAM_PROLOGUE RAM_USE_CLASS_1
   mov A,  REG[UART_TX_CONTROL_REG]
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_bReadRxData
;
;  DESCRIPTION:
;     Reads the RX buffer register.  Should check the status regiser to make
;     sure data is valid.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     bRxData - returned in A.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_bReadRxData:
_UART_bReadRxData:
 bUART_ReadRxData:                               ; For backwards compatibility only
_bUART_ReadRxData:                               ; For backwards compatibility only
   RAM_PROLOGUE RAM_USE_CLASS_1
   mov A, REG[UART_RX_BUFFER_REG]
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_bReadRxStatus
;
;  DESCRIPTION:
;     Reads the RX Status bits in the Control/Status register.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     BYTE  bRXStatus - receive status data.  Use the following defined bits
;                       masks: RX_COMPLETE and RX_BUFFER_EMPTY
;           returned in A.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_bReadRxStatus:
_UART_bReadRxStatus:
 bUART_ReadRxStatus:                             ; For backwards compatibility only
_bUART_ReadRxStatus:                             ; For backwards compatibility only
   RAM_PROLOGUE RAM_USE_CLASS_1
   mov A,  REG[UART_RX_CONTROL_REG]
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_TxIntMode
;
;  DESCRIPTION:
;     This function is used to change the TX Interrupt mode.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     A => Tx Interrupt mode
;             0 => Interrupt on TX_Reg_Empty  (Default)
;             1 => Interrupt on TX Complete
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_TxIntMode:
_UART_TxIntMode:
   RAM_PROLOGUE RAM_USE_CLASS_1

   and  A,UART_INT_MODE_TX_COMPLETE
   M8C_SetBank1
   cmp  A,UART_INT_MODE_TX_COMPLETE
   jz   .SetTxCmpMode

   and  reg[UART_TX_FUNC_REG],0xEF               ; Set Interrupt on Tx_Reg_Empty
   jmp  .TxIntMode_End

.SetTxCmpMode:                                       ; Set Interrupt on TX Complete
   or   reg[UART_TX_FUNC_REG],0x10

.TxIntMode_End:
   M8C_SetBank0
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION

    
.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_IntCntl
;
;  DESCRIPTION:
;     This function is used to enable/disable the Rx and Tx interrupt.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     A => Interrupt mask
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
;  THEORY of OPERATION or PROCEDURE:
;     Set or Clears the Tx/Rx user module interrupt enable mask bit in the TX
;     and RX block.
;
 UART_IntCntl:
_UART_IntCntl:
   RAM_PROLOGUE RAM_USE_CLASS_1

   push A
   and  A,UART_ENABLE_RX_INT
   jz   .DisRxInt
     ; Enable Rx Interrupt
   M8C_EnableIntMask UART_RX_INT_REG, UART_RX_INT_MASK
   jmp  .CheckTxInt
.DisRxInt:
     ; Disable Rx Interrupt
   M8C_DisableIntMask UART_RX_INT_REG, UART_RX_INT_MASK

.CheckTxInt:
   pop  A
   and  A,UART_ENABLE_TX_INT
   jz   .DisTxInt
     ; Enable Tx Interrupt
   M8C_EnableIntMask UART_TX_INT_REG, UART_TX_INT_MASK
   jmp  .End_IntCntl
.DisTxInt:
     ; Disable Tx Interrupt
   M8C_DisableIntMask UART_TX_INT_REG, UART_TX_INT_MASK

.End_IntCntl:
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


;=============================================================================
;=============================================================================
;
;     High-Level Commands
;
;=============================================================================
;=============================================================================


;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_PutSHexByte
;
;  DESCRIPTION:
;     Print a byte in Hex (two characters) to the UART Tx
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     A  => (BYTE) Data/char to be printed
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
.LITERAL
UART_HEX_STR:
     DS    "0123456789ABCDEF"
.ENDLITERAL

.SECTION
 UART_PutSHexByte:
_UART_PutSHexByte:
   RAM_PROLOGUE RAM_USE_CLASS_1
   push  A                             ; Save lower nibble
   asr   A                             ; Shift high nibble to right
   asr   A
   asr   A
   asr   A
   and   A,0Fh                         ; Mask off nibble
   index UART_HEX_STR                  ; Get Hex value
   call  UART_PutChar                  ; Write data to screen
   pop   A                             ; Restore value
   and   A,0Fh                         ; Mask off lower nibble
   index UART_HEX_STR                  ; Get Hex value
   call  UART_PutChar                  ; Write data to screen
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_PutSHexInt
;
;  DESCRIPTION:
;     Print an Int in Hex (four characters) to UART Tx
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     Pointer to string
;     A  => ASB of Int
;     X  => MSB of Int
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;

 UART_PutSHexInt:
_UART_PutSHexInt:
   RAM_PROLOGUE RAM_USE_CLASS_1
   swap  A,X
   call  UART_PutSHexByte              ; Print MSB
   mov   A,X                           ; Move LSB into position
   call  UART_PutSHexByte              ; Print LSB
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_PutChar
;
;  DESCRIPTION:
;     Send character out through UART TX port.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     A has Character to send to UART Tx Port
;
;  RETURNS:
;     none
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;

   macro InLinePutChar( Source )
.BufEmptyWaitLoop:
   tst REG[UART_TX_CONTROL_REG], UART_TX_BUFFER_EMPTY     ; Check Tx Status
   jz  .BufEmptyWaitLoop
   mov REG[UART_TX_BUFFER_REG], @Source          ; Write data to Tx Port
   endm

 UART_PutChar:
_UART_PutChar:
   RAM_PROLOGUE RAM_USE_CLASS_1
   InLinePutChar A
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_cGetChar
;
;  DESCRIPTION:
;     Read character from UART RX port.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;      none
;
;  RETURNS:
;     char that is returned from UART
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
;    Program flow will stay in this function until a character is received.
;    If the watchdog timer is used, care must be taken to make sure that
;    the delay between characters is less than the watchdog timeout.
;
 UART_cGetChar:
_UART_cGetChar:
   RAM_PROLOGUE RAM_USE_CLASS_1
   tst REG[UART_RX_CONTROL_REG],UART_RX_REG_FULL    ; Check if a character is ready
   jz  UART_cGetChar                             ; If not loop
   mov A, REG[UART_RX_BUFFER_REG]                ; Get character
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_cReadChar
;
;  DESCRIPTION:
;     Read character from UART RX port.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;      none
;
;  RETURNS:
;     char that is returned from UART
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
;    A valid 0x00 character will be ignored, since a 0x00 return value
;    implies a valid character or an error condition occured.
;
 UART_cReadChar:
_UART_cReadChar:
   RAM_PROLOGUE RAM_USE_CLASS_1
   mov  A,REG[UART_RX_CONTROL_REG]                         ; Get Status of RX
   push A
   and  A,UART_RX_COMPLETE                                 ; Check if a character is ready
   jnz  .RX_DATA_RDY                                       ; Data Ready go read it.
   pop  A
   jmp  .RX_NO_VALID_CHAR

.RX_DATA_RDY:
   mov  A,REG[UART_RX_BUFFER_REG ]          
   swap A,X                                                ; determine if data is valid

   pop  A                                                  ; Check for errors
   and  A,(UART_RX_PARITY_ERROR | UART_RX_FRAMING_ERROR)
   jnz  .RX_NO_VALID_CHAR                                  ; No character, exit
   swap A,X                                                ; Put data in A and exit
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret

.RX_NO_VALID_CHAR:
   mov A,0x00                                              ; Zero out character

 End_UART_cReadChar:
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_iReadChar
;
;  WARNING WARNING WARNING  Negative return value not correct!!!!  We may want
;  to just set a value in the upper byte if error conditions exists.
;
;  DESCRIPTION:
;     Read character from UART RX port.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;      none
;
;  RETURNS:
;     An integer value is returned.  A negative value inplies and error
;     condition, a positive value between 0 and 255 is the return character.
;
;     Error Codes:
;        0x80CC    Parity Error
;        0x40CC    Overrun Error
;        0x20CC    Framing Error
;        0x01CC    No Data available
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_iReadChar:
_UART_iReadChar:
   RAM_PROLOGUE RAM_USE_CLASS_1
   mov  A,REG[UART_RX_CONTROL_REG]                         ; Get Status of RX
                                                           ; Mask only errors and data ready
   and  A,(UART_RX_ERROR|UART_RX_REG_FULL)
   push A
   and  A,UART_RX_COMPLETE                                 ; Check if a character is ready
   jnz  .RX_GET_DATA                                       ; Data Ready go read it.
   pop  A
   or   A,UART_RX_NO_DATA                                  ; Add no data flag
   swap A,X
   jmp  End_UART_iReadChar

.RX_GET_DATA:
   pop  A
   and  A,UART_RX_ERROR
   swap A,X
   mov  A,REG[UART_RX_BUFFER_REG ]                         ; Read data first, then
                                                           ; determine if data is valid

 End_UART_iReadChar:
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_PutString
;
;  DESCRIPTION:
;     Send String out through UART TX port.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     Pointer to String
;     A has MSB of string address
;     X has LSB of string address
;
;  RETURNS:
;     none
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;          
;    Currently only the page pointer registers listed below are modified: 
;          IDX_PP
;
 UART_PutString:
_UART_PutString:
   RAM_PROLOGUE RAM_USE_CLASS_3
   RAM_SETPAGE_IDX A
.PutStringLoop:
   mov   A,[X]                                   ; Get value pointed to by X
   jz    End_PutString                           ; Check for end of string
   call  UART_PutChar                            ; Send character to Tx port
   inc   X                                       ; Advance pointer to next character
   jmp   .PutStringLoop                          ; Get next character

End_PutString:
   RAM_EPILOGUE RAM_USE_CLASS_3
   ret
.ENDSECTION
    
.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_Write
;
;  DESCRIPTION:
;     Send String of length X to serial port
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     Pointer to String
;     [SP-5] Count of characters to send
;     [SP-4] has MSB of string address
;     [SP-3] has LSB of string address
;
;  RETURNS:
;     none
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;          
;    Currently only the page pointer registers listed below are modified: 
;          IDX_PP
;
CNT_LEN:    equ -5                               ; Length of data to send
STR_MSB:    equ -4                               ; MSB pointer of string 
STR_LSB:    equ -3                               ; LSB pointer of string 

 UART_Write:
_UART_Write:
   RAM_PROLOGUE RAM_USE_CLASS_3
   RAM_SETPAGE_IDX2STK                           ; Refer indexed addrs to the stack
   mov   X, SP                                   ; Establish the frame pointer 

.NextByteLoop:
   mov   A, [X+CNT_LEN]                          ; End of the string?
   jz    .End_Write                              ;   Yes, prepare to exit
   dec   [X+CNT_LEN]                             ; Decrement counter

   IF SYSTEM_LARGE_MEMORY_MODEL
   mov   A, [X+STR_MSB]                          ; Load pointer to char to send
   ENDIF

   mov   X, [X+STR_LSB]                          ; Load pointer to char to send
   RAM_SETPAGE_IDX A                             ; switch index pages
   mov   A, [X]                                  ; Grab the data
   InLinePutChar A                               ; Put data in empty TX buf reg
   mov   X, SP                                   ; Recover frame pointer
   RAM_SETPAGE_IDX2STK                           ; Prepare for stack access
   inc   [X+STR_LSB]                             ; Point to next byte, but do not
   jmp   .NextByteLoop                           ;    cross RAM page boundary!

.End_Write:
   RAM_EPILOGUE RAM_USE_CLASS_3
   ret
.ENDSECTION
    

.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_CWrite
;
;             WARNING WARNING NOT COMPLETE
;
;  DESCRIPTION:
;     Send String of length X to serial port
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     [SP-4] MSB of Count of character to send
;     [SP-3] LSB of Count of character to send
;     [SP-2] has MSB of string address
;     [SP-1] has LSB of string address
;
;  RETURNS:
;     none
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
CLEN_MSB:   equ -6           ; MSB Length of data to send
CLEN_LSB:   equ -5           ; LSB Length of data to send
CSTR_MSB:   equ -4           ; MSB pointer of string
CSTR_LSB:   equ -3           ; LSB pointer of string

 UART_CWrite:
_UART_CWrite:
   RAM_PROLOGUE RAM_USE_CLASS_2
   mov   X,SP
.CW_Loop:
   cmp   [X+CLEN_MSB],0x00                  ; Check for zero counter
   jnz   .CW_WRITEIT
   cmp   [X+CLEN_LSB],0x00
   jz    .End_CWrite                        ; Leave if done

.CW_WRITEIT:                                
   push  X                                  ; Save frame pointer
   mov   A,[X+CSTR_MSB]
   mov   X,[X+CSTR_LSB]
   romx                                     ; Get character from ROM
   InLinePutChar A                          ; Put data in empty TX buf reg
   pop   X                                  ; Restore frame pointer
   add   [X+CSTR_LSB],1                     ; Increment the string pointer
   adc   [X+CSTR_MSB],0
   sub   [X+CLEN_LSB],0x01                  ; Dec the counter
   sbb   [X+CLEN_MSB],0x00
   jmp   .CW_Loop

.End_CWrite:
   RAM_EPILOGUE RAM_USE_CLASS_2
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_CPutString
;
;  DESCRIPTION:
;     Send String out through UART TX port.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     Pointer to String
;     A has MSB of string address
;     X has LSB of string address
;
;  RETURNS:
;     none
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_CPutString:
_UART_CPutString:
   RAM_PROLOGUE RAM_USE_CLASS_1
   push  A                                       ; Store ROM pointer
   push  X
   romx                                          ; Get character from ROM
   jz    .End_CPutString
   call  UART_PutChar                            ; Print character
   pop   X
   pop   A
   inc   X                                       ; Inc LSB of pointer
   jnc   UART_CPutString                         ; Check for carry
   inc   A                                       ; Inc MSB of pointer
   jmp   UART_CPutString


.End_CPutString:
   add   SP, -2
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_PutCRLF
;
;  DESCRIPTION:
;     Send a CR and LF
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;
 UART_PutCRLF:
_UART_PutCRLF:
   RAM_PROLOGUE RAM_USE_CLASS_1
   mov  A,0x0D                        ; Send CR
   call UART_PutChar
   mov  A,0x0A                        ; Send LF
   call UART_PutChar
   RAM_EPILOGUE RAM_USE_CLASS_1
   ret
.ENDSECTION


IF (UART_RXBUF_ENABLE)
;=============================================================================
;=============================================================================
;
;     Command Buffer commands
;
;=============================================================================
;=============================================================================

.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_CmdReset
;
;  DESCRIPTION:
;     Reset command string and status flags
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     none.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;          
;    Currently only the page pointer registers listed below are modified: 
;          CUR_PP
;
;  THEORY of OPERATION or PROCEDURE:
;     Clear the command buffer, command counter, and flag.
;
 UART_CmdReset:
_UART_CmdReset:
   RAM_PROLOGUE RAM_USE_CLASS_4
   RAM_SETPAGE_CUR >UART_aRxBuffer
   mov [UART_aRxBuffer], 0x00
   RAM_SETPAGE_CUR >UART_bRxCnt
   mov [UART_bRxCnt], 0x00
   and [UART_fStatus], 0x00
   RAM_SETPAGE_CUR >ptrParam
   mov [ptrParam],0x00
   RAM_EPILOGUE RAM_USE_CLASS_4
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_bCmdCheck
;
;  DESCRIPTION:
;     Check to see if valid command in buffer.
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     BYTE  fStatus - Status of command receive buffer.
;                     Returns non-zero value in A if command is valid.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;          
;    Currently only the page pointer registers listed below are modified: 
;          CUR_PP
;
;  THEORY of OPERATION or PROCEDURE:
;     Read the status and control register.
;
 UART_bCmdCheck:
_UART_bCmdCheck:
   RAM_PROLOGUE RAM_USE_CLASS_4
   RAM_SETPAGE_CUR >UART_fStatus
   mov A,  [UART_fStatus]
   and A, UART_RX_BUF_CMDTERM                    ; Mask off Command status
   RAM_EPILOGUE RAM_USE_CLASS_4
   ret
.ENDSECTION
    

.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_bErrCheck
;
;  DESCRIPTION:
;     Check to see if an error has occured since last CmdReset
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     BYTE  fStatus - Status of command receive buffer.
;                     Returns non-zero value in A if command is valid.
;           0x80 => Parity Error
;           0x40 => OverRun Error
;           0x20 => Framing Error
;           0x10 => Software Buffer OverRun
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;          
;    Currently only the page pointer registers listed below are modified: 
;          CUR_PP
;     Error Status is clear when read.
;
;  THEORY of OPERATION or PROCEDURE:
;     Read RX buffer error status and clear status
;
 UART_bErrCheck:
_UART_bErrCheck:
   RAM_PROLOGUE RAM_USE_CLASS_4
   RAM_SETPAGE_CUR >UART_fStatus
   mov A,  [UART_fStatus]
   and A, UART_RX_BUF_ERROR                      ; Mask off Error status
   and [UART_fStatus], ~UART_RX_BUF_ERROR
   RAM_EPILOGUE RAM_USE_CLASS_4
   ret
.ENDSECTION

.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_bCmdLength
;
;  DESCRIPTION:
;     Get length of command string
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;     none.
;
;  RETURNS:
;     BYTE  bRxCnt    Returns the command length in A.
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;          
;    Currently only the page pointer registers listed below are modified: 
;          CUR_PP
;
 UART_bCmdLength:
_UART_bCmdLength:
   RAM_PROLOGUE RAM_USE_CLASS_4
   RAM_SETPAGE_CUR >UART_bRxCnt
   mov A,  [UART_bRxCnt]
   RAM_EPILOGUE RAM_USE_CLASS_4
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_szGetParam
;
;  DESCRIPTION:
;      Return next parameter from UART Rx buffer
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:  none
;
;  RETURNS:
;     A => MSB of parameter address
;     X => LSB of parameter address
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;          
;    Currently only the page pointer registers listed below are modified: 
;          CUR_PP
;          IDX_PP
;
;     The receive string is modified by placing Null characters at the end
;     of each parameter as they are recovered.
;
;  THEORY OF OPERATION:
;     This function is a stateful generator of addresses to the "parameters"
;     of an input "Command". It scans the (optional) input buffer and breaks
;     each lexically distinct element into a null-terminated string by replacing
;     delimiters with nulls, as appropriate. The state of the generator is 
;     maintained by the private variable ptrParam, which is a buffer-relative
;     offset. The generator is initialized by a call to the function
;     UART_CmdReset which resets the entire buffer to the 'empty'
;     state. Typically this function, UART_szGetParam, is
;     not called until the buffer has been loaded with an entire command
;     (See UART_bCmdCheck).
;
;     Note, there is no special distinction between the "command" and the 
;     "parameters". The first non-delimiter character of the buffer---the first
;     character of the "command"---is also, for the purposes of this function,
;     the first "parameter" to which it returns an address.
;
;     The value of a delimiter (commonly an ascii space, 0x20 and decimal 32)
;     is determined at configuration time by a user module parameter.
;
 UART_szGetParam:
_UART_szGetParam:
   RAM_PROLOGUE RAM_USE_CLASS_4
   RAM_PROLOGUE RAM_USE_CLASS_3
    
   RAM_SETPAGE_CUR >ptrParam
   mov   A, <UART_aRxBuffer                 ; Get address to receive buffer
   add   A, [ptrParam]                      ; Add string offset
   mov   X, A
   RAM_SETPAGE_IDX >UART_aRxBuffer
   mov   A, [X]                             ; Get character pointed by X
   jnz   .SkipOverDelimitersLoop            ; Null? No,  continue...
   push  X                                  ;       Yes, Save LSB of current pointer
   jmp   .End_GetNextParam
                                            ; Check for delimiter and keep looping until
                                            ; all leading delimiters have been found.
.SkipOverDelimitersLoop:
   cmp   A, UART_DELIMITER                  ; Do we have a delimiter?
   jnz   .ParamStartFound                   ;   No,  Bingo! found a parameter
   inc   X                                  ;   Yes, Increment both index and...
   inc   [ptrParam]                         ;          the stored pointer.
   mov   A, [X]                             ; Get character pointed by X
   cmp   [ptrParam], (UART_RX_BUFFER_SIZE -1)   ; End of buffer?
   jnz   .SkipOverDelimitersLoop            ;   No,  continue the scan

.EndOfString:                               ;   Yes, end of string found...
   push  X                                  ;        Save ptr
.TerminateString:
   mov   [X], 0x00                          ; Make sure string is zero
   jmp   .End_GetNextParam

.ParamStartFound:
   push  X                                  ; Beginning of parameter found, save pointer

.ParamLoop:                                 ; Now loop until end of parameter found.
   inc   X                                  ; Advance pointers.
   inc   [ptrParam]
   cmp   [ptrParam], (UART_RX_BUFFER_SIZE -1)   ; Check if we are at the end of buffer
   jz    .TerminateString
   mov   A, [X]                             ; Get next character
   jz    .End_GetNextParam
   cmp   A, UART_DELIMITER                  ; Check if we have a delimiter
   jnz   .ParamLoop                         ; Still no delimiter, loop again
   mov   [X], 0x00                          ; Replace delimiter with null for end of substring
   inc   [ptrParam]
   cmp   [ptrParam], (UART_RX_BUFFER_SIZE -1)   ; Check if we are at the end of buffer
   jnz   .End_GetNextParam                  ; If not end of string leave
   mov   [ptrParam], (UART_RX_BUFFER_SIZE -1)   ; Reset pointer to end of string.

.End_GetNextParam:
   pop   X
   push  X
   cmp   [X], 0x00
   jnz   .NotNullString
   pop   X
   mov   X, 0x00
   mov   A, X
   RAM_EPILOGUE RAM_USE_CLASS_3
   RAM_EPILOGUE RAM_USE_CLASS_4
   ret

.NotNullString:
   pop  X
   mov  A, >UART_aRxBuffer                  ; Return pointer
   RAM_EPILOGUE RAM_USE_CLASS_3
   RAM_EPILOGUE RAM_USE_CLASS_4
   ret
.ENDSECTION


.SECTION
;-----------------------------------------------------------------------------
;  FUNCTION NAME: UART_szGetRestOfParams
;
;  DESCRIPTION:
;      Returns a pointer to the rest of the UART RX buffer
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:  none
;
;  RETURNS:
;     A => MSB of parameter
;     X => LSB of parameter
;
;  SIDE EFFECTS:
;    The A and X registers may be modified by this or future implementations
;    of this function.  The same is true for all RAM page pointer registers in
;    the Large Memory Model.  When necessary, it is the calling function's
;    responsibility to perserve their values across calls to fastcall16 
;    functions.
;          
;    Currently only the page pointer registers listed below are modified: 
;          CUR_PP
;
 UART_szGetRestOfParams:
_UART_szGetRestOfParams:
   RAM_PROLOGUE RAM_USE_CLASS_4
   RAM_SETPAGE_CUR >ptrParam
   mov  A, <UART_aRxBuffer                  ; Get address to receive buffer
   add  A, [ptrParam]                       ; Add string offset
   mov  X,A
   mov  A,>UART_aRxBuffer                   ; Return pointer
   RAM_EPILOGUE RAM_USE_CLASS_4
   ret
.ENDSECTION

ENDIF


; End of File UART.asm
