📄 js50.asm
字号:
add A, [configuration_status] ; get correct configuration
jmp execute ; send configuration to host
; The interface status is a 16-bit value (two bytes) that is always
; zero for both bytes.
GetInterfaceStatus:
mov A, 2 ; send two bytes
mov [data_count], A
mov A, (get_interface_status_table - control_read_table)
jmp execute ; send interface status to host
; The endpoint status is a 16-bit value (two bytes) with only one
; bit (D0) defined. If D0=0, then the selected endpoint is not
; stalled. If D0=1, then the selected endpoint is stalled.
GetEndpointStatus:
mov A, 2 ; send two bytes
mov [data_count], A
mov A, [endpoint_stall]
asl A ; select the correct entry
add A, (get_endpoint_status_table - control_read_table)
jmp execute ; send endpoint status to host
;------------------------------------------------------------------------
; Set Report
SetReport:
jmp SendStall ; *** not supported ***
; Set Idle silences a particular report on the interrupt pipe until a new
; event occurs or the specified amount of time (wValue) passes.
SetIdle:
jmp SendStall ; *** not supported ***
; Set Protocol switches between the boot protocol and the report protocol.
; For boot protocol, wValue=0. For report protocol, wValue=1.
; Note, the joystick firmware does not actually do anything with the
; protocol status, yet.
SetProtocol:
mov A, [wValue] ; load wValue
mov [protocol_status], A ; write new protocol value
call no_data_control ; handshake with host
ret ; return
; Get Report allows the host to receive a report via the control pipe.
; The report type is specified in the wValue high byte while the low
; byte has a report ID.
GetReport:
jmp SendStall ; currently not supported
GetReportDescriptor:
mov A, (end_hid_report_desc_table - hid_report_desc_table)
mov [data_count], A ; save descriptor length
mov A, (hid_report_desc_table - control_read_table)
call execute ; send descriptor to host
;
; Enumeration is complete!
;
ret ; return
; Get Idle reads the current idle rate for a particular input report.
GetIdle:
jmp SendStall ; *** not supported ***
; Get Protocol sends the current protocol status back to the host.
GetProtocol:
mov A, 1 ; send one byte
mov [data_count], A
mov A, (get_protocol_status_table - control_read_table)
add A, [protocol_status] ; get correct configuration
jmp execute ; send protocol to host
;========================================================================
; Standard Get Descriptor routines
;
; Return the device descriptor to the host.
GetDeviceDescriptor:
mov A, 0 ; load the device descriptor length
index device_desc_table
mov [data_count], A ; save the device descriptor length
mov A, (device_desc_table - control_read_table)
jmp execute ; send the device descriptor
; Return the configuration, interface, and endpoint descriptors.
GetConfigurationDescriptor:
mov A, (end_config_desc_table - config_desc_table)
mov [data_count], A ; save the descriptor length
mov A, (config_desc_table - control_read_table)
execute: ; send the descriptors
mov [data_start], A ; save start index
call get_descriptor_length ; correct the descriptor length
call control_read ; perform control read function
ret ; return
;------------------------------------------------------------------------
; HID class Get Descriptor routines
;
; Return the HID descriptor and enable endpoint one.
GetHIDDescriptor:
mov A, (Endpoint_Descriptor - Class_Descriptor)
mov [data_count], A ; save descriptor length
mov A, ( Class_Descriptor - control_read_table)
call execute ; send descriptor to host
ret ; return
;**********USB library main routines*******************
;******************************************************
; The host sometimes lies about the number of bytes it
; wants from a descriptor. Any request to get descriptor
; should return the lesser of the number of bytes requested
; or the actual length of the descriptor.
get_descriptor_length:
mov A, [wLengthHi] ; load requested transfer length
cmp A, 0 ; confirm high byte is zero
jnz use_actual_length ; no requests should be longer than 256b
mov A, [wLength] ; test low byte against zero
cmp A, 0
jz use_actual_length ; must request some data
cmp A, [data_count] ; compare to the amount of data
jnc use_actual_length
mov [data_count], A ; use requested length
use_actual_length:
ret ; return
;========================================================================
; function: no_data_control
; purpose: performs the no-data control operation
; as defined by the USB specifications
no_data_control:
mov A, C0h ; set up the transfer
iowr USB_EP0_TX_Config ; register for data1
; and 0 byte transfer
mov A, [interrupt_mask] ; enable interrupts
iowr Global_Interrupt
wait_nodata_sent:
iord USB_EP0_TX_Config ; wait for the data to be
and A, 80h ; transferred
jnz wait_nodata_sent
ret ; return to caller
;========================================================================
;******************************************************
;
; function: Control_read
; Purpose: Performs the control read operation
; as defined by the USB specification
; SETUP-IN-IN-IN...OUT
;
; data_start: must be set to the descriptors info
; as an offset from the beginning of the
; control read table
; data count holds the
; data_count: must be set to the size of the
; descriptor
;******************************************************
control_read:
push X ; save X on stack
mov A, 00h ; clear data 0/1 bit
mov [endp0_data_toggle], A
control_read_data_stage:
mov X, 00h
mov A, 00h
mov [loop_counter], A
iowr USB_EP0_RX_Status ; clear setup bit
; Fixing a bug seen by NEC hosts
iord USB_EP0_RX_Status ; check setup bit
and A, 01h ; if not cleared, another setup
jnz control_read_status_stage ; has arrived. Exit ISR
mov A, 08h ; set BADOUTS BIT
iowr USB_Status_Control
mov A, [data_count]
cmp A, 00h
jz control_read_status_stage
dma_load_loop: ; loop to load data into the data buffer
mov A, [data_start]
index control_read_table
mov [X + endpoint_0], A ; load dma buffer
inc [data_start]
inc X
inc [loop_counter]
dec [data_count] ; exit if descriptor
jz dma_load_done ; is done
mov A, [loop_counter] ; or 8 bytes sent
cmp A, 08h
jnz dma_load_loop
dma_load_done:
iord USB_EP0_RX_Status ; check setup bit
and A, 01h ; if not cleared, another setup
jnz control_read_status_stage ; has arrived. Exit ISR
mov A, [endp0_data_toggle]
xor A, 40h
mov [endp0_data_toggle], A
or A, 80h
or A, [loop_counter]
iowr USB_EP0_TX_Config
mov A, [interrupt_mask]
iowr Global_Interrupt
wait_control_read:
iord USB_EP0_TX_Config ; wait for the data to be
and A, 80h ; transfered
jz control_read_data_stage
iord USB_EP0_RX_Status
and A, 02h ; check if out was sent by host
jz wait_control_read
control_read_status_stage: ; OUT at end of data transfer
pop X ; restore X from stack
mov A, [interrupt_mask]
iowr Global_Interrupt
ret
;********** ROM lookup tables *************************************
XPAGEOFF
control_read_table:
device_desc_table:
db 12h ; Descriptor length (18 bytes)
db 01h ; Descriptor type (Device)
db 00h,01h ; Complies to USB Spec. Release (1.00)
db 00h ; Class code (0)
db 00h ; Subclass code (0)
db 00h ; Protocol (No specific protocol)
db 08h ; Max. packet size for EP0 (8 bytes)
db B4h,04h ; Vendor ID (Cypress)
db 1fh,0fh ; Product ID (Sidewinder = 0x0f1f)
db 88h,02h ; Device release number (2.88)
db 00h ; Mfr string descriptor index (None)
db 00h ; Product string descriptor index (None)
db 00h ; Serial Number string descriptor index (None)
db 01h ; Number of possible configurations (1)
end_device_desc_table:
config_desc_table:
db 09h ; Descriptor length (9 bytes)
db 02h ; Descriptor type (Configuration)
db 22h,00h ; Total data length (34 bytes)
db 01h ; Interface supported (1)
db 01h ; Configuration value (1)
db 00h ; Index of string descriptor (None)
db 80h ; Configuration (Bus powered)
db 32h ; Maximum power consumption (100mA)
Interface_Descriptor:
db 09h ; Descriptor length (9 bytes)
db 04h ; Descriptor type (Interface)
db 00h ; Number of interface (0)
db 00h ; Alternate setting (0)
db 01h ; Number of interface endpoint (1)
db 03h ; Class code ()
db 00h ; Subclass code ()
db 00h ; Protocol code ()
db 00h ; Index of string()
Class_Descriptor:
db 09h ; Descriptor length (9 bytes)
db 21h ; Descriptor type (HID)
db 00h,01h ; HID class release number (1.00)
db 00h ; Localized country code (None)
db 01h ; # of HID class dscrptr to follow (1)
db 22h ; Report descriptor type (HID)
; Total length of report descriptor
db (end_hid_report_desc_table - hid_report_desc_table),00h
Endpoint_Descriptor:
db 07h ; Descriptor length (7 bytes)
db 05h ; Descriptor type (Endpoint)
db 81h ; Encoded address (Respond to IN, 1 endpoint)
db 03h ; Endpoint attribute (Interrupt transfer)
db 06h,00h ; Maximum packet size (6 bytes)
db 0Ah ; Polling interval (10 ms)
end_config_desc_table:
hid_report_desc_table:
db 05h, 01h ; Usage Page (Generic Desktop)
db 09h, 04h ; Usage (Joystick)
db A1h, 01h ; Collection (Application)
db 09h, 01h ; Usage (Pointer)
db A1h, 00h ; Collection (Physical)
db 05h, 01h ; Usage Page (Generic Desktop)
db 09h, 30h ; Usage (X)
db 09h, 31h ; Usage (Y)
db 15h, 80h ; Logical Minimum (-127)
db 25h, 7Fh ; Logical Maximum (127)
db 35h, 00h ; Physical Minimum (0)
db 45h, FFh ; Physical Maximum (255)
db 66h, 00h, 00h; Unit (None (2 bytes))
db 75h, 08h ; Report Size (8) (bits)
db 95h, 02h ; Report Count (2) (fields)
db 81h, 02h ; Input (Data, Variable, Absolute)
db 09h, 35h ; Usage (Rotation about z-axis)
db 15h, C0h ; Logical Minimum (-64)
db 25h, 3Fh ; Logical Maximum (63)
db 35h, 00h ; Physical Minimum (0)
db 46h, FFh, 00h; Physical Maximum (255)
db 66h, 00h, 00h; Unit (None (2 bytes))
db 75h, 08h ; Report size (8)
db 95h, 01h ; Report Count (1)
db 81h, 02h ; Input (Data, Variable, Absolute)
db 09h, 39h ; Usage (Hat switch)
db 15h, 01h ; Logical Minimum (1)
db 25h, 08h ; Logical Maximum (8)
db 36h, 00h, 00h; Physical Minimum (0) (2 bytes)
db 46h, 3Bh, 01h; Physical Maximum (315) (2 bytes)
db 65h, 14h ; Unit (Degrees)
db 75h, 08h ; Report Size (8)
db 95h, 01h ; Report Count (1)
db 81h, 02h ; Input (Data, Variable, Absolute)
db 05h, 09h ; Usage page (buttons)
db 19h, 01h ; Usage minimum (1)
db 29h, 04h ; Usage maximum (4)
db 15h, 00h ; Logical Minimum (0)
db 25h, 01h ; Logical Maximum (1)
db 35h, 00h ; Physical Minimum (0)
db 45h, 01h ; Physical Maximum (1)
db 75h, 01h ; Report Size (1)
db 95h, 04h ; Report Count (4)
db 81h, 02h ; Input (Data, Variable, Absolute)
db 95h, 01h ; Report Size (1)
db 75h, 04h ; Report Count (4)
db 81h, 01h ; input (4 bit padding)
db C0h ; End Collection
db 05h, 01h ; Usage Page (Generic Desktop)
db 09h, 36h ; Usage (Slider)
db 15h, 00h ; Logical Minimum (0)
db 26h, FFh, 00h; Logical Maximum (255)
db 35h, 00h ; Physical Minimum (0)
db 46h, FFh, 00h; Physical Maximum (255)
db 75h, 08h ; Report Size (8)
db 66h, 00h, 00h; Unit (None)
db 95h, 01h ; Report Count (1)
db 81h, 02h ; Input (Data, Variable, Absolute)
db C0h ; End Collection
end_hid_report_desc_table:
;========================================================================
; These tables are the mechanism used to return status information to the
; host. The status can be either device, interface, or endpoint.
get_dev_status_table:
db 00h, 00h ; remote wakeup disabled, bus powered
db 02h, 00h ; remote wakeup enabled, bus powered
get_interface_status_table:
db 00h, 00h ; always return both bytes zero
get_endpoint_status_table:
db 00h, 00h ; not stalled
db 01h, 00h ; stalled
get_configuration_status_table:
db 00h ; not configured
db 01h ; configured
get_protocol_status_table:
db 00h ; boot protocol
db 01h ; report protocol
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -