;;*****************************************************************************
;;*****************************************************************************
;;  FILENAME: USBUART_std.asm
;;  Version: 1.0, Updated on 2008/04/07 at 12:05:03
;;  Generated by PSoC Designer ???
;;
;;  DESCRIPTION: USB Device User Module software implementation file
;;               for the CY8C24090 and CY7C64215 family of devices.
;;
;;  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 preserve 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 2006. All Rights Reserved.
;;*****************************************************************************
;;*****************************************************************************

include "m8c.inc"
include "USBUART_macros.inc"
include "USBUART.inc"

;-----------------------------------------------
;  Constant Data Allocation
;-----------------------------------------------
AREA UserModules (ROM, REL)

;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_Not_Supported
;
;  DESCRIPTION:
;
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------

; d2h_std_dev
IF (USB_CB_SRC_d2h_std_dev_00 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_00
USBUART_CB_d2h_std_dev_00:
ENDIF
IF (USB_CB_SRC_d2h_std_dev_01 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_01
USBUART_CB_d2h_std_dev_01:
ENDIF
IF (USB_CB_SRC_d2h_std_dev_02 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_02
USBUART_CB_d2h_std_dev_02:
ENDIF
IF (USB_CB_SRC_d2h_std_dev_03 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_03
USBUART_CB_d2h_std_dev_03:
ENDIF
IF (USB_CB_SRC_d2h_std_dev_04 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_04
USBUART_CB_d2h_std_dev_04:
ENDIF
IF (USB_CB_SRC_d2h_std_dev_05 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_05
USBUART_CB_d2h_std_dev_05:
ENDIF
IF (USB_CB_SRC_d2h_std_dev_06 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_06
USBUART_CB_d2h_std_dev_06:
ENDIF
IF (USB_CB_SRC_d2h_std_dev_07 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_07
USBUART_CB_d2h_std_dev_07:
ENDIF
IF (USB_CB_SRC_d2h_std_dev_08 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_dev_08
USBUART_CB_d2h_std_dev_08:
ENDIF

; h2d_std_dev
IF (USB_CB_SRC_h2d_std_dev_00 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_00
USBUART_CB_h2d_std_dev_00:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_01 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_01
USBUART_CB_h2d_std_dev_01:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_02 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_02
USBUART_CB_h2d_std_dev_02:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_03 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_03
USBUART_CB_h2d_std_dev_03:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_04 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_04
USBUART_CB_h2d_std_dev_04:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_05 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_05
USBUART_CB_h2d_std_dev_05:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_06 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_06
USBUART_CB_h2d_std_dev_06:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_07 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_07
USBUART_CB_h2d_std_dev_07:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_08 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_08
USBUART_CB_h2d_std_dev_08:
ENDIF
IF (USB_CB_SRC_h2d_std_dev_09 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_dev_09
USBUART_CB_h2d_std_dev_09:
ENDIF

; d2h_std_ifc
IF (USB_CB_SRC_d2h_std_ifc_00 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_00
USBUART_CB_d2h_std_ifc_00:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_01 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_01
USBUART_CB_d2h_std_ifc_01:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_02 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_02
USBUART_CB_d2h_std_ifc_02:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_03 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_03
USBUART_CB_d2h_std_ifc_03:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_04 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_04
USBUART_CB_d2h_std_ifc_04:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_05 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_05
USBUART_CB_d2h_std_ifc_05:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_06 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_06
USBUART_CB_d2h_std_ifc_06:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_07 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_07
USBUART_CB_d2h_std_ifc_07:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_08 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_08
USBUART_CB_d2h_std_ifc_08:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_09 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_09
USBUART_CB_d2h_std_ifc_09:
ENDIF
IF (USB_CB_SRC_d2h_std_ifc_10 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ifc_10
USBUART_CB_d2h_std_ifc_10:
ENDIF

; d2h_std_ifc
IF (USB_CB_SRC_h2d_std_ifc_00 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_ifc_00
USBUART_CB_h2d_std_ifc_00:
ENDIF

; d2h_std_ep
IF (USB_CB_SRC_d2h_std_ep_00 & USB_NOT_SUPPORTED)
export  USBUART_CB_d2h_std_ep_00
USBUART_CB_d2h_std_ep_00:
ENDIF

; h2d_std_ep
IF (USB_CB_SRC_h2d_std_ep_00 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_ep_00
USBUART_CB_h2d_std_ep_00:
ENDIF
IF (USB_CB_SRC_h2d_std_ep_01 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_ep_01
USBUART_CB_h2d_std_ep_01:
ENDIF
IF (USB_CB_SRC_h2d_std_ep_02 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_ep_02
USBUART_CB_h2d_std_ep_02:
ENDIF
IF (USB_CB_SRC_h2d_std_ep_03 & USB_NOT_SUPPORTED)
export  USBUART_CB_h2d_std_ep_03
USBUART_CB_h2d_std_ep_03:
ENDIF

export  USBUART_Not_Supported
export _USBUART_Not_Supported
USBUART_Not_Supported:
_USBUART_Not_Supported:
   MOV    A, 0                         ; Count 0
   MOV    X, USB_MODE_STALL_IN_OUT     ; Stall the request
   LJMP   USBUART_EP0_UPD_MODE_EXIT
;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_d2h_std_dev_00
;
;  DESCRIPTION:   Get Device Status
;
;****************************************************************
; STANDARD DEVICE IN REQUEST: Get_Device_Status
;****************************************************************
;
; bmRequestType  : (IN | STANDARD | DEVICE)       = 80h
; bRequest       : GET_STATUS                     = 00h
; wValue         : RESERVED                       = 0000h
; wIndex         : RESERVED                       = 0000h
; wLength        : SIZEOF_ENDPOINT_STATUS         = 0002h
;
; The GET_DEVICE_STATUS request returns the current device status.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_d2h_std_dev_00 & USB_UM_SUPPLIED)
.LITERAL
GetStatusTransferDescrTable:
    TD_START_TABLE 1                   ; One entry
    TD_ENTRY    USB_DS_RAM, 2, USBUART_TransferBuffer, NULL_PTR  ; Intermediate Buffer
.ENDLITERAL
export  USBUART_CB_d2h_std_dev_00
USBUART_CB_d2h_std_dev_00:
    MOV     [USBUART_t2], 0            ; Use the UM temp var--Selector

    MOV     [USBUART_TransferBuffer+1], 0  ; Use the UM Transfer Buffer
    MOV     [USBUART_TransferBuffer], [USBUART_DeviceStatus]

    MOV     A,>GetStatusTransferDescrTable  ; Get the ROM Address MSB
    MOV     X,<GetStatusTransferDescrTable  ; Get the ROM Address LSB
    JMP     USBUART_GetTableEntry_Local_Std
ENDIF

;-----------------------------------------------------------------------------
;  USB 2nd Tier Dispatch Jump Tables for Standard Requests (based on bRequest)
;-----------------------------------------------------------------------------
;  FUNCTION NAME: ;  USB 2nd Tier Dispatch Jump Table
;
;  DESCRIPTION:   The following tables dispatch to the Standard request handler
;                 functions.  (Assumes bmRequestType(5:6) is 0, Standard)
;
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
.LITERAL
USBUART_DT_d2h_std_dev:
;-----------------------------------------------------------------------------

    jmp     USBUART_CB_d2h_std_dev_00
    jmp     USBUART_CB_d2h_std_dev_01
    jmp     USBUART_CB_d2h_std_dev_02
    jmp     USBUART_CB_d2h_std_dev_03
    jmp     USBUART_CB_d2h_std_dev_04
    jmp     USBUART_CB_d2h_std_dev_05
    jmp     USBUART_CB_d2h_std_dev_06
    jmp     USBUART_CB_d2h_std_dev_07
    jmp     USBUART_CB_d2h_std_dev_08

USBUART_DT_d2h_std_dev_End:
USBUART_DT_d2h_std_dev_Size: equ (USBUART_DT_d2h_std_dev_End-USBUART_DT_d2h_std_dev) / 2
USBUART_DT_d2h_std_dev_Dispatch::
    MOV    A, REG[USBUART_EP0DATA + bRequest]
    DISPATCHER USBUART_DT_d2h_std_dev, USBUART_DT_d2h_std_dev_Size, USBUART_Not_Supported

.ENDLITERAL
;-----------------------------------------------------------------------------
.LITERAL
USBUART_DT_h2d_std_dev:
;-----------------------------------------------------------------------------

    jmp     USBUART_CB_h2d_std_dev_00
    jmp     USBUART_CB_h2d_std_dev_01
    jmp     USBUART_CB_h2d_std_dev_02
    jmp     USBUART_CB_h2d_std_dev_03
    jmp     USBUART_CB_h2d_std_dev_04
    jmp     USBUART_CB_h2d_std_dev_05
    jmp     USBUART_CB_h2d_std_dev_06
    jmp     USBUART_CB_h2d_std_dev_07
    jmp     USBUART_CB_h2d_std_dev_08
    jmp     USBUART_CB_h2d_std_dev_09

USBUART_DT_h2d_std_dev_End:
USBUART_DT_h2d_std_dev_Size: equ (USBUART_DT_h2d_std_dev_End-USBUART_DT_h2d_std_dev) / 2
USBUART_DT_h2d_std_dev_Dispatch::

    MOV     A, REG[USBUART_EP0DATA + bRequest]
    DISPATCHER USBUART_DT_h2d_std_dev, USBUART_DT_h2d_std_dev_Size, USBUART_Not_Supported

.ENDLITERAL

;-----------------------------------------------------------------------------
.LITERAL
USBUART_DT_d2h_std_ifc:
;-----------------------------------------------------------------------------

    jmp     USBUART_CB_d2h_std_ifc_00
    jmp     USBUART_CB_d2h_std_ifc_01
    jmp     USBUART_CB_d2h_std_ifc_02
    jmp     USBUART_CB_d2h_std_ifc_03
    jmp     USBUART_CB_d2h_std_ifc_04
    jmp     USBUART_CB_d2h_std_ifc_05
    jmp     USBUART_CB_d2h_std_ifc_06
    jmp     USBUART_CB_d2h_std_ifc_07
    jmp     USBUART_CB_d2h_std_ifc_08
    jmp     USBUART_CB_d2h_std_ifc_09
    jmp     USBUART_CB_d2h_std_ifc_10

USBUART_DT_d2h_std_ifc_End:
USBUART_DT_d2h_std_ifc_Size: equ (USBUART_DT_d2h_std_ifc_End-USBUART_DT_d2h_std_ifc) / 2
USBUART_DT_d2h_std_ifc_Dispatch::
    CMP     [USBUART_Configuration], 0 ; Is the device configured?
    JNZ     .configured                ; Jump on configured
    JMP    _USBUART_Not_Supported      ; Stall the request if not configured
; Jump here if the device is configured
.configured:
    MOV     A, REG[USBUART_EP0DATA + bRequest]
    DISPATCHER USBUART_DT_d2h_std_ifc, USBUART_DT_d2h_std_ifc_Size, USBUART_Not_Supported
.ENDLITERAL

;-----------------------------------------------------------------------------
.LITERAL
USBUART_DT_h2d_std_ifc:
;-----------------------------------------------------------------------------

    jmp     USBUART_CB_h2d_std_ifc_00

USBUART_DT_h2d_std_ifc_End:
USBUART_DT_h2d_std_ifc_Size: equ (USBUART_DT_h2d_std_ifc_End-USBUART_DT_h2d_std_ifc) / 2
USBUART_DT_h2d_std_ifc_Dispatch::
    CMP     [USBUART_Configuration], 0 ; Is the device configured?
    JNZ     .configured                ; Jump on configured
    JMP    _USBUART_Not_Supported      ; Stall the request if not configured
; Jump here if the device is configured
.configured:
    MOV     A, REG[USBUART_EP0DATA + bRequest]
    DISPATCHER USBUART_DT_h2d_std_ifc, USBUART_DT_h2d_std_ifc_Size, USBUART_Not_Supported
.ENDLITERAL

;-----------------------------------------------------------------------------
.LITERAL
USBUART_DT_d2h_std_ep:
;-----------------------------------------------------------------------------
    jmp     USBUART_CB_d2h_std_ep_00

USBUART_DT_d2h_std_ep_End:
USBUART_DT_d2h_std_ep_Size: equ (USBUART_DT_d2h_std_ep_End-USBUART_DT_d2h_std_ep) / 2
USBUART_DT_d2h_std_ep_Dispatch::
    CMP     [USBUART_Configuration], 0 ; Is the device configured?
    JNZ     .configured                ; Jump on configured

    MOV     A, REG[USBUART_EP0DATA + wIndexHi] ; Is the request for EP0?
    MOV     [USBUART_t2], A            ; Use the UM temp var--Selector
    MOV     A, REG[USBUART_EP0DATA + wIndexLo] ;
    OR      [USBUART_t2], A            ; Use the UM temp var--Selector
    JZ      .ep0_request

    JMP    _USBUART_Not_Supported      ; Stall the request if not configured
; Jump here if the device is configured or EP0 request
.configured:
.ep0_request:
    MOV     A, REG[USBUART_EP0DATA + bRequest]
    DISPATCHER USBUART_DT_d2h_std_ep, USBUART_DT_d2h_std_ep_Size, USBUART_Not_Supported

.ENDLITERAL

;-----------------------------------------------------------------------------
.LITERAL
USBUART_DT_h2d_std_ep:
;-----------------------------------------------------------------------------
    jmp     USBUART_CB_h2d_std_ep_00
    jmp     USBUART_CB_h2d_std_ep_01
    jmp     USBUART_CB_h2d_std_ep_02
    jmp     USBUART_CB_h2d_std_ep_03

USBUART_DT_h2d_std_ep_End:
USBUART_DT_h2d_std_ep_Size: equ (USBUART_DT_h2d_std_ep_End-USBUART_DT_h2d_std_ep) / 2
USBUART_DT_h2d_std_ep_Dispatch::
    CMP     [USBUART_Configuration], 0 ; Is the device configured?
    JNZ     .configured                ; Jump on configured

    MOV     A, REG[USBUART_EP0DATA + wIndexHi] ; Is the request for EP0?
    MOV     [USBUART_t2], A            ; Use the UM temp var--Selector
    MOV     A, REG[USBUART_EP0DATA + wIndexLo] ;
    OR      [USBUART_t2], A            ; Use the UM temp var--Selector
    JZ      .ep0_request

    JMP    _USBUART_Not_Supported      ; Stall the request if not configured
; Jump here if the device is configured or EP0 request
.configured:
.ep0_request:
    MOV     A, REG[USBUART_EP0DATA + bRequest]
    DISPATCHER USBUART_DT_h2d_std_ep, USBUART_DT_h2d_std_ep_Size, USBUART_Not_Supported

USBUART_GetTableEntry_Local_Std:
    LJMP    USBUART_GetTableEntry

USBUART_NoDataStageControlTransfer_Local_Std:
    LJMP    USBUART_NoDataStageControlTransfer

.ENDLITERAL
;-----------------------------------------------
; Add custom application code for routines
; redefined by USB_APP_SUPPLIED in USB_HID.INC
;-----------------------------------------------

   ;@PSoC_UserCode_BODY_1@ (Do not change this line.)
   ;---------------------------------------------------
   ; Insert your custom code below this banner
   ;---------------------------------------------------

   ;---------------------------------------------------
   ; Insert your custom code above this banner
   ;---------------------------------------------------
   ;@PSoC_UserCode_END@ (Do not change this line.)

;-----------------------------------------------------------------------------
; FUNCTION NAME: USBUART_CB_d2h_std_dev_06
;
; DESCRIPTION:   Get Device Descriptor
;
;****************************************************************
; STANDARD DEVICE IN REQUEST: Get_Device_Descriptor
;****************************************************************
;
; bmRequestType  : (IN | STANDARD | DEVICE)       = 80h
; bRequest       : GET_DESCRIPTOR                 = 06h
; wValue         : DESCRIPTOR TYPE | INDEX        = xxxxh
; wIndex         : ZERO or LANG_ID                = xxxxh
; wLength        : SIZEOF_DESCRIPTOR              = --xxh
;
; The GET_DEVICE_DESCRIPTOR returns the specified descriptor if
; the descriptor exists.
;
; The upper byte of wValue contains the descriptor type and
; the lower byte contains the descriptor index. wIndex
; contains either 0000h or the Language ID. wLength contains
; the descriptor length. The actual descriptor information is
; transferred in subsequent data packets.
;
;****************************************************************
;
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_d2h_std_dev_06 & USB_UM_SUPPLIED)
export  USBUART_CB_d2h_std_dev_06
USBUART_CB_d2h_std_dev_06:
;-----------------------------------------------------------------------------
; Dispatch to the proper handler
;-----------------------------------------------------------------------------
    MOV     A, REG[USBUART_EP0DATA+wValueHi] ; Get the descriptor type
    ASL     A                          ; Make it into a offset
    CMP     A, GET_DESCR_DISPATCH_SIZE         ; Validity check
    JNC     USBUART_Not_Supported

    JACC    GET_DESCR_DISPATCH

GET_DESCR_DISPATCH:
    JMP     USBUART_Not_Supported      ; Invalid
    JMP     USBUART_SendDeviceDescr    ; Device Descriptor
    JMP     USBUART_SendConfigDescr    ; Configuration Descriptor
    JMP     USBUART_SendStringDescr    ; String Descriptor

GET_DESCR_DISPATCH_END:
GET_DESCR_DISPATCH_SIZE: EQU (GET_DESCR_DISPATCH_END - GET_DESCR_DISPATCH)
;-----------------------------------------------------------------------------
; Configuration Descriptor Handler
;-----------------------------------------------------------------------------
USBUART_SendConfigDescr:
    CALL    USBUART_GET_DEVICE_TABLE_ENTRY
    SWAP    A, X
    ADD     A, 2                       ; We want the pointer to the descriptor table (second entry)
    SWAP    A, X
    ADC     A, 0                       ; Don't forget the carry
    MOV    [USBUART_t2], USBUART_t1    ; Set up the destination
    CALL    USBUART_GETWORD            ; Get the pointer

    MOV     A, [USBUART_t1]            ; Pointer MSB
    MOV     X, [USBUART_t1+1]          ; Pointer LSB

    PUSH    A                          ; Save the MSB

    MOV     A, REG[USBUART_EP0DATA+wValueLo]  ; Get the descriptor index
    MOV     [USBUART_t2], A            ; Use the UM temp var--Selector
    POP     A                          ; Need the MSB for the range check
    PUSH    A                          ; Save the MSB for after the range check
    ROMX                               ; First entry is the table size (only a byte)
    CMP     A, [USBUART_t2]            ; Range check
    JNC     .range_ok

    POP     A                          ; Fix the stack
    JMP    USBUART_Not_Supported

.range_ok:
    POP     A                          ; Get the MSB back
    JMP     USBUART_GetTableEntry_Local_Std
;-----------------------------------------------------------------------------
; Device Descriptor Handler
;-----------------------------------------------------------------------------
USBUART_SendDeviceDescr:
    MOV     [USBUART_t2], [USBUART_bCurrentDevice]  ; Use the UM temp var--Selector
    MOV     A,>USBUART_DEVICE_DESCR_TABLE  ; Get the ROM Address MSB
    MOV     X,<USBUART_DEVICE_DESCR_TABLE  ; Get the ROM Address LSB
    ROMX                               ; First entry is the table size (only a byte)
    CMP     A, [USBUART_t2]            ; Range check
    JC      USBUART_Not_Supported

    MOV     A,>USBUART_DEVICE_DESCR_TABLE  ; Get the ROM Address MSB

    JMP     USBUART_GetTableEntry_Local_Std
;-----------------------------------------------------------------------------
; String Descriptor Handler
;-----------------------------------------------------------------------------
USBUART_SendStringDescr:
    MOV     A, REG[USBUART_EP0DATA+wValueLo]  ; Get the descriptor index
    MOV     [USBUART_t2], A            ; Use the UM temp var--Selector

    MOV     A,>USBUART_StringTable     ; Get the ROM Address MSB
    MOV     X,<USBUART_StringTable     ; Get the ROM Address LSB
    ROMX                               ; First entry is the table size (only a byte)
    CMP     A, [USBUART_t2]            ; Range check
    JC      USBUART_Not_Supported

    MOV     A,>USBUART_StringTable     ; Get the ROM Address MSB

    JMP     USBUART_GetTableEntry_Local_Std
ENDIF
;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_d2h_std_dev_08
;
;  DESCRIPTION:   Get Device Configuration
;
;****************************************************************
; STANDARD DEVICE IN REQUEST: Get_Device_Configuration
;****************************************************************
;
; bmRequestType  : (IN | STANDARD | DEVICE)       = 80h
; bRequest       : GET_CONFIGURATION              = 08h
; wValue         : RESERVED                       = 0000h
; wIndex         : RESERVED                       = 0000h
; wLength        : SIZEOF_DEVICE_CONFIGURATION    = 0001h
;
; The GET_DEVICE_CONFIGURATION request returns the currently
; selected device configuration number.
;
; request_value and request_index contain 0000h. request_length
; contains 0001h and the one-byte configuration number is returned
; in a separate data transfer.
;
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_d2h_std_dev_08 & USB_UM_SUPPLIED)
.LITERAL
GetConfigTransferDescrTable:
    TD_START_TABLE  1                  ; One entry
    TD_ENTRY    USB_DS_RAM, 1, USBUART_Configuration, NULL_PTR  ; Current configuration
.ENDLITERAL
export  USBUART_CB_d2h_std_dev_08
USBUART_CB_d2h_std_dev_08:
    MOV     [USBUART_t2], 0            ; Use the UM temp var--Selector
    MOV     A,>GetConfigTransferDescrTable  ; Get the ROM Address MSB
    MOV     X,<GetConfigTransferDescrTable  ; Get the ROM Address LSB
    JMP     USBUART_GetTableEntry_Local_Std
ENDIF
;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_h2d_std_dev_01
;
;  DESCRIPTION:   Clear Device Feature
;
;****************************************************************
; STANDARD DEVICE OUT REQUEST: Clear_Device_Feature
;****************************************************************
;
; bmRequestType  : (OUT | STANDARD | DEVICE)      = 00h
; bRequest       : CLEAR_FEATURE                  = 01h
; wValue         : FEATURE_SELECTOR               = --xxh
; wIndex         : RESERVED                       = 0000h
; wLength        : RESERVED                       = 0000h
;
; The CLEAR_DEVICE_FEATURE request disables a particular feature
; for a device. The only feature supported for a device is the
; REMOTE_WAKEUP feature.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_h2d_std_dev_01 & USB_UM_SUPPLIED)
export  USBUART_CB_h2d_std_dev_01
USBUART_CB_h2d_std_dev_01:
    MOV     A, REG[USBUART_EP0DATA+wValueLo]  ; Get the Feature Selector
                                       ; Check against valid features
                                       ;  for device recipient
    CMP     A, USB_DEVICE_REMOTE_WAKEUP  ; Only remote wakeup is defined for clear
    JNZ     USBUART_Not_Supported      ;
    AND     [USBUART_DeviceStatus], ~USB_DEVICE_STATUS_REMOTE_WAKEUP
    JMP     USBUART_NoDataStageControlTransfer_Local_Std
ENDIF
;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_h2d_std_dev_03
;
;  DESCRIPTION:   Set Device Feature
;
;****************************************************************
; STANDARD DEVICE OUT REQUEST: Set_Device_Feature
;****************************************************************
;
; bmRequestType  : (OUT | STANDARD | DEVICE)      = 00h
; bRequest       : SET_FEATURE                    = 03h
; wValue         : FEATURE_SELECTOR               = --xxh
; wIndex         : RESERVED                       = 0000h
; wLength        : RESERVED                       = 0000h
;
; The SET_DEVICE_FEATURE request enables a particular feature
; on a device. The only feature supported for a device is the
; REMOTE_WAKEUP feature.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_h2d_std_dev_03 & USB_UM_SUPPLIED)
export  USBUART_CB_h2d_std_dev_03
USBUART_CB_h2d_std_dev_03:
    MOV     A, REG[USBUART_EP0DATA+wValueLo]  ; Get the Feature Selector
                                       ; Check against valid features
                                       ;  for device recipient
    CMP     A, USB_DEVICE_REMOTE_WAKEUP  ; Remote wakeup?
    JZ      .remote_wakeup

    CMP     A, USB_TEST_MODE           ; Test Mode
    JZ      .test_mode
; Flow here for any other selector is invalid for device recipient
    JMP     USBUART_Not_Supported
; Jump here to enable remote wake up
.remote_wakeup:
    OR      [USBUART_DeviceStatus], USB_DEVICE_STATUS_REMOTE_WAKEUP
    JMP     .finish
; Jump here to enable test mode
.test_mode:
    JMP     USBUART_Not_Supported
.finish:
    JMP     USBUART_NoDataStageControlTransfer_Local_Std
ENDIF
;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_h2d_std_dev_05
;
;  DESCRIPTION:   Set Device Address
;
;****************************************************************
; STANDARD DEVICE OUT REQUEST: Set_Device_Address
;****************************************************************
;
; bmRequestType  : (OUT | STANDARD | DEVICE)      = 00h
; bRequest       : SET_ADDRESS                    = 05h
; wValue         : DEVICE_ADDRESS                 = 00xxh
; wIndex         : RESERVED                       = 0000h
; wLength        : RESERVED                       = 0000h
;
; The SET_DEVICE_ADDRESS request sets the USB device address
; for all future USB accesses.
;
;****************************************************************
;
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------

IF (USB_CB_SRC_h2d_std_dev_05 & USB_UM_SUPPLIED)
export  USBUART_CB_h2d_std_dev_05
USBUART_CB_h2d_std_dev_05:
      
    MOV     [USBUART_fDataPending], USB_ADDRESS_CHANGE_PENDING       
    MOV     A, REG[USBUART_EP0DATA+wValueLo]       
    MOV     [USBUART_TransferBuffer],A       
                                                   
    JMP     USBUART_NoDataStageControlTransfer_Local_Std
ENDIF


;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_h2d_std_dev_09
;
;  DESCRIPTION:   Set Configuration
;
;****************************************************************
; STANDARD DEVICE OUT REQUEST: Set_Device_Configuration
;****************************************************************
;
; bmRequestType  : (OUT | STANDARD | DEVICE)      = 00h
; bRequest       : SET_CONFIGURATION              = 09h
; wValue         : CONFIGURATION_VALUE            = --xxh
; wIndex         : RESERVED                       = 0000h
; wLength        : RESERVED                       = 0000h
;
; The SET_DEVICE_CONFIGURATION request selects a device
; configuration to be activated as the current configuration.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------

IF (USB_CB_SRC_h2d_std_dev_09 & USB_UM_SUPPLIED)
export  USBUART_CB_h2d_std_dev_09
USBUART_CB_h2d_std_dev_09:
    CALL    USBUART_GET_DEVICE_TABLE_ENTRY  ; Get the selected device
    MOV     [USBUART_t2],USBUART_t1    ; Set the GETWORD destination
    CALL    USBUART_GETWORD            ; Get the pointer to the CONFIG_LOOKUP table
                                       ; ITempW has the address
    MOV     A, REG[USBUART_EP0DATA+wValueLo]  ; Get the configuration number
    MOV     [USBUART_t2],A             ; Save it
    MOV     A, [USBUART_t1]            ; Get the CONFIG_LOOKUP ROM Address MSB
    MOV     X, [USBUART_t1+1]          ; Get the CONFIG_LOOKUP ROM Address LSB
    ROMX                               ; First entry is the table size (only a byte)
    CMP     A, [USBUART_t2]            ; Range check
    JC      USBUART_Not_Supported

; Refactored from the two loops below
    MOV     [USBUART_Configuration],[USBUART_t2]  ; Save the config number

    CMP     [USBUART_t2], 0            ; Unconfigure?
    JZ      .unconfigure

; Flow here to configure the endpoints
    MOV     A, [USBUART_t1]            ; Get the CONFIG_LOOKUP ROM Address MSB
    MOV     X, [USBUART_t1+1]          ; Get the CONFIG_LOOKUP ROM Address LSB
    INC     X                          ; Point to the first table entry
    ADC     A, 0                       ;
    MOV    [USBUART_t2], USBUART_t1    ; Set up the destination
    CALL    USBUART_GETWORD            ; Get the pointer to the CONFIG_LOOKUP table
                                       ; ITempW has the address
    MOV     X, 0                       ; Start the index at 0, but we INC first
.configure_next:
    INC     X                          ; Do the next one
    PUSH    X                          ; Save the endpoint number
    MOV     A, [USBUART_t1]            ; Get the CONFIG_LOOKUP ROM Address MSB
    MOV     X, [USBUART_t1+1]          ; Get the CONFIG_LOOKUP ROM Address LSB
    ROMX
    INC     [USBUART_t1+1]             ; Point to the next
    ADC     [USBUART_t1], 0            ;
    POP     X
    CALL    ConfigureEP                ; X contains the EP number
                                       ; A contains the EP Direction
    MOV     A, X                       ;
    CMP     A, USB_MAX_EP_NUMBER       ; Configure each of the endpoints
    JNZ     .configure_next            ; Do another one?
; Flow here when we are done
    JMP     .done

; Jump here to unconfigure the endpoints
.unconfigure:
    M8C_SetBank1	; _EP1MODE is in Bank 1
    MOV     X, USB_MAX_EP_NUMBER       ; Configure each of the endpoints
.unconfigure_next:
    MOV     [X+USBUART_EndpointAPIStatus], NO_EVENT_ALLOWED ; For the API
    MOV     REG[X+USBUART_EP1MODE-1], USB_MODE_DISABLE ; Disable the endpoint
    DEC     X                          ; One more down
    JNZ     .unconfigure_next          ; Don't unconfigure EP0
	M8C_SetBank0
.done:
    JMP     USBUART_NoDataStageControlTransfer_Local_Std
ENDIF


;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_d2h_std_ifc_00
;
;  DESCRIPTION:   Get Interface Status
;
;****************************************************************
; STANDARD INTERFACE IN REQUEST: Get_Interface_Status
;****************************************************************
;
; bmRequestType  : (IN | STANDARD | INTERFACE)    = 81h
; bRequest       : GET_STATUS                     = 00h
; wValue         : RESERVED                       = 0000h
; wIndex         : INTERFACE                      = --xxh
; wLength        : SIZEOF_INTERFACE_STATUS        = 0002h
;
; The GET_INTERFACE_STATUS request returns status for the
; specified interface.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_d2h_std_ifc_00 & USB_UM_SUPPLIED)
.LITERAL
GetInterfaceStatusTransferDescrTable:
    TD_START_TABLE  1                  ; One entry
    TD_ENTRY        USB_DS_RAM, 2, USBUART_TransferBuffer, NULL_PTR  ; Reuse the transfer buffer
.ENDLITERAL
export  USBUART_CB_d2h_std_ifc_00
USBUART_CB_d2h_std_ifc_00:

    MOV     [USBUART_TransferBuffer], 0     ; Zero the transfer buffer
    MOV     [USBUART_TransferBuffer+1], 0  ;

    MOV     [USBUART_t2], 0            ; Use the UM temp var--Selector
    MOV     A,>GetInterfaceStatusTransferDescrTable  ; Get the ROM Address MSB
    MOV     X,<GetInterfaceStatusTransferDescrTable  ; Get the ROM Address LSB

    JMP     USBUART_GetTableEntry_Local_Std
ENDIF
;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_d2h_std_ifc_10
;
;  DESCRIPTION:   Get Interface
;
;****************************************************************
; STANDARD INTERFACE IN REQUEST: Get_Interface
;****************************************************************
;
; bmRequestType  : (IN | STANDARD | INTERFACE)    = 81h
; bRequest       : GET_INTERFACE                  = 0Ah
; wValue         : RESERVED                       = 0000h
; wIndex         : INTERFACE                      = xxxxh
; wLength        : SIZEOF_GET_INTERFACE           = 0001h
;
; The GET_INTERFACE request returns the selected alternate
; setting for the specified interface.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------

IF (USB_CB_SRC_d2h_std_ifc_10 & USB_UM_SUPPLIED)
.LITERAL
GetInterfaceTransferDescrTable:
    TD_START_TABLE  1                  ; One entry
    TD_ENTRY        USB_DS_RAM, 1, USBUART_TransferBuffer, NULL_PTR  ; Reuse the transfer buffer
.ENDLITERAL
export  USBUART_CB_d2h_std_ifc_10
USBUART_CB_d2h_std_ifc_10:
    MOV     A, REG[USBUART_EP0DATA+wIndexLo]  ; Get the interface number
    CMP     A, 2                       ; Valid interface number? (UM Parameter: NumInterfaces)
    JNC     USBUART_Not_Supported

    MOV     X, A                       ; The interface number is the index into alternates settings table

    MOV     A, [X + USBUART_InterfaceSetting]  ; Save the current interface setting
    MOV     [USBUART_TransferBuffer], A     ; into the transfer buffer

    MOV     [USBUART_t2], 0            ; Use the UM temp var--Selector
    MOV     A,>GetInterfaceTransferDescrTable  ; Get the ROM Address MSB
    MOV     X,<GetInterfaceTransferDescrTable  ; Get the ROM Address LSB

    JMP     USBUART_GetTableEntry_Local_Std
ENDIF


;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_d2h_std_ep_00
;
;  DESCRIPTION:   Get Endpoint Status
;
;****************************************************************
; STANDARD ENDPOINT IN REQUEST: Get_Endpoint_Status
;****************************************************************
;
; bmRequestType  : (IN | STANDARD | ENDPOINT)     = 82h
; bRequest       : GET_STATUS                     = 00h
; wValue         : RESERVED                       = 0000h
; wIndex         : ENDPOINT                       = 00xxh
; wLength        : SIZEOF_ENDPOINT_STATUS         = 0002h
;
; The GET_ENDPOINT_STATUS request returns status for the specified
; endpoint.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_d2h_std_ep_00 & USB_UM_SUPPLIED)
export  USBUART_CB_d2h_std_ep_00
USBUART_CB_d2h_std_ep_00:
    MOV     A, REG[USBUART_EP0DATA+wIndexLo]  ; Get the endpoint number
    AND     A, ~USB_DIR_IN             ; Strip off the direction bit
    CMP     A, USB_NUM_ENDPOINTS       ; Range check
    JNC     USBUART_Not_Supported

    MOV     X, A                       ; The endpoint number is the index

    MOV     [USBUART_t2], 0            ; Use the UM temp var--Selector

    MOV     [USBUART_TransferBuffer + 1], 0  ; Use the UM Transfer Buffer
    MOV     A, [X + USBUART_EndpointStatus]  ; Get the status
    MOV     [USBUART_TransferBuffer], A  ; Save it in the report

    MOV     A,>GetStatusTransferDescrTable  ; Get the ROM Address MSB
    MOV     X,<GetStatusTransferDescrTable  ; Get the ROM Address LSB

    JMP     USBUART_GetTableEntry_Local_Std
ENDIF

;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_h2d_std_ep_01
;
;  DESCRIPTION:   Clear Endpoint Feature
;
;****************************************************************
; STANDARD ENDPOINT OUT REQUEST: Clear_Endpoint_Feature
;****************************************************************
;
; bmRequestType  : (OUT | STANDARD | ENDPOINT)    = 02h
; bRequest       : CLEAR_FEATURE                  = 01h
; wValue         : FEATURE_SELECTOR               = --xxh
; wIndex         : ENDPOINT                       = 00xxh
; wLength        : RESERVED                       = 0000h
;
; The CLEAR_ENDPOINT_FEATURE request disables a particular
; feature for an endpoint.
;
; The only feature supported for an endpoint is the EP_HALT
; feature.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_h2d_std_ep_01 & USB_UM_SUPPLIED)
export  USBUART_CB_h2d_std_ep_01
USBUART_CB_h2d_std_ep_01:
    MOV     A, REG[USBUART_EP0DATA+wValueLo]  ; Get the feature selector
    CMP     A, USB_ENDPOINT_HALT       ; Halt is the only selector defined for endpoints
    JNZ     USBUART_Not_Supported

    MOV     A, REG[USBUART_EP0DATA+wIndexLo]  ; Get the Endpoint number
    AND     A, ~USB_DIR_IN             ; Strip off the direction bit
    CMP     A, 0                       ; Since we can't halt the Control Endpoint
    JZ      .done

    CMP     A, USB_NUM_ENDPOINTS       ; Range check
    JNC     USBUART_Not_Supported

    MOV     X, A                       ; Endpoint number is the index
    AND     [X+USBUART_EndpointStatus], ~USB_ENDPOINT_STATUS_HALT  ; Clear the endpoint halt

    index   USBUART_USB_EP_BIT_LOOKUP	   ; Find bit position for endpoint
    xor     A, FFh
    and     [USBUART_EPDataToggle], A ; Clear the data toggle for this endpoint
    TST     REG[USBUART_EP0DATA+wIndexLo], USB_DIR_IN  ; IN or OUT endpoint?
    M8C_SetBank1	                      ; For EP1_MODE register
    JNZ     .in

    ; Mark endpoint as empty so it will be reloaded
    mov     [X+USBUART_EndpointAPIStatus], NO_EVENT_PENDING
    mov     reg[X + USBUART_EP1MODE - 1], USB_MODE_ACK_OUT    ; ACK the endpoint
    JMP     .done
.in:
    mov     [X+USBUART_EndpointAPIStatus], EVENT_PENDING
    MOV     REG[X + USBUART_EP1MODE - 1], USB_MODE_NAK_IN  ; NAK the endpoint
.done:
	M8C_SetBank0
    JMP     USBUART_NoDataStageControlTransfer_Local_Std
ENDIF
;-----------------------------------------------------------------------------
;  FUNCTION NAME: USBUART_CB_h2d_std_ep_03
;
;  DESCRIPTION:   Set Endpoint Feature
;
;****************************************************************
; STANDARD ENDPOINT OUT REQUEST: Set_Endpoint_Feature
;****************************************************************
;
; bmRequestType  : (OUT | STANDARD | ENDPOINT)    = 02h
; bRequest       : SET_FEATURE                    = 03h
; wValue         : FEATURE_SELECTOR               = --xxh
; wIndex         : ENDPOINT                       = 00xxh
; wLength        : RESERVED                       = 0000h
;
; The SET_ENDPOINT_FEATURE request enables a particular feature
; for a specific endpoint. The only feature supported for an
; endpoint is the EP_HALT feature.
;
;****************************************************************
;-----------------------------------------------------------------------------
;
;  ARGUMENTS:
;
;  RETURNS:
;
;  SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
IF (USB_CB_SRC_h2d_std_ep_03 & USB_UM_SUPPLIED)
export  USBUART_CB_h2d_std_ep_03
USBUART_CB_h2d_std_ep_03:
    MOV     A, REG[USBUART_EP0DATA+wValueLo]  ; Get the feature selector
    CMP     A, USB_ENDPOINT_HALT       ; Halt is the only selector defined for endpoints
    JNZ     USBUART_Not_Supported

    MOV     A, REG[USBUART_EP0DATA+wIndexLo]  ; Get the Endpoint number
    AND     A, ~USB_DIR_IN             ; Strip off the direction bit
    CMP     A, 0                       ; Never halt the Control Endpoint
    JZ      .done

    CMP     A, USB_NUM_ENDPOINTS       ; Range check
    JNC     USBUART_Not_Supported

    MOV     X, A                       ; Endpoint number is the index

    OR      [X+USBUART_EndpointStatus], USB_ENDPOINT_STATUS_HALT  ; Halt the endpoint
    mov     [X+USBUART_EndpointAPIStatus], NO_EVENT_ALLOWED

    TST     REG[USBUART_EP0DATA+wIndexLo], USB_DIR_IN  ; IN or OUT endpoint?
    M8C_SetBank1	                      ; For EP1_MODE register
    JNZ     .in

    MOV     REG[X + USBUART_EP1MODE - 1], USB_MODE_STALL_DATA_EP | USB_MODE_ACK_OUT  ; Stall the endpoint
    JMP     .done
.in:
    MOV     REG[X + USBUART_EP1MODE - 1], USB_MODE_STALL_DATA_EP | USB_MODE_ACK_IN  ; Stall the endpoint
.done:
	M8C_SetBank0
    JMP     USBUART_NoDataStageControlTransfer_Local_Std
ENDIF
;-----------------------------------------------------------------------------
;  FUNCTION NAME: ConfigureEP
;
;  DESCRIPTION:   Configure an endpoint
;
;  ARGUMENTS:    A contains the endpoint direction
;                X contains the endpoint number
;
;  RETURNS:
;
;  SIDE EFFECTS:  The A REGISTER IS VOLATILE.  X REGISTER IS MAINTAINED!
;
;  THEORY of OPERATION or PROCEDURE:
;
;-----------------------------------------------------------------------------
ConfigureEP:
    CMP     A, USB_DIR_UNUSED          ; Is this endpoint unused?
    JNZ     .enable                    ; Only enable it if it is used
    RET                                ; Quick exit if this endpoint is unused

; Jump here to enable an endpoint
.enable:
    PUSH    A		                        ; Save the endpoint direction
    MOV     A, X	                      ; We are using a JACC to dispatch to enable the interrupt
    ASL     A		                        ;
    JACC    .EP_INT_ENABLE             ;


.LITERAL
.EP_INT_ENABLE:
    JMP     .EP0IntEnable              ; Enable EP0
    JMP     .EP1IntEnable              ; Enable EP1
    JMP     .EP2IntEnable              ; Enable EP2
    JMP     .EP3IntEnable              ; Enable EP3
    JMP     .EP4IntEnable              ; Enable EP4
.ENDLITERAL

; Jump here to enable EP0 Interrupts
.EP0IntEnable:
    M8C_EnableIntMask USBUART_INT_REG, USBUART_INT_EP0_MASK
;    JMP   .exit2
    JMP   .cont
.EP1IntEnable:
    M8C_EnableIntMask USBUART_INT_REG, USBUART_INT_EP1_MASK
    JMP   .cont
.EP2IntEnable:
    M8C_EnableIntMask USBUART_INT_REG, USBUART_INT_EP2_MASK
    JMP   .cont
.EP3IntEnable:
    M8C_EnableIntMask USBUART_INT_REG, USBUART_INT_EP3_MASK
    JMP   .cont
.EP4IntEnable:
    M8C_EnableIntMask USBUART_INT_REG, USBUART_INT_EP4_MASK
	JMP   .cont
; Jump or flow here to continue configuring the endpoint
.cont:
    MOV     A, X	                      ; Get the endpoint number from X
    INDEX   USBUART_USB_EP_BIT_LOOKUP	 ; Find bit position for endpoint
    XOR     A, FFh
    AND     [USBUART_EPDataToggle], A ; Clear the data toggle for this endpoint
    and     [X+USBUART_EndpointStatus], ~USB_ENDPOINT_STATUS_HALT    ; Clear any endpoint halts

; if endpoint 0 set EP0MODE
; then exit
;    mov     A, X	                     ; Get the endpoint number from X
;    cmp     A, EP0	                   ; Is this endpoint zero?
;    jnz     .enable                   ; Only enable it if it is used
    M8C_SetBank1
    POP   A                            ; Get the endpoint direction back
    AND   A, USB_DIR_IN                ; Is it an IN endpoint?
    JNZ   .in                          ; Jump on IN
; Flow here for an OUT Endpoint
    mov     reg[X+USBUART_EP1MODE-1], USB_MODE_ACK_OUT   ; ACK the endpoint
    MOV   [X+USBUART_EndpointAPIStatus], NO_EVENT_PENDING ; For the API
    JMP   .exit1
; Jump here for an IN Endpoint
.in:
    MOV   REG[X+USBUART_EP1MODE-1], USB_MODE_NAK_IN ; NAK the endpoint
    MOV   [X+USBUART_EndpointAPIStatus], EVENT_PENDING ; For the API
; Jump or flow here to set the API event and exit
.exit1:
	M8C_SetBank0
.exit2:
    RET


; End of File USBUART_std.asm
