📄 usb.asm
字号:
;-----------------------------------------------------------------------------
;
; ARGUMENTS: A the endpoint number
;
; 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.
;
.SECTION
USB_DisableOutEP:
_USB_DisableOutEP:
cmp A, 0 ; Can't disable EP0
jz .exit ; Bail out
cmp A, (USB_MAX_EP_NUMBER + 1) ; Range check
jnc .exit ; Bail out
; Flow here to disable an endpoint
mov X, A ; Endpoint number is the index
M8C_SetBank1
mov A, reg[X+USB_EP1MODE-1] ; Unlock the mode register
mov reg[X+USB_EP1MODE-1], USB_MODE_NAK_OUT ; Disable the endpoint
M8C_SetBank0
; Jump or flow here for a common exit
.exit:
ret ; All done
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_Force
;
; DESCRIPTION: Force the J/K/SE0 State of D+/D-
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: A: USB_FORCE_J
; USB_FORCE_K
; USB_FORCE_SE0
; USB_FORCE_NONE
;
; RETURNS: Nothing
;
; 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.
;
USB_Force:
_USB_Force:
mov reg[USB_USBIO_CR0], A
ret ; Exit
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_bReadOutEP
;
; DESCRIPTION: This function reads the data from the USB Out endpoint
; and loads it into the specified buffer.
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS:
; [SP-7] MSB of Count to read
; [SP-6] LSB of Count to read
; [SP-5] MSB of data array address to put data in
; [SP-4] LSB of data array address to put data in
; [SP-3] Endpoint Number
;
; 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
; IDX_PP
;
EP_NUMR: equ -3 ; Endpoint Number
DATA_LSBR: equ -4 ; MSB pointer of data
DATA_MSBR: equ -5 ; LSB pointer of data
CNTLEN_LSBR: equ -6 ; Length of data to send
CNTLEN_MSBR: equ -7
//asdf PG3_DATA: EQU 0x80 ; TEST ONLY ASDF WRF
USB_bReadOutEP:
_USB_bReadOutEP:
RAM_PROLOGUE RAM_USE_CLASS_4
RAM_PROLOGUE RAM_USE_CLASS_3
RAM_SETPAGE_CUR >USB_bCurrentDevice ; Set the CUR_PP to the right page
RAM_SETPAGE_IDX2STK
mov X, SP
mov A, [X+EP_NUMR]
CMP A, USB_MAX_EP_NUMBER+1 ; Range check
JNC .exit ; Bail out
;Get the count value passed
mov A, [X+CNTLEN_MSBR] ; Get the MSB of the Count
and A, 0x01 ; Mask off the count bit
mov [USB_APITemp], A ; Save the count
mov A, [X+CNTLEN_LSBR] ; Get the LSB of the Count
mov [USB_APITemp+1], A ; Save the count
;Determine which is smaller the requested data or the available data
mov A, [X+EP_NUMR] ; Get the Endpoint number
asl A ; Double the ep number for proper cnt access
mov X, A ; Make it into an index
mov A, reg[X+USB_EP1CNT1 - 2] ; Get the Real count MSB
and A, 0x01 ; Mask off the LSB
cmp A, [USB_APITemp] ; Are they equal
jz .MSBEqual ; If they are check if they are 1
jc .CountDetermined ;If the requested count is smaller use it
mov [USB_APITemp], A ; Else use the actual
mov A, reg[X+USB_EP1CNT1 - 1] ; Get the Real count LSB
mov [USB_APITemp + 1], A ; Else use the actual
jmp .CountDetermined
.MSBEqual:
mov A, [USB_APITemp]
jz .CheckLSB
mov [USB_APITemp + 1], 0
jmp .CountDetermined
.CheckLSB:
mov A, reg[X+USB_EP1CNT1 - 1] ; Get the Real count LSB
cmp A, [USB_APITemp+1] ; Are they equal
jz .CountDetermined ; If they are check if they are 1
jnc .CountDetermined ;If the requested count is smaller use it
mov [USB_APITemp+1], A ; Else use the actual
.CountDetermined:
; First we need to determine where within the PMA the EP Start Address is
mov X, SP ; Get the Stack Pointer
mov A, [X+EP_NUMR] ; Get the Endpoint number
mov X, A ; Use the EP number as an index
mov A, reg[X+TMP_DR0-1] ; Get the address of ep from tmp register
M8C_SetBank1
; =====================================================================
IF NDX_WORKAROUND
mov [ndxUsbTmp], A ; ndx
ELSE
M8C_DisableGInt ; Required for VoIP
mov reg[PMA0_RA], A ; Set the Read pointer of our pma to ep space
M8C_EnableGInt ; Required for VoIP
ENDIF
; =====================================================================
M8C_SetBank0
; Now we are ready to start moving data
and [USB_APITemp], 0x01 ; Mask off the MSB bit
jnz .start_send ; If it is high then we have 256 bytes
mov A, [USB_APITemp+1] ; Check the LSB register
jz .done ; If it is 0 then we have a 0 length packet
.start_send:
mov X, SP
mov A, [X+DATA_LSBR] ; Get the LSB of the pointer
push A ; save on stack
IF SYSTEM_LARGE_MEMORY_MODEL
mov A, [X+DATA_MSBR] ; Get the MSB of the pointer
mov reg[IDX_PP], A ; Use as value for IDX_PP
ENDIF
pop X ; Get the LSB again
IF NDX_WORKAROUND
ELSE ;; CHANGE TO 12MHZ CLOCK WORKAROUND
;;
;; 24Mhz read PMA workaround (kvn)
;;
M8C_SetBank1
mov A, reg[OSC_CR0]
push A
and A, 0xf8 ; ZERO CPU speed bits
or A, OSC_CR0_CPU_12MHz ; Specify
mov reg[OSC_CR0],A ; clk is now set at 12Mhz
M8C_SetBank0
ENDIF
.loop:
IF NDX_WORKAROUND
M8C_SetBank1 ; ndx workaround
mov A, [ndxUsbTmp] ; ndx workaround
; =====================================================================
; Interrupts MUST be disabled when writing to reg[PMA0_RA] for a
; consistently correct write. With no workaround, consistency varies
; from device-to-device. The workaround mentioned in KVN #12
; "Out Endpt PMA register failure at 24 MHz" also fails here,
; for unknown reasons.
; =====================================================================
M8C_DisableGInt ; Required for VoIP
mov reg[PMA0_RA], A ; ndx workaround
M8C_EnableGInt ; Required for VoIP
inc [ndxUsbTmp] ; ndx workaround
M8C_SetBank0 ; ndx workaround
ENDIF
mov A, reg[PMA0_DR] ; Get the data from the PMA space
mov [X], A ; save it in data array
inc X ; increment the pointer
dec [USB_APITemp+1] ; decrement the counter
jnz .loop ; wait for count to zero out
//asdf ; =============================================================================
//asdf ; =============================================================================
//asdf ; FOLLOWING CODE COPIES USB BUFFER TO PAGE 3 FOR NON-REALTIME DUMP
//asdf tst [_pg3ptr], 0
//asdf jnz .S10
//asdf
//asdf MOV A, REG[MVR_PP]
//asdf push a
//asdf mov a, reg[MVW_PP]
//asdf push a
//asdf
//asdf mov a, x
//asdf sub a, 16
//asdf mov x, a
//asdf
//asdf mov reg[MVR_PP], 1
//asdf mov [_pg1ptr], x
//asdf mov reg[MVW_PP], 3
//asdf mov [_pg3ptr], PG3_DATA
//asdf mov [nonIsrCt], 8
//asdf .L10:
//asdf mvi a, [_pg1ptr]
//asdf cmp a, 0x38
//asdf jz .S1
//asdf nop
//asdf nop
//asdf .S1:
//asdf mvi [_pg3ptr], a
//asdf
//asdf mvi a, [_pg1ptr]
//asdf cmp a, 0x19
//asdf jz .S2
//asdf nop
//asdf nop
//asdf .S2:
//asdf mvi [_pg3ptr], a
//asdf dec [nonIsrCt]
//asdf jnz .L10
//asdf
//asdf pop a
//asdf mov reg[MVW_PP], a
//asdf pop a
//asdf mov reg[MVR_PP], a
//asdf .S10:
//asdf ; PRIOR CODE COPIES USB BUFFER TO PAGE 3 FOR NON-REALTIME DUMP
//asdf ; =============================================================================
//asdf ; =============================================================================
IF NDX_WORKAROUND
ELSE ;; CHANGE TO 12MHZ CLOCK WORKAROUND
;; 24Mhz read PMA workaround (back to previous clock speed (kvn)
pop A ;recover previous reg[OSC_CR0] value
M8C_SetBank1
mov reg[OSC_CR0],A ;clk is now set at previous value (probably 24Mhz)
M8C_SetBank0
;; end 24Mhz read PMA workaround (kvn)
ENDIF
RAM_SETPAGE_IDX2STK
mov X, SP
mov A, [X+EP_NUMR]
asl A
mov X, A
mov A, reg[X+USB_EP1CNT1 - 1] ; Get the Real count LSB
sub A, 2
.done:
.exit:
RAM_EPILOGUE RAM_USE_CLASS_3
RAM_EPILOGUE RAM_USE_CLASS_4
ret
.ENDSECTION
.SECTION
;-----------------------------------------------------------------------------
; FUNCTION NAME: USB_bGetEPAckState
;
; DESCRIPTION: Returns whether the ACK bit of EP has been set for
; an endpoint
;
;-----------------------------------------------------------------------------
;
; ARGUMENTS: A is the Endpoint Number
;
; RETURNS: A is 0 if ACK bit is not set and non-zero if it is
;
; 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.
;
USB_bGetEPAckState:
_USB_bGetEPAckState:
mov X, A
M8C_SetBank1
mov A, reg[X + USB_EP1MODE-1]
M8C_SetBank0
and A, 0x10
ret ; Exit
.ENDSECTION
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -