📄 hx_all.asm
字号:
mov COMMAND_BUFFER1, RXDAT ; bmRequestType
mov COMMAND_BUFFER1+1, RXDAT ; bRequest
mov COMMAND_BUFFER1+3, RXDAT ; wValue LSB
mov COMMAND_BUFFER1+2, RXDAT ; wValue MSB
mov COMMAND_BUFFER1+5, RXDAT ; wIndex LSB
mov COMMAND_BUFFER1+4, RXDAT ; wIndex MSB
mov COMMAND_BUFFER1+7, RXDAT ; wLength LSB
mov COMMAND_BUFFER1+6, RXDAT ; wLength MSB
setb RXFFRC ; Update receive FIFO state
clr RXSETUP
push DPX ; Processing the jump table will
; corrupt DPX. Save it here
lCall ProcessSetup1
pop DPX ; Restore DPX
ReturnSetup1:
Ret
;COMMENT *------------------------------------------------------------
;Function name : ProcessSetup
;Brief Description : Process a Setup token recd. on EP0. Thile some of the
; : code may look sifficult to understand the end result is not.
; : The following simply prepares a byte of data for use in a jump table.
; : The code compresses the 8 byte bmRequestValue into 4 1/2
; : bits by removing bits 2,3 & 4. These bits are never used
; : and it allows the jump table to be signfigantly smaller.
; : By using this jump table, the code size reduces by several
; : hundred bytes over the entire code!
; : THIS FIRMWARE IS ASSUMES BITS 2,3 & 4 are zero!!!!
; : By compressing the byte down, we limit the size
; : of the jump table.
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
ProcessSetup1:
; The First step is setting up the Stage tracing variable by examing the
; bmRequest value. This will tell us if this is a control Write
; or control read command. For right now we will assume that this
; is a no data command and will therefore pre-initilize the data
; byte counters used to send data back, to zero.
mov gbFControlBufferBytesLeft1, #00h
mov gbFControlBufferBytesLeft1 + 1, #00h
mov A, bmRequestType1
jb ACC.7, SetupGetCommand1
SetupSetCommand1:
mov gbSetupSeqRX1, #DATA_PHASE ; Advance State Machine to next state
mov gbSetupSeqTX1, #STATUS_PHASE
; Now check to see if this is a control write with a data stage.
mov A, wLength1
orl A, wLength1+1
jz DoJumpTable1 ; If this is a no data command then process it
ret ; If we are expecting data then don't
; process the command yet. Exit and wait
; for the rest of the data to come in.
SetupGetCommand1:
mov gbSetupSeqRX1, #STATUS_PHASE ; Advance State Machine to next state
mov gbSetupSeqTX1, #DATA_PHASE
DoJumpTable1:
; This table will jump to the correct subroutine
; to handle the type of command contained in bmRequestType
; The new jmp table will be compressed by shifting and rotating
; out bits, 2,3 & 4.
; Place bmRequestType in the following order and then do the jump table
; on it.
; xx65107x
; if bits 65 == 11, Reserved = Error
; Unless you have time, don't spend a lot of time tracing the algorythm
; It's fancy and it works. If you don't understand it go ask someone for a quarter.
mov A, bmRequestType1 ; Get the value.
anl A, #0E3h ; Clear out bits 2,3,4 since
; we don't need these
; Reg A now looks like 765xxx10
RL A ; Put bits 1,0,& 7 in new placement
RL A ; Leave LSB cleared so jump is the number of words.
; xxxx1076
CheckBit6_1: ; 6 is currently in bit 0 position,
jnb ACC.0, CheckBit5_1 ; Convert it to bit 5 position
setb ACC.5 ; xx6x107x
CheckBit5_1: ; Bit 5 is currently at 7 position
jnb ACC.7, CheckValidType1 ; Convert it to bit 4 position
setb ACC.4 ; xx65107x
CheckValidType1: ;
jnb ACC.5, GoodCommand1 ; If this bit (6) is clear we know
; it's a valid value
jb ACC.4, ReservedCommand1 ; Bit (6) was set, if bit 5 is set it's
; a reserved command.
ljmp GoodCommand1
ReservedCommand1:
orl EPCON, #0C0h ; Stall EP0.
ret
; THis code will branch to the correct jump statement
; in the bmRequestJumpTable below.
GoodCommand1:
anl A, #3Eh
mov B, A
rr A
anl A, #1fH
clr CY
ADD A, B
mov DPTR, #bmRequestJumpTable1
mov DPXL, #LOW HIGH16(GoodCommand1) ; Get Page of Jump Table.
; Low byte of the upper 16 bits of the 32 bit address of the
; jump table.
; Is this code in RAM or ROM
jmp @A+DPTR ; Used because I use RISM sometimes
; which places code in RAM
;---------------------------------------
;-- bmRequest Jump Table ---------------
;-- The order of these are based on the
;-- compresion algorythm used above.
;-- Each of these instructions occupy two bytes of
;-- ROM. Do not change AJMP to LJMP as the algorytm depends on the
;-- 2 byte length of AJMP. LJMP is 3 bytes long
;-- ------------------------------------
bmRequestJumpTable1:
LJMP StandardSetDeviceCommand1
LJMP StandardGetDeviceCommand1
LJMP StandardSetInterfaceCommand1
LJMP StandardGetInterfaceCommand1
LJMP StandardSetEndpointCommand1
LJMP StandardGetEndpointCommand1
LJMP StandardSetOtherCommand1
LJMP StandardGetOtherCommand1
LJMP ClassSetDeviceCommand1
LJMP ClassGetDeviceCommand1
LJMP ClassSetInterfaceCommand1
LJMP ClassGetInterfaceCommand1
LJMP ClassSetEndpointCommand1
LJMP ClassGetEndpointCommand1
LJMP ClassSetOtherCommand1
LJMP ClassGetOtherCommand1
LJMP VendorSetDeviceCommand1
LJMP VendorGetDeviceCommand1
LJMP VendorSetInterfaceCommand1
LJMP VendorGetInterfaceCommand1
LJMP VendorSetEndpointCommand1
LJMP VendorGetEndpointCommand1
LJMP VendorSetOtherCommand1
LJMP VendorGetOtherCommand1
;-----------------------------------------------------------------
;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSs
;S
;S STANDARD TYPE COMMANDS FIRST
;S
;SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSs
;-----------------------------------------------------------------
;COMMENT *------------------------------------------------------------
;Function name : GetStandardDeviceCommand:
;Brief Description : Process a Get Standard Device Command Setup Token
; : This can only be a Get (Device or Configuration) Descriptor,
; : or Get Device Status, Get Configuration.
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
StandardGetDeviceCommand1:
mov A, bRequest1
cjne A, #GET_DESCRIPTOR, CheckGetConfiguration1
mov A, bDescriptorType1
cjne A, #DEVICE_DESCR, CheckConfigDescriptor1
; ********************** GET DESCRIPTOR, DEVICE *******************
mov gbFControlBufferLocation1, #LOW HIGH16(BEGIN_DEVICE_DESCRIPTOR)
mov gbFControlBufferLocation1+1, #HIGH LOW16(BEGIN_DEVICE_DESCRIPTOR)
mov gbFControlBufferLocation1+2, #LOW LOW16(BEGIN_DEVICE_DESCRIPTOR)
mov A, #12h
mov B, #00h
ljmp LoadBuffer1
CheckConfigDescriptor1:
cjne A, #CONFIG_DESCR, CheckStringDescriptor1
; ********************** GET DESCRIPTOR, CONFIGURATION ************
mov gbFControlBufferLocation1, #LOW HIGH16(BEGIN_CONFIG_DESCRIPTOR)
mov gbFControlBufferLocation1+1, #HIGH LOW16(BEGIN_CONFIG_DESCRIPTOR)
mov gbFControlBufferLocation1+2, #LOW LOW16(BEGIN_CONFIG_DESCRIPTOR)
mov A, #LOW (END_CONFIG_DESCRIPTOR - BEGIN_CONFIG_DESCRIPTOR)
mov B, #HIGH (END_CONFIG_DESCRIPTOR - BEGIN_CONFIG_DESCRIPTOR)
ljmp LoadBuffer1
CheckStringDescriptor1:
cjne A, #STRING_DESCR, ReturnBADSTDGetDeviceCommand1
; ********************** GET DESCRIPTOR, CONFIGURATION ************
mov gbFControlBufferLocation1, #LOW HIGH16(STRING_1)
mov gbFControlBufferLocation1+1, #HIGH LOW16(STRING_1)
mov gbFControlBufferLocation1+2, #LOW LOW16(STRING_1)
mov A, #LOW (STRING_2-STRING_1)
mov B, #HIGH(STRING_2-STRING_1)
ljmp LoadBuffer1
LoadBuffer1: ; Compare to see which is shorter.
; The amount asked for or the amount
; availible.
push ACC
push B
clr CY ; A=Actual-wLength1=AskedFor
subb A, wLength1+1
mov A, B
subb A, wLength1
jc AskedFor_IsLarger1
LengthsMatch1:
wLengthIsSmaller1: ; If Asked for is smaller, replace
; actual with asked for.
pop B
pop ACC
mov B, wLength1
mov A, wLength1+1
sjmp LoadIt1
AskedFor_IsLarger1:
pop B
pop ACC
LoadIt1: ; From now on, wLength1 = bytes remaining.
mov gbFControlBufferBytesLeft1, B
mov gbFControlBufferBytesLeft1+1, A
lcall LoadControlTXFifo1
ljmp ReturnSTDGetDeviceCommand1
CheckGetConfiguration1:
cjne A, #GET_CONFIGURATION, CheckGetStatus1
;------------------------------------------------
;- GET CONFIGURATION
;------------------------------------------------
mov R11, CurrentConfiguration1
mov TXDAT, A
mov TXCNTL,#01h
ljmp ReturnSTDGetDeviceCommand1
CheckGetStatus1:
cjne A, #GET_STATUS, ReturnSTDGetDeviceCommand1
;------------------------------------------------
;- GET DEVICE STATUS
;------------------------------------------------
jnb HRWUPE, NotRWUEnabled1
mov A, #03h ; RWU Enabled and self powered
sjmp DoneGetDeviceStatus1
NotRWUEnabled1:
mov A, #01h ; RWU Not Enabled and self powered
DoneGetDeviceStatus1:
mov TXDAT, A
mov TXDAT, #00h
mov TXCNTL,#02h
ljmp ReturnSTDGetDeviceCommand1
ReturnBADSTDGetDeviceCommand1:
orl EPCON, #0C0h ; Stall EP0
ReturnSTDGetDeviceCommand1:
ret
;COMMENT *------------------------------------------------------------
;Function name : StandardGetEndpointCommand:
;Brief Description : Process a Standard Set Endpoint Command Setup Token
; : This can only be a Set,Clear Feature - Endpoint Stall
; :
;Regs preserved : No reg. is saved
;--------------------------------------------------------------------*
;SCOPE
StandardGetEndpointCommand1:
mov A, bRequest1
cjne A, #GET_STATUS, ReturnBadSTDGetEPCommand1
;------------------------------------------------
;- GET ENDPOINT STATUS
;------------------------------------------------
mov A, wIndex1 + 1
anl A, #0Fh ; Mask off all but the endpoint value
orl EPINDEX,A ; Point the Index register at the
mov A, wIndex1 + 1 ; Start by clearing out R0
jb ACC.7, GetInStallStatus1
GetOutStallStatus1:
mov A, EPCON
jnb ACC.6, NotStalled1
mov A, #01 ; Return Stalled
ljmp DoneWithCommand1
GetInStallStatus1:
mov A, wIndex1 +1
anl A, #0Fh
cjne A, #00, GetEp1InStall1
mov A, EPCON
jnb ACC.7, NotStalled1
mov A, #01
sjmp DoneWithCommand1
GetEp1InStall1:
mov A, HSTAT ; GET EP1 Stall Information
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -