;****************************************************************************
;FUNCTION: THIS ROUTINE IS TO DECODE EACH STEP DATA INTO BUTTON PATTERN.
; THE INPUT IS A POINTER POINTS AT THE CURRENT STEP DATA. THE FIRST
; BYTE IS RETRIEVED AND TESTED TO CONFIRM THE STEP LENGTH. DECODED
; PATTERN IS STORED TO THE DECODED BUFFERS (2 BYTES) AND THE LENGTH
; OF THE STEP TO W REGISTER. THE INPUT POINTER IS MODIFIED TO
; POINT AT THE NEXT STEP ON EXIT. REPEAT FUNCTION WILL BE DECODED
; TO NUMBER OF TIME OF REPETITION TO SET STEP TIMER TO 1, 2, 4 AND
; 8 AS REQUIRED. THE DECODED PATTERN WILL BE THE LAST VALID FIRE
; STEP PATTERN.
;FILENAME: C:\PROJECTS\SV363\DECODE.ASM
;ROUTINE NAME: DECODE
;INPUT: PTR_NXT WHICH POINTS AT THE CURRENT STEP LOCATION
;OUTPUT: W REGISTER = CURRENT STEP SIZE
; DCODE_PB0, DCODE_PB1 = DECODED BIT PATTERN
; PTR_NXT = NEXT STEP POINTER
; LAST_PB0, LAST_PB1 = DECODED BIT PATTERN
; dur_step = STEP DURATION
;RAM AFFECTED: 65H,64H,63H,5EH,5DH,61H,60H
;SUBROUTINE CALL:
;****************************************************************************
;
#define step_buf0 pgm_buf0 ;RAM LOCATION 65H
#define step_buf1 pgm_buf1 ;RAM LOCATION 64H
#define step_buf2 pgm_buf2 ;RAM LOCATION 63H
#define dcode_pb0 ee_buf0 ;RAM LOCATION 5EH
#define dcode_pb1 ee_buf1 ;RAM LOCATION 5DH
#define last_pb0 mem_free ;RAM LOCATION 6BH
#define last_pb1 data_length ;RAM LOCATION 66H
;
decode:
movf ptr_nxt,W ;USE INDIRECT TO ACCESS STEP INFORMATION
movwf FSR ;AND STORE TO STEP BUFFERS
movf INDF,W
movwf step_buf0
incf FSR,F
movf INDF,W
movwf step_buf1
incf FSR,F
movf INDF,W
movwf step_buf2
;
movlw 0xff ;INITIALIZE DCODE_PB'S TO FF
movwf dcode_pb0
movwf dcode_pb1
;
movlw 0xff ;SEE IF 1ST BYTE = FF -> MULTI BUTTON STEP
subwf step_buf0,W
btfss STATUS,Z ; skpz
goto three_pb ;GOTO CHECK IF THREE BUTTON CODE
multipb:
movf step_buf1,W ;BUFFER ALREADY CONTAINS BIT PATTERN
movwf dcode_pb1 ;SO CAN DIRECTLY STORE TO DECODED BUFFER
movwf last_pb1 ;STORE ALSO TO LAST_PB BUFFER FOR REPEAT STEP
movf step_buf2,W
movwf dcode_pb0
bsf STATUS,RP0
movwf last_pb0
bcf STATUS,RP0
movlw STEP_TMR_1 ;SET STEP TIMER TO DEFAULT 1
movwf dur_step
movlw STEP_SIZE_3 ;UPDATE NEXT STEP POINTER AND W = STEP SIZE
addwf ptr_nxt,F
return
;
three_pb:
movlw 0x0f ;MASK THE LOWER DIGIT TO TEST FOR 3 BUTTON
iorwf step_buf0,W ;STEP IF RESULT IS FF
bcf STATUS,C ;clrc
addlw 0x02 ;INCREMENT TO SEE IF CARRY SET
; movwf temp_buf3
; sublw 0x02
btfss STATUS,C ;skpc ;IF CARRY SET -> THREE BUTTON STEP
goto one_pb0
movlw 0x0f ;MASK THE UPPER DIGIT TO LOCATE BIT ASSERTED
andwf step_buf0,W ;RETRIEVE THE BIT INFORMATION TO W REGISTER
call clr_pb_bit
movlw 0x0f ;MASK THE NEXT BYTE AGAIN TO RETRIEVE THE
andwf step_buf1,W ;SECOND BIT ASSERTED DATA
call clr_pb_bit
swapf step_buf1,F ;TRANSFER THE UPPER DIGIT TO LOWER DIGIT
movlw 0x0f ;TO RETRIEVE THE THIRD BIT ASSERTED DATA
andwf step_buf1,W ;MASK TO GIVE THE ASSERTED BIT #
call clr_pb_bit
movf dcode_pb1,W ;STORE THE DECODED PB'S TO LAST PB'S
movwf last_pb1
movf dcode_pb0,W
bsf STATUS,RP0
movwf last_pb0
bcf STATUS,RP0
movlw STEP_TMR_1 ;SET STEP TIMER TO DEFAULT 1
movwf dur_step
movlw STEP_SIZE_2 ;UPDATE NEXT STEP POINTER AND W = STEP SIZE
addwf ptr_nxt,F
return
;
one_pb0:
movf step_buf0,W ;SEE IF UPPER DIGIT = LOWER DIGIT
swapf step_buf0,F ;IF EQUAL -> ONE BUTTON STEP
subwf step_buf0,W
swapf step_buf0,F ;SWAP BACK THE HIGH & LOW DIGIT
btfss STATUS,Z ; skpz
goto two_pb0
movlw 0x0f ;SET UP W TO MASK UPPER DIGIT
andwf step_buf0,F ;STEP_BUF0 NOW = BIT # ASSERTED
movf step_buf0,W
sublw 0x0e ;SEE IF IDLE PERIOD
btfsc STATUS,Z ; skpnz
goto idle_pb
;
movf step_buf0,W
call clr_pb_bit ;CLEAR THE CORRESPONDING BIT IN DECODE BUFFER
movf dcode_pb1,W ;STORE THE DECODED PB'S TO LAST PB'S
movwf last_pb1
movf dcode_pb0,W
bsf STATUS,RP0
movwf last_pb0
bcf STATUS,RP0
movlw STEP_TMR_1 ;SET STEP TIMER TO DEFAULT 1
movwf dur_step
movlw STEP_SIZE_1 ;UPDATE NEXT STEP POINTER AND W = STEP SIZE
addwf ptr_nxt,F
return
;
two_pb0:
movlw 0x0f ;MASK THE LOWER DIGIT TO RETRIVE THE
iorwf step_buf0,W ;HIGHER DIGIT TO SEE IF 'E'
sublw 0xef
btfsc STATUS,Z ;skpnz
goto sp_func
;
movlw 0x0f ;MASK THE UPPE DIGIT TO RETRIEVE THE
andwf step_buf0,W ;FIRST BIT ASSERTED DATA
call clr_pb_bit
swapf step_buf0,F ;TRANSFER THE UPPER DIGIT TO LOWER DIGIT
movlw 0x0f ;TO RETRIEVE THE SECOND BIT ASSERTED DATA
andwf step_buf0,W ;MASK TO GIVE THE ASSERTED BIT #
call clr_pb_bit
movf dcode_pb1,W ;STORE THE DECODED PB'S TO LAST PB'S
movwf last_pb1
movf dcode_pb0,W
bsf STATUS,RP0
movwf last_pb0
bcf STATUS,RP0
movlw STEP_TMR_1 ;SET STEP TIMER TO DEFAULT 1
movwf dur_step
movlw STEP_SIZE_1 ;UPDATE NEXT STEP POINTER AND W = STEP SIZE
addwf ptr_nxt,F
return
;
sp_func: ;SEE IF SPECIAL FUNCTION BUTTON
movlw 0x0f ;SET TO MASK UPPER DIGIT
andwf step_buf0,W ;RETRIEVE THE LOWER DIGIT
movwf step_buf1 ;USE THE STEP_BUF1 AS TEMPORARY STORAGE BYTE
sublw 0x03 ;SEE IF LOWER DIGIT < 4
btfss STATUS,C ;skpc ;IF LOWER DIGIT > 3, CODE IS AN IDLE PERIOD
goto idle_pb ;TREAT IF AS IDLE PERIOD IN > 3
btfsc STATUS,Z
goto repeat_8 ;bz repeat_8 ;IF W=3 -> REPEAT STEP 8 TIMES
movf step_buf1,W ;RETRIEVE THE LOWER DIGIT
sublw 0x2 ;SEE IF LOWER DIGIT = 2
btfsc STATUS,Z
goto repeat_4 ; bz repeat_4 ;IF LOWER DIGIT =2 -> REPEAT 4 TIMES
movf step_buf1,W ;RETRIEVE THE LOWER DIGIT
sublw 0x1 ;SEE IF LOWER DIGIT = 2
btfsc STATUS,Z
goto repeat_2 ;bz repeat_2 ;IF LOWER DIGIT =2 -> REPEAT 2 TIMES
goto repeat_1 ;OTHERWISE LOWER DIGIT -> REPEAT 1 TIMER
repeat_8:
movlw STEP_TMR_8 ;SET STEP TIMER TO 8
movwf dur_step
goto repeat_end
repeat_4:
movlw STEP_TMR_4 ;SET STEP TIMER TO 4
movwf dur_step
goto repeat_end
repeat_2:
movlw STEP_TMR_2 ;SET STEP TIMER TO 2
movwf dur_step
goto repeat_end
repeat_1:
movlw STEP_TMR_1 ;SET STEP TIMER TO 1
movwf dur_step
repeat_end:
bsf STATUS,RP0
movf last_pb0,W ;USE THE LAST BIT PATTERN
bcf STATUS,RP0
movwf dcode_pb0
movf last_pb1,W
movwf dcode_pb1
movlw STEP_SIZE_1 ;SET STEP SIZE TO W
addwf ptr_nxt,F ;UPDATE NEXT STEP POINTER
return
;
idle_pb:
movf dcode_pb1,W ;STORE THE DECODED PB'S TO LAST PB'S
movwf last_pb1
movf dcode_pb0,W
bsf STATUS,RP0
movwf last_pb0
bcf STATUS,RP0
movlw STEP_TMR_1 ;SET STEP DURATION TIMER
movwf dur_step
movlw STEP_SIZE_1 ;SET STEP SIZE TO 1
addwf ptr_nxt,F ;UPDATA NEXT STEP POINTER
return
;
;
;****************************************************************************
;FUNCTION: THIS ROUTINE IS TO CLEAR THE ASSERTED BIT IN THE DECODE BUFFER TO
; TO THE BUTTON PATTERN. INPUT IS LOCATION WHERE THE BIT IS TO BE
; CLEAR. ON EXIT, THE CORRESPONDING DECODE BUFFER BIT WILL BE CLEAR
;FILENAME: C:\PROJECTS\SV363\DECODE.ASM
;ROUTINE NAME: CLEAR_PB_BIT
;INPUT: W = LOCATION OF BIT TO BE CLEAR
;OUTPUT: IF W < 8, CORRESPONDING BIT LOCATION IN DCODE_PB0 WILL BE 0
; IF 7 < W, W = W - 8 AND CORRESPONDING BIT LOCATION IN DECODE_PB1
; WILL BE CLEAR.
;RAM AFFECTED: IN_BIT_LOC
;SUBROUTINE CALL: NIL
;****************************************************************************
;
;#define in_bit_loc temp_buf3 ;RAM LOCATION 5FH
;
clr_pb_bit:
movwf in_bit_loc ;STORE TO INPUT BIT LOCATION TO BUFFER
btfss STATUS,Z ; skpz
goto clr_1
bcf dcode_pb0,0
return
clr_1:
movlw b'11111101'
movwf temp_buf1
clr_1_lp:
decfsz in_bit_loc,F ;=0 -> clear bit 1
goto clr_1_next
movf temp_buf1,W
andwf dcode_pb0,F
return
clr_1_next:
bsf STATUS,C
rlf temp_buf1,F
btfsc STATUS,C
goto clr_1_lp
movlw b'11111110'
movwf temp_buf1
clr_2_lp:
decfsz in_bit_loc,F ;=0 -> clear bit 1
goto clr_2_next
movf temp_buf1,W
andwf dcode_pb1,F
return
clr_2_next:
bsf STATUS,C
rlf temp_buf1,F
btfsc STATUS,C
goto clr_2_lp
clr_15:
bcf dcode_pb1,7
return