⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps2_io.asm

📁 CY7C63743 usb键盘的源码
💻 ASM
字号:
;========================================================================
;   FILE: ps2_io.asm
;
;   This file contains the code that sends/receives data via the 
;   D- and D+ output pins, in ps2 format
;REVISION_HISTORY:
;
;8/25/98 Added a 50 usec delay prior to sending commands. 
;Some PC's did not like it without this delay.
;
;
;========================================================================
;
;defines for the 4 combinations of clock and data

CLKH_DATAH:                  equ     DPH_DMH
CLKL_DATAH:                  equ     DPL_DMH
CLKH_DATAL:                  equ     DPH_DML
CLKL_DATAL:                  equ     DPL_DML


;========================================================================
; FUNCTION: ps2_send
;
; Sends a byte 
;
;
; Returns: 
;   C= 0 if transmission was successful
;   C= 1 if not
;
;========================================================================



ps2_send:
    push    A                                   ;save our data byte                    
    push    X                                   ;save X register

    mov     X,A                                 ;save data byte momentarily in X               
    iord    USB_STATUS_CONTROL_REG              ;get clock/data pair
    and     A,(PS2_CLOCK_BIT + PS2_DATA_BIT)    ;mask off other bits in port
    cmp     A,(PS2_CLOCK_BIT + PS2_DATA_BIT)    ;if both are not high,
    jz      .l1            
    SETC
    jmp     .exit                               ;exit this routine with carry set

.l1:
    DELAY   50
    call    send_0                              ;clock out start bit
    jc      .exit                               ;if a problem, quit now
    mov     A,1
    mov     [ps2_temp0],A                       ;keep track of parity
    mov     A,X                                 ;get back our data byte
    mov     X,8                                 ;count 8 bits
.l2:
    asr     A                                   ;shift bit to send into carry
    jc      .one                                ;if carry is zero
    call    send_0                              ;send a zero
    jc      .exit                               ;problem, quit now
    jmp     .next                               ;
.one:                                           ;else
    call    send_1                              ;  send a 1
    jc      .exit                               ;  problem, quit now
    inc     [ps2_temp0]                         ;  keep track of parity
.next:                                          ;
    dec     X                                   ;decrement counter
    jz      .parity                             ;if at zero do parity
    jnc     .l2                                 ;if -1, exit

 .stopbit:
    call    send_1                              ;clock out stop bit  
    CLEARC
    jmp     .exit

.parity:
    mov     A,[ps2_temp0]                      ;now send parity too
    jmp     .l2

.exit:
    mov     A,CLKH_DATAH                       ;make sure PS2 bus is left idle
    iowr    USB_STATUS_CONTROL_REG
    pop     X
    pop A
    ret                                        ;return



;========================================================================
; FUNCTION: send_0,send_1
;
; Sends bit out the ps2 port
;
;
; Returns: 
;   C= 0 if transmission was successful
;   C= 1 if not
;
;========================================================================



;
;the following state table defines the next state for the clock-data pair
;to clock out a given bit.
;
XPAGEOFF
drive_table:
        db          0,0,0,CLKH_DATAL,0,CLKL_DATAL,CLKH_DATAH,CLKL_DATAH
XPAGEON



send_1:
    push    A
    mov     A,CLKH_DATAH                        ;start with clock high, data high
    jmp     clock
send_0:
    push    A
    mov     A,CLKH_DATAL                        ;start with clock high, data low

clock:
    push    A
    iord    USB_STATUS_CONTROL_REG              ;read clock
    and        A,PS2_CLOCK_BIT            
    pop     A    
    jnz     .l2
    SETC
    pop     A                                          ;should be high
    ret
.l2:
    iowr    USB_STATUS_CONTROL_REG              ;set up register
    DELAY    5 
    index   drive_table                         ;wait 5 us
    iowr    USB_STATUS_CONTROL_REG              ;write it out
    DELAY    35                                 ;delay as per spec
    index   drive_table                         ;deassert clock
    iowr    USB_STATUS_CONTROL_REG
    DELAY    30                                 ;wait as per spec
    CLEARC
    pop    A
    ret

;========================================================================
; FUNCTION: getbit
;
; Receives  a bit
;
;
; Returns: 
;   C = state of bit clocked in
;
;========================================================================
getbit:
    push    A                               ;push A
    iord    USB_STATUS_CONTROL_REG          ;if inhibit, get out now
    and     A,PS2_CLOCK_BIT
    jz      .error
    mov     A,CLKL_DATAH                    ;start with clock low, data high
    iowr    USB_STATUS_CONTROL_REG          
    DELAY    35                             ;wait 35 usec
    mov     A,CLKH_DATAH                    ;raise clock line
    iowr    USB_STATUS_CONTROL_REG          ;
    DELAY    5                              ;wait 5 usec 
    iord    USB_STATUS_CONTROL_REG          ;read the data line
    DELAY    30                             ;wait 25 usec
    and    a,  PS2_DATA_BIT                 ;mask off all but data bit
    jz      .low                            ;if data bit high,
    SETC                                    ;set the carry
.low:
    pop     A                               ;pop acc and rotate carry into msb
    rrc     A
    CLEARC                                  ;clear carry indicating success
    ret                                     ;return
.error:
    pop     A
    SETC
    ret
    


   


;========================================================================
; FUNCTION: ps2_receive
;
; Receives a byte 
;
;
; Returns: 
;   C= 0 if reception was successful
;   C= 1 if not
;
;========================================================================



ps2_receive:
    push    X                                   ;save X, we'll wipe it out

    mov     X,18                                ;do the following 18 times:
.wait:                                          ;
    DELAY   7                                   ;kill time for 7 us
    iord    USB_STATUS_CONTROL_REG              ;get port 3 data
    and     A,PS2_DATA_BIT                      ;make sure data bit low
    jnz      .exitearly                         ;out now if not
    dec     X                                   ;wait again
    jnz     .wait                               ;
                                                ;above loop consumes approx 180 us.

.start:
    

;    DELAY    5                                  ;wait prior to anything
    mov     X,8                                 ;count 9  bits (8 data, 1 parity)
    mov     A,0                                 ;clear parity count
    mov     [ps2_temp0],A

.l1:
    call    getbit
    jc      .inhibit                            ;if not inhibiting
    cmp     A,80h                               ;see if msbit = 1
    jc      .next                               ;yup,
    inc     [ps2_temp0]                         ;increment parity count
.next:
    dec     X                                   ;decrement counter
    jc      .done                               ;if at -1, done    
    jnz     .l1    
    push    A                                   ;else save partial result
    jmp     .l1

.inhibit:                                       ;we were inhibited in
    dec     X                                   ;the middle of getting stuff,
    jc     .done                               ;adjust stack appropriately
    push    A
.done:
    
    ;arrive here with data byte on the stack and the received parity bit in the msb
    ;of the accumulator. the calculated parity bit is in the lsb of ps2_temp0.
    ;if we arrived here due to host inhibit, both parity and data byte are
    ;garbage but that's ok -- we'll abort out of this routine anyway.
    mov     A,[ps2_temp0]                        ;
    and     A,1
    mov     X,A
                                                 ;X should be 1 if ok

    call    getbit                               ;get stop bit
    jc     .error                                ;if no problem getting it
    rlc     a                           
    jc     .ack                                 ;if it's not a 1
    mov     X,0                                  ;X= 0 indicates an error

.badstop:                                       ;
    call    getbit                              ;keep looking for it
    jc      .error
    rlc     a
    jnc    .badstop

.ack:
                                                ;arrive here with x = 0 if no errors
    call    send_0                              ;send a 0 to ack the transaction
    mov     A,X
    cmp     A,0
    jz     .error

.exit:
    mov     A,CLKH_DATAH                        ;make sure PS2 bus is left idle
    iowr    USB_STATUS_CONTROL_REG
	jmp	.return

.error:
    mov     A,CLKH_DATAH                        ;make sure PS2 bus is left idle
    iowr    USB_STATUS_CONTROL_REG
	SETC                                         ;set carry indicating a problem
.return:
    pop     A                                    ;pop result into ACC  
    pop     X                                    ;restore X
    ret
 .exitearly:
    SETC
    pop     X
    ret





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -