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