- PS2M_Send:
- _PS2M_Send:
- .data: equ -1 ; Local stack variables
- .cnt: equ -2
- .parity: equ -3
- ; M8C_DisableGInt
- PUSH X ; Build the local variable
- ADD SP, 3 ;
- MOV X, SP ;
- MOV [X + .data], A ; Save off the data byte
- MOV [X + .parity], 1 ; Start the parity at 1
- MOV [X + .cnt], 8 ; Send 8 data bits
- MOV [_fHostRqs], 0
- ; Test for inhibit
- TST REG[PS2M_DR], PS2M_SCLK ; Inhibit?
- JZ .rts ; Continue to wait if we are inhibited
- DELAY 20, 60 ; Min delay between check for inhibit
- TST REG[PS2M_DR], PS2M_SCLK ; Inhibit?
- JZ .rts ; Continue to wait if we are inhibited
- ; Test for RTS
- TST REG[PS2M_DR], PS2M_SDATA ; RTS?
- JZ .rts ; Jump if RTS
- ; change data pin to output mode
- OR REG[P01CR], 0x01
- OR REG[P02CR], 0x01 ;test debug
- ; Flow here to send start bit
- CALL PS2M_Send_0 ; Start bits are zero
- JC .inhib ; Host has inhibited
- DELAY 2, 12 ; Wait 2 uSec
- ; Flow or jump here to sent the data bits
- .snb:
- ASR [X + .data] ; rotate the next bit to the carry
- JC .s1 ; and send a 1 or 0 based
- .s0:
- CALL PS2M_Send_0 ; Send 0
- JMP .cont
- .s1:
- INC [X + .parity] ; Count the number of 1 bits for the parity
- CALL PS2M_Send_1 ; Send 1
- .cont:
- JC .inhib ; Did the host inhibit us during the last bit?
- DEC [X + .cnt] ; If not, send the next bit
- JZ .s_parity ; When it hits zero, do the parity
- JNC .snb ; It will carry after the parity bit is sent
- ; Flow here to send the stop bit
- CALL PS2M_Send_1 ; Stop bits are 1
- JMP .success
-
- ; Flow here after all 8 data bits have been clocked out
- .s_parity:
- MOV A, [X + .parity] ; clock out the lsb of the parity
- MOV [X + .data],a ; Save the data
- JMP .snb
- ; Jump here on a successful stop bit
- .success:
- MOV A, 0 ; Flow here after a successful stop bit
- ; CMP [PS2M_bCmdCnt], 0x00
- ; JZ .exit
- ; CALL PS2M_ReadSendBuffer
- JMP .exit
- ; Jump here if we failed because we were inhibited
- .inhib: ; Jump here for any failed bit
- OR reg[PS2M_DR], PS2M_CLKH_DATAH
- MOV [_fHostRqs], 1
- MOV A, 0x88
- JMP .exit
- ; Jump here if we found a RTS
- .rts: ; Jump here for a RTS
- MOV A, 0x90 ;
- ; Jump or flow here to exit
- .exit:
- ;change data pin to input mode
- AND REG[P01CR], 0xfe
- AND REG[P02CR], 0xfe ;test debug
- ADD SP, -3 ; Clean up the stack
- POP X
- ; M8C_EnableGInt
- PUSH A
- DELAY 38, 12 ; Wait 38 uSec
- POP A
- RET
- ;-----------------------------------------------------------------------------
- ; FUNCTION NAME: PS2M_Send_1, PS2M_Send_0
- ; DESCRIPTION: Local function. Assembly interface only.
- ;
- ;-----------------------------------------------------------------------------
- ;
- ; ARGUMENTS:
- ;
- ; RETURNS:
- ;
- ; SIDE EFFECTS: REGISTERS ARE VOLATILE: THE A AND X REGISTERS MAY BE MODIFIED!
- ;
- ; THEORY of OPERATION or PROCEDURE:
- ;
- ;-----------------------------------------------------------------------------
- PS2M_Send_1:
- OR REG[PS2M_DR], PS2M_SDATA ; Set the data bit high
- DELAY 10, 12 ; Wait 10 uSec
- ; Clock Low ; Clock Low and the data
- AND REG[PS2M_DR], ~PS2M_SCLK ; Clock Low
- DELAY 38, 12 ; Wait 38 uSec
- ; Clock High ; Finally Clock High and the data
- OR REG[PS2M_DR], PS2M_SCLK ; Clock High
- DELAY 22, 60 ; Wait 22 uSec
- ; Check for inhibit
- CLEARC ; Carry clear indicates success
- AND REG[P02CR], 0xfe ;test debug
- TST REG[PS2M_DR], PS2M_SCLK ; Inhibit?
- JNZ .clock_done ; Jump if not
- SETC ; Carry set indicates fail/Inhibit
- .clock_done:
- ; Done
- OR REG[P02CR], 0x01 ;test debug
- RET
- PS2M_Send_0:
- AND REG[PS2M_DR], ~PS2M_SDATA ; clear the data bit high
- DELAY 10, 12 ; Wait 10 uSec
- ; Clock Low ; Clock Low and the data
- AND REG[PS2M_DR], ~PS2M_SCLK ; Clock Low
- DELAY 38, 12 ; Wait 38 uSec
- ; Clock High ; Finally Clock High and the data
- OR REG[PS2M_DR], PS2M_SCLK ; Clock High
- DELAY 22, 60 ; Wait 22 uSec
- ; Check for inhibit
- CLEARC ; Carry clear indicates success
- AND REG[P02CR], 0xfe ;test debug
- TST REG[PS2M_DR], PS2M_SCLK ; Inhibit?
- JNZ .clock_done ; Jump if not
- SETC ; Carry set indicates fail/Inhibit
- .clock_done:
- ; Done
- OR REG[P02CR], 0x01 ;test debug
- RET