;COMMENT /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;**************************************************************************
;**                                                                      **
;**                  I N T E L   P R O P R I E T A R Y                   **
;**                                                                      **
;**     COPYRIGHT (c)  1996, 1997 BY  INTEL  CORPORATION.  ALL RIGHTS    **
;**     RESERVED.   NO  PART  OF THIS PROGRAM  OR  PUBLICATION  MAY      **
;**     BE  REPRODUCED,   TRANSMITTED,   TRANSCRIBED,   STORED  IN  A    **
;**     RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER    **
;**     LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,    **
;**     MAGNETIC,  OPTICAL,  CHEMICAL, MANUAL, OR OTHERWISE,  WITHOUT    **
;**     THE PRIOR WRITTEN PERMISSION OF :                                **
;**                                                                      **
;**                        INTEL  CORPORATION                            **
;**                                                                      **
;**                     2200 MISSON COLLEGE BLVD                         **
;**                                                                      **
;**               SANTA  CLARA,  CALIFORNIA  95052-8119                  **
;**                                                                      **
;**************************************************************************
;   Revision History
;   ---------------------------------------------
;    1.21    7-23-98		Paul Luse
;				cleanup
;				changed PLC includes to absolute	
;    1.2     05-29-97          Charles H Linthicum Jr.
;                              Fixed problem with when the embedded function is
;                               disabled the host would continue to see status
;                               changes on port 4 and not enable port 5.
;                               added a clear port connect status change to
;                               get port status routine when embedded function is
;                               disabled.
;    1.1     03-20-97          Charles H Linthicum Jr.
;                              Made changes for Helsinki with extra (4th)
;                               downstream port.
;                              Fixed problem with get port status on embedded fn
;    1.0     ??-??-97          Kenneth Schultz

;These two equate statements allow the user to switch between the PLC
;and Keil assemblers.  Place a 1 on the assembler that is to be used to
;assemble this file.
PLC EQU 1
KEIL EQU 0

IF PLC
	include "8x930HX.INC"
	include "SWITCH.INC"              ; include file of various switches
ENDIF
IF KEIL
    $include (Reg930.INC)
  $include (SWITCH.INC)              ; include file of various switches
ENDIF


;Doug Equates.
HEX_DSP_10      EQU     0ffe8h
HEX_DSP_32      EQU     0ffe9h
HEX_DSP_54      EQU     0ffeah
HEX_DSP_76      EQU     0ffebh


C_HUB_LOCAL_POWER       EQU   0
C_HUB_OVER_CURRENT      EQU   1
PORT_CONNECTION         EQU   0
PORT_ENABLE             EQU   1
PORT_SUSPEND            EQU   2
PORT_OVER_CURRENT       EQU   3
PORT_RESET              EQU   4
PORT_POWER              EQU   8
PORT_LOW_SPEED          EQU   9
C_PORT_CONNECTION       EQU   16
C_PORT_ENABLE           EQU   17
C_PORT_SUSPEND          EQU   18
C_PORT_OVER_CURRENT     EQU   19
C_PORT_RESET            EQU   20


DISABLE_PORT_CMD        EQU   00h
ENABLE_PORT_CMD         EQU   01h
RESET_ENABLE_PORT_CMD   EQU   02h
SUSPEND_PORT_CMD        EQU   03h
RESUME_PORT_CMD         EQU   04h

CLEAR_PCSC_MASK         EQU  0FEh
CLEAR_PESC_MASK         EQU  0FDh
CLEAR_PSSC_MASK         EQU  0FBh
CLEAR_RSTSC_MASK        EQU  0EFH
CLEAR_OVISC_MASK        EQU  0F7h



public GetClassDeviceCommand
public GetClassOtherCommand
public SetClassDeviceCommand
public SetClassOtherCommand
public InitilizeHubVariables

IF PLC
	extern bRequest:DATA, wValue:DATA, wIndex:DATA
	extern gbFControlBufferLocation:DATA
	extern LoadBuffer:CODE
ENDIF
IF KEIL
	extern DATA (bRequest), DATA (wValue), DATA (wIndex)
	extern DATA (gbFControlBufferLocation)
	extern CODE (LoadBuffer)
ENDIF

IF PLC
	extern InitilizeEmbeddedFunction:CODE
	extern  EmbeddedFunctionInReset:DATA
ENDIF
IF KEIL
    extern CODE (InitilizeEmbeddedFunction)
	extern DATA (EmbeddedFunctionInReset)
ENDIF

IF PLC
	DEFINE HUB_CODE_SEGMENT, SPACE=CODE
	SEGMENT HUB_CODE_SEGMENT
ENDIF
IF KEIL
	HUB_CODE_SEGMENT SEGMENT CODE
	RSEG HUB_CODE_SEGMENT
ENDIF

;COMMENT *------------------------------------------------------------
;Function name     : InitilizeHubVariables
;Brief Description : This routine simply initializes the Repeater Code varaibles
;                  : right now.  No other variables are used.
;Regs preserved    : No reg. is saved
;--------------------------------------------------------------------*

InitilizeHubVariables:
         ret

;COMMENT *------------------------------------------------------------
;Function name     : GetHubClassDeviceCommand
;Brief Description : Processes a Get Hub Class Device Command
;                  : All data from this is written into the FIFO
;                  : and the proper count is written to TXCNT.
;Regs preserved    : No reg. is saved
;Regs Used         : A
;--------------------------------------------------------------------*
;SCOPE
GetClassDeviceCommand:
GetHubClassDeviceCommand:
        mov    A,       bRequest
        cjne   A,       #GET_DESCRIPTOR, ?CheckGetHubStatus
GetHubDescriptor:
IF INTERNAL_PORT == ENABLED
    sjmp  LEAVE_CONNECTED
ENDIF
        jb     EMBD_FN_SWITCH, LEAVE_CONNECTED
        push   HPINDEX
        mov    HPINDEX, #EMBEDDED_PORT_NUMBER         ; Select the desired port to get the data from.
        anl    HPSC,    #00h
        pop    HPINDEX
LEAVE_CONNECTED:

        ; ********************** GET DESCRIPTOR,  HUB *******************
        IF PLC
			mov     gbFControlBufferLocation,   #LOW HIGH16(BEGIN_HUB_DESCRIPTOR)
    	    mov     gbFControlBufferLocation+1, #HIGH LOW16(BEGIN_HUB_DESCRIPTOR)
        	mov     gbFControlBufferLocation+2, #LOW  LOW16(BEGIN_HUB_DESCRIPTOR)
	        mov     A,  #LOW  LOW16(END_HUB_DESCRIPTOR - BEGIN_HUB_DESCRIPTOR)
    	    mov     B,  #HIGH LOW16(END_HUB_DESCRIPTOR - BEGIN_HUB_DESCRIPTOR)
		ENDIF
		IF KEIL
            mov     gbFControlBufferLocation,   #BYTE2(BEGIN_HUB_DESCRIPTOR)
    	    mov     gbFControlBufferLocation+1, #BYTE1(BEGIN_HUB_DESCRIPTOR)
        	mov     gbFControlBufferLocation+2, #BYTE0(BEGIN_HUB_DESCRIPTOR)
        mov     A,  #BYTE0(END_HUB_DESCRIPTOR - BEGIN_HUB_DESCRIPTOR)
    	    mov     B,  #BYTE1(END_HUB_DESCRIPTOR - BEGIN_HUB_DESCRIPTOR)
		ENDIF
        ljmp    LoadBuffer



?CheckGetHubStatus:
        cjne    A ,     #GET_STATUS, ReturnGetClassDevice

GetHubStatus:
   ;------------------------------------------------
   ;- GET HUB STATUS
   ;------------------------------------------------
        mov    A ,      HSTAT
        anl    A ,      #03h
        mov    HTXDAT,  A
        mov    HTXDAT,  #0

        mov    A ,      HSTAT
        RR     A
        RR     A
        anl    A ,      #03
        mov    HTXDAT,  A
        mov    HTXDAT,  #0
        mov    HTXCNTL, #4
        jmp    ReturnGetClassDevice


ReturnGetClassDevice:
        ret




;COMMENT *------------------------------------------------------------
;Function name     : GetClassOtherCommand
;Brief Description : This routine executes two commands.
;                  : GetBusState Retuns 1 byte of status information
;                  : GetPortStatus Retuns a 4 byte of status information
;Regs preserved    : No reg. is saved
;Regs Used         : A
;--------------------------------------------------------------------*
;SCOPE
GetClassOtherCommand:

        mov     A ,     bRequest
        cjne    A ,     #GET_STATUS, ?CheckGetBusState

   ;------------------------------------------------
   ;- GET PORT STATUS
   ;- Brief Description : Returns 4 byte bus status
   ;------------------------------------------------

GetPortStatus:
        push   HPINDEX
        mov    HPINDEX, wIndex+1            ; Select the disired port to get the data from.
        ; chl debug
        mov     EPINDEX,        #80h

        mov    A, wIndex+1
        cjne   A, #EMBEDDED_PORT_NUMBER, NotInternalPort

IF FUB_BOARD == ENABLED ; check embedded function switch_port bit P1.1
        jb     EMBD_FN_SWITCH,  NotInternalPort     ; If it's attached, treat as normal port.
                                                    ; otherwise show disonnected
ELSE  ;  IF FUB_BOARD == DISABLED
   IF INTERNAL_PORT == ENABLED
     sjmp       NotInternalPort
   ELSE
     sjmp       SHOW_DISCONNECT
   ENDIF
ENDIF

SHOW_DISCONNECT:
        mov     TXDAT,  #00h
        mov     TXDAT,  #01h      ; only show PPSTAT = 1 for port power
        mov     TXDAT,  #00h
        mov     TXDAT,  #00h
        mov     TXCNTL, #04h

        ; In reality at this point HPSTAT will show  91 and HPSC 01
        ; PCSTAT = 1 hard-wired
        ; PCSC = 1 ... we need to clear this
        anl     HPSC,   #0FEh   ; clear PCSC bit

        sjmp    DoneGetPortStatus

NotInternalPort:
                                            ; wPortStatus First
temp2:
        mov    A ,      HPSTAT              ; Get the first byte of wPortStatus
        anl    A ,      #07h
        jnb    PRSTAT,  ?FirstByteDone
        orl    A ,      #10h
?FirstByteDone:
        mov    HTXDAT,  A                   ; Load first byte into FIFO

                                            ; DO SECOND BYTE
        mov    A,       #00h
        jnb    PPSTAT,  ?Check_LS           ; If the PP bit set, then set the corresponding
                                            ; value in the report
        orl    A ,      #01h
?Check_LS:
        jnb    LSSTAT,  ?SendByte2          ; If the LS bit set, then set the corresponding
        orl    A ,      #02h                ; value in the report
?SendByte2:
        mov    HTXDAT,  A
                                            ; DO THIRD BYTE
                                            ; Now get the LSB of the wPortChange byte
?GetwPortChange:
        mov    A ,      HPSC
        anl    A ,      #1Fh
        mov    HTXDAT,  A
        mov    HTXDAT,  #0
        mov    HTXCNTL, #4h

DoneGetPortStatus:

        pop    HPINDEX                      ; Restore the index
        jmp    ReturnGetClassOther





?CheckGetBusState:
        cjne    A ,     #GET_STATE, ReturnBadGetClassOtherCommand
   ;------------------------------------------------
   ;- GET BUS STATE
   ;- Brief Description : Returns bus state, Bit 0 = V-, Bit 1 = V+
   ;------------------------------------------------
GetBusState:
        push   HPINDEX
        mov    HPINDEX, wIndex+1            ; Select the disired port to get the data from.

        mov    A,       HPSTAT
        RL     A
        RL     A
        anl    A,       #03h
        mov    HTXDAT,  A
        mov    HTXCNTL, #1h
        pop    HPINDEX
        sjmp   ReturnGetClassOther


ReturnBadGetClassOtherCommand:
ReturnGetClassOther:
        ret


;COMMENT *------------------------------------------------------------
;Function name     : SetClassDeviceCommand
;Brief Description : Sets & Clears the hub featues.
;                  : ClearHubFeature
;                  : SetHubFeature
;                  :
;Regs preserved    : No reg. is saved
;Regs Used         : A
;--------------------------------------------------------------------*
;SCOPE

SetClassDeviceCommand:
        mov     A ,     bRequest
        cjne    A ,     #CLEAR_FEATURE, CheckSetHubFeature

ClearHubFeature:

        mov     A ,     wValue+1              ; Get Feature Selector
CheckLocalPower:
        cjne    A ,     #C_HUB_LOCAL_POWER, CheckOverCurrent
        ; Not supported on this chip , just return
        jmp     ReturnSetClassDevice

CheckOverCurrent:
        cjne    A ,     #C_HUB_OVER_CURRENT, ReturnBadSetClassDeviceCommand
        anl     HSTAT,  #CLEAR_OVISC_MASK
        jmp     ReturnSetClassDevice


CheckSetHubFeature:                      ; There is no such thing as a SetHubFeature
                                         ; since there are no Hub Features that can be set.
SetHubFeature:

ReturnBadSetClassDeviceCommand:
        jmp   BadCommandStatus

ReturnSetClassDevice:

        ret

;COMMENT *------------------------------------------------------------
;Function name     : SetClassOtherCommand
;Brief Description : Excutes either a SetPortFeature or ClearPortFeature
;                  : These routines are called via a jump to reduce
;                  : stack size
;Regs preserved    : No reg. is saved
;Regs Used         : A
;--------------------------------------------------------------------*
;SCOPE

SetClassOtherCommand:
        mov     A ,   bRequest
        cjne    A ,   #CLEAR_FEATURE,  CheckSetHubOtherFeature
        jmp     ClearPortFeature


CheckSetHubOtherFeature:
        cjne    A ,   #SET_FEATURE, ReturnBadSetClassOtherCommand
        jmp     SetPortFeature


ReturnBadSetClassOtherCommand:

        jmp   BadCommandStatus


;COMMENT *------------------------------------------------------------
;Function name     : ClearPortFeature
;Brief Description : Clears the feature contained in R0 = LSB of wValue


;Regs preserved    : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
ClearPortFeature:
        push   HPINDEX                    ; Save the current port - Restored in GoodHandshakeStatus
        mov    HPINDEX, wIndex+1          ; Select the disired port to get the data from.


        mov    A ,    wValue+1            ; Get Feature Selector

ClearPortConnection:                      ; Not Used as this is hardwired
CheckClearPortEable:
        cjne   A ,    #PORT_ENABLE, CheckClearPortSuspend
        mov    HPCON, #DISABLE_PORT_CMD
        jmp    GoodNoDataCommandStatus

CheckClearPortSuspend:
        cjne   A ,    #PORT_SUSPEND, CheckClearPortPower

        mov    A ,    wIndex+1            ; Get the port to suspend.
                                          ; If it's the internal one call
                                          ; the function routine to do the
                                          ; resume call.
        cjne   A ,    #EMBEDDED_PORT_NUMBER, Clear1

               ;--------------------------------------------
               ; EMBEDDED RESUME
               ; Call the embedded function and have it wake
               ; up as well.
               ;--------------------------------------------
        Call   DoEmbeddedResume
Clear1:

        mov    HPCON, #RESUME_PORT_CMD
        jmp    GoodNoDataCommandStatus


CheckClearPortPower:
        cjne   A ,    #PORT_POWER,   CheckClearPortConnectionSC
        push   ACC                           ; Save ACC
        mov    ACC,   HPINDEX                ; HPINDEX would have been set
                                             ; before comming into this routine.
        add    A,     #2
        movc   A,     @A+PC                  
        sjmp   ClearPortPower

clearPortPowerMasks:
        db     0FFh                          ; 0 = Bit 0 = Port 0, Illegal but we will ignore it.
        db     0FDh                          ; 1 = Bit 1 = Port 1,
        db     0FBh                          ; 2 = Bit 2 = Port 2,
        db     0F7h                          ; 3 = Bit 3 = Port 3
        db     0EFh                          ; 4 = Bit 4 = Port 4 - Embedded Port
        db     0DFh                          ; 5 = Bit 5 = Port 5 - Helsinki: 4th downstream port

ClearPortPower:
        anl    HPPWR, A                      ; Use mask to turn off port.
        pop    ACC                           
        jmp    GoodNoDataCommandStatus

CheckClearPortConnectionSC:
        cjne   A,     #C_PORT_CONNECTION, CheckClearPortEnableSC
        anl    HPSC,  #CLEAR_PCSC_MASK
        jmp    GoodNoDataCommandStatus

CheckClearPortEnableSC:
        cjne   A,     #C_PORT_ENABLE,     CheckClearPortSuspendSC
        anl    HPSC,  #CLEAR_PESC_MASK
        jmp    GoodNoDataCommandStatus

CheckClearPortSuspendSC:
        cjne   A,     #C_PORT_SUSPEND,    CheckClearPortResetSC
        anl    HPSC,  #CLEAR_PSSC_MASK
        jmp    GoodNoDataCommandStatus

CheckClearPortResetSC:
        cjne   A,     #C_PORT_RESET,      IllegalFeatureSelector

        anl    HPSC,  #CLEAR_RSTSC_MASK
        jmp    GoodNoDataCommandStatus

IllegalFeatureSelector:
        Jmp    BadCommandStatus

;COMMENT *------------------------------------------------------------
;Function name     : SetPortFeature
;Brief Description : Sets the feature contained in R0 = LSB of wValue


;Regs preserved    : HPINDEX
;--------------------------------------------------------------------*
;SCOPE
SetPortFeature:
        push   HPINDEX                       ; Save the current port-Restored in GoodHandshakeStatus
        mov    HPINDEX, wIndex+1             ; Select the disired port to get the data from.
        mov    A,     wValue+1               ; Get Feature Selector

?CheckSetPortEable:
        cjne   A,     #PORT_ENABLE, ?CheckSetPortSuspend
        mov    HPCON, #ENABLE_PORT_CMD
        jmp    GoodNoDataCommandStatus

?CheckSetPortSuspend:
        cjne   A,     #PORT_SUSPEND, ?CheckSetPortReset
        mov    A,     HPINDEX
        cjne   A,     #EMBEDDED_PORT_NUMBER, Set1

               ;--------------------------------------------
               ; EMBEDDED SUSPEND
               ; Call the embedded function and have it go to
               ; sleep.  
               ;--------------------------------------------

        lcall   DoEmbeddedSuspend
Set1:
        mov    HPCON, #SUSPEND_PORT_CMD
        jmp    GoodNoDataCommandStatus

?CheckSetPortReset:
        cjne   A,     #PORT_RESET, ?CheckSetPortPower

        mov    HPCON, #RESET_ENABLE_PORT_CMD                ; DO the reset.
        mov    A,     HPINDEX                               ; Now if this is port 4, then wait for the reset
                                                            ; to complete and then call the software reset
                                                            ; which will configure the hardware as well.

         cjne   A,      #EMBEDDED_PORT_NUMBER, Set2

               ;--------------------------------------------
               ; EMBEDDED RESET
               ; Reset the embedded function.
               ; Tell it to change its ways or else!
               ;--------------------------------------------

         jnb    PRSTAT, $                                   ; Wait for reset to be applied.
                                                            ; This will happen at EOF.
                                                            ; Since the embedded function will
                                                            ; actually reset at EOF and clear all
                                                            ; of the USB registers.
                                                            ; This loop is here so we can tell
                                                            ; when it's safe to initilize the registers.
         Call   InitilizeEmbeddedFunction                   ; Init the embedded function.

Set2:


        jmp    GoodNoDataCommandStatus

?CheckSetPortPower:
        cjne   A,     #PORT_POWER, BadCommandStatus

        push   ACC                            ; Save ACC
        mov    ACC,   HPINDEX                 ; HPINDEX would have been set
                                              ; before comming into this routine.
        add    A,     #2
        movc   A,     @A+PC                   
        sjmp   SetPortPower                   

SetPortPowerMasks:
        db     000h                           ; 0 = Bit 0 = Port 0, Illegal but we will ignore it.
        db     002h                           ; 1 = Bit 1 = Port 1,
        db     004h                           ; 2 = Bit 2 = Port 2,
        db     008h                           ; 3 = Bit 3 = Port 3
        db     010h                           ; 4 = Bit 4 = Port 4 = Embedded Port
        db     020h                           ; 5 = Bit 5 = Port 5 = Helsinki 4th DS port
        nop                                   ; to help the disassembler out.
SetPortPower:
        orl    HPPWR, A                       ; Use mask to shut off port.
        pop    ACC
        jmp    GoodNoDataCommandStatus



GoodNoDataCommandStatus:
        pop    HPINDEX
        ret
BadCommandStatus:
        pop    HPINDEX
        ret

DoEmbeddedResume:
        ret
DoEmbeddedSuspend:
        ret
DoEmbeddedReset:
  ;     lcall  InitilizeEmbeddedFunction
       ret

;************************************************************************
;************* HUB DESCRIPTOR ****************************************
;************************************************************************

;
; NOTE!!!!! '251 is a Big Endian machine. Words and DWords are stored with the
; LSB in the numerically higher address.
;
IF PLC
	DEFINE  HUB_DESCRIPTOR_CODE_SEGMENT, SPACE=CODE
	SEGMENT HUB_DESCRIPTOR_CODE_SEGMENT
ENDIF
IF KEIL
    HUB_DESCRIPTOR_CODE_SEGMENT SEGMENT CODE
	RSEG HUB_DESCRIPTOR_CODE_SEGMENT
ENDIF

BEGIN_HUB_DESCRIPTOR:
        gHub_bLength:              db  END_HUB_DESCRIPTOR-BEGIN_HUB_DESCRIPTOR
        gHub_bDescriptorType:      db  HUB_DESCR
IF HELSINKI == ENABLED
        gHub_NumPorts:             db  05h                ; Supports 5 ports (4 ds + 1 embedded)

ELSE
        gHub_NumPorts:             db  04h                ; Supports 4 ports (3 ds + 1 embedded)
ENDIF
        gHub_wHubCharacteristics:  dw  00h                ; Ganged Power, NotCompound, Gloabl OverIProct
        gHub_bPwrOn2PwrGood:       db  016h               ; Approx 40mSecs for Power to stabalize
        gHub_bHubConrCurrent:      db  100d               ; 100 milliamps
        gHub_bDeviceRemovable:     db  010h               ; Note: 1,2,3,5 ports removable P4 not removable (embedded fn)
                                                          ; Regardless of Halifax vs. Helsinki this mask does
                                                          ; not have to change
        gHub_bPortPwrCtrlMask:     db  0h                 ; All ports respond to Ganged Power Commands
END_HUB_DESCRIPTOR:

END
