📄 keyer-3.0.18.asm
字号:
retlw b'01010100' ;S 27
retlw b'00000000'
retlw b'11000000' ;T 28
retlw b'00000000'
retlw b'01011100' ;U 29
retlw b'00000000'
retlw b'01010111' ;V 30
retlw b'00000000'
retlw b'01111100' ;W 31
retlw b'00000000'
retlw b'11010111' ;X 32
retlw b'00000000'
retlw b'11011111' ;Y 33
retlw b'00000000'
retlw b'11110101' ;Z 34
retlw b'00000000'
endif ;include_cw_table_long
; Subroutines -------------------------------------------------------------
check_paddles
banksel PORTA
pagesel $
ifdef include_paddle_reverse_code
btfsc paddle_reverse
goto check_paddles_reverse
endif ;include_paddle_reverse_code
btfss dit ; if dit is not keyed, skip next
bsf dit_buffer ; set dit_buffer
btfss dah ; if dah is not keyed, skip next
bsf dah_buffer ; set dah_buffer
goto squeeze_check
ifdef include_paddle_reverse_code
check_paddles_reverse
btfss dit ; if dit is not keyed, skip next
bsf dah_buffer ; set dah_buffer
btfss dah ; if dah is not keyed, skip next
bsf dit_buffer ; set dit_buffer
endif ;include_paddle_reverse_code
squeeze_check
ifdef include_iambic_mode_code
btfsc iambic_b_mode ; don't do squeeze check if we're in iambic b mode
return
endif ;include_iambic_mode_code
btfsc dit ; if both dit and dah are squeezed, set the squeeze_detected flag
return
btfsc dah
return
bsf squeeze_detected
return
; ------------------
send_w_BCD_in_cw
; this sends the lower nibble of w (BCD binary coded decimal) in CW
movwf temp_memory
addwf temp_memory, F ; double it so we're in the right spot in cw_table
movfw temp_memory ; put it in W for lookup table
call cw_table
movwf cw_char_to_send+0
movfw temp_memory
addlw 0x01 ; add 1 to get next byte in table
call cw_table
movwf cw_char_to_send+1
errorlevel -306
pagesel send_cw
call send_cw
errorlevel +306
return
; ------------------
ifdef include_funky_beeps_code
beep
movwf temp_w ; store w temporarily
movfw wavesidetone_counter_setting ; store real wavesidetone setting in temp_memory
movwf temp_memory
movfw temp_w ; get temp_w and put in for wavesidetone setting
movwf wavesidetone_counter_setting
movlw _beep_length
movwf counter1
movwf counter2
bsf sidetone
beep_loop
call produce_wavesidetone
decfsz counter1, F
goto beep_loop
decfsz counter2, F
goto beep_loop
bcf sidetone
movfw temp_memory ; restore real wavesidetone setting
movwf wavesidetone_counter_setting
return
; ------------------
high_beep
ifndef exclude_delays_debug
movlw _high_beep_tone
call beep
endif ;exclude_delays_debug
return
; ------------------
low_beep
ifndef exclude_delays_debug
movlw _low_beep_tone
call beep
endif ;exclude_delays_debug
return
; ------------------
beep_boop
ifndef exclude_delays_debug
call high_beep
call low_beep
endif ;exclude_delays_debug
return
; ------------------
boop_beep
call low_beep
call high_beep
return
endif ;include_funky_beeps_code
; ------------------
divide16bit
; dividend / divisor = quotient
; this code from Mark Sullivan www.markworld.com (thanks for saving me hours of work ! :-)
banksel PORTA
pagesel $
movlw d'16'
movwf count
clrf quotient+0 ;quotient
clrf quotient+1
clrf remainder+0 ;remainder
clrf remainder+1
udiv1
bcf STATUS,C
rlf dividend+1,F
rlf dividend+0,F
rlf remainder+1,F
rlf remainder+0,F
movf divisor+0,W
subwf remainder+0,W
btfss STATUS,Z
goto udiv2
movf divisor+1,W
subwf remainder+1,W
btfss STATUS,C
goto udiv4
movwf remainder+1
movf divisor+0,W
subwf remainder+0,F
goto udiv3
udiv2
btfss STATUS,C
goto udiv4
movf divisor+1,W
subwf remainder+1,F
btfss STATUS,C
decf remainder+0,F
movf divisor+0,W
subwf remainder+0,F
udiv3
bsf STATUS,C
udiv4
rlf quotient+1,F
rlf quotient+0,F
decfsz count,F
goto udiv1
retlw 0
; ------------------
ifdef include_freq_counter_code
bcd2binary
; BCD to 16 bit binary converter
; adapted from Microchip AN526
; http://www.microchip.com
; thanks, Microchip !
;input parameters:
;bcd2binary+0 : MSB
;bcd2binary+1 : LSB
;output:
;BCD0 = most significant digits
;BCD1
;BCD2 = least significant digits
;each BCD register contains and upper and lower nibble BCD digit
banksel PORTA
pagesel $
clrf bcd2binary_binary_out+0
movf BCD0,W
andlw 0x0F
movwf bcd2binary_binary_out+1
call mpy10a ; result = 10a+b
swapf BCD1,W
call mpy10b ; result = 10[10a+b]
movf BCD1,W
call mpy10b ; result = 10[10[10a+b]+c]
swapf BCD2,W
call mpy10b ; result = 10[10[10[10a+b]+c]+d]
movf BCD2,W
andlw 0x0F
addwf bcd2binary_binary_out+1, F
btfsc STATUS,C
incf bcd2binary_binary_out+0, F ; result = 10[10[10[10a+b]+c]+d]+e
return ; BCD to binary conversion done
; subroutines
mpy10b
andlw 0x0F
addwf bcd2binary_binary_out+1, F
btfsc STATUS,C
incf bcd2binary_binary_out+0, F
mpy10a
bcf STATUS,C ; multiply by 2
rlf bcd2binary_binary_out+1,W
movwf L_temp
rlf bcd2binary_binary_out+0,W ; (H_temp,L_temp) = 2*N
movwf H_temp
bcf STATUS,C ; multiply by 2
rlf bcd2binary_binary_out+1, F
rlf bcd2binary_binary_out+0, F
bcf STATUS,C ; multiply by 2
rlf bcd2binary_binary_out+1, F
rlf bcd2binary_binary_out+0, F
bcf STATUS,C ; multiply by 2
rlf bcd2binary_binary_out+1, F
rlf bcd2binary_binary_out+0, F ; (bcd2binary_binary_out+0,bcd2binary_binary_out+1) = 8*N
movf L_temp,W
addwf bcd2binary_binary_out+1, F
btfsc STATUS,C
incf bcd2binary_binary_out+0, F
movf H_temp,W
addwf bcd2binary_binary_out+0, F
return ; (bcd2binary_binary_out+0,bcd2binary_binary_out+1) = 10*N
endif ;include_freq_counter_code
; ------------------
binary2bcd
; 16 bit binary to bcd converter
; adapted from Microchip AN526
; http://www.microchip.com
; thanks, Microchip !
banksel PORTA
pagesel $
bcf STATUS, C ; clear the carry bit
movlw .16
movwf count
clrf BCD0 ; most significant digit
clrf BCD1
clrf BCD2 ; least significant digit
loop16
rlf binary2bcd_binary_in+1, F ; LSB
rlf binary2bcd_binary_in+0, F ; MSB
rlf BCD2, F
rlf BCD1, F
rlf BCD0, F
decfsz count, F
goto adjDEC
retlw 0
adjDEC
movlw BCD2
movwf FSR
call adjBCD
movlw BCD1
movwf FSR
call adjBCD
movlw BCD0
movwf FSR
call adjBCD
goto loop16
adjBCD
movlw 3
addwf INDF, W
movwf temp
btfsc temp,3 ; test if result > 7
movwf INDF
movlw 30
addwf INDF, W
movwf temp
btfsc temp,7 ; test if result > 7
movwf INDF ; save as MSD
retlw 0
; ------------------
write_eeprom
pagesel $
; save EEDATA and EEADR for write verify
errorlevel -302
banksel EEDATA
movfw EEDATA
banksel PORTA
movwf write_verify_data
banksel EEADR
movfw EEADR
banksel PORTA
movwf write_verify_addr
errorlevel +302
start_write
errorlevel -302
banksel INTCON
bcf INTCON, GIE ; disable interrupts
banksel EECON1
bsf EECON1, WREN ; enable write
movlw 0x55 ; required write sequence
movwf EECON2 ; required write sequence
movlw 0xaa ; required write sequence
movwf EECON2 ; required write sequence
bsf EECON1,WR ; write
wait_to_complete_write
btfsc EECON1, WR ; watch for WR flag to clear
goto wait_to_complete_write
; check if write failed, loop a couple times to try again
banksel write_verify_addr
movfw write_verify_addr ; select the address
banksel EEADR
movwf EEADR
banksel EECON1
bsf EECON1, RD ; read it
banksel EEDATA
movfw EEDATA ; get the data
banksel PORTA
subwf write_verify_data, W ; compare it
btfss STATUS, Z ; skip next if its equal
goto write_again ; otherwise, write it again
write_eeprom_blowout
banksel INTCON
bsf INTCON, GIE ; enable interrupts
banksel EECON1
bcf EECON1, WREN ; clear write enable flag
bcf EECON1, EEIF ; clear EE Interrupt flag for the hell of it
banksel PORTA
return
write_again
banksel write_verify_data
movfw write_verify_data ; reload EEDATA and EEADR with the original values
banksel EEDATA
movwf EEDATA
banksel write_verify_addr
movfw write_verify_addr
banksel EEADR
movwf EEADR
banksel PORTA
goto start_write
errorlevel -302
; ------------------
calculate_cw_unit_values
banksel PORTA
pagesel $
movlw LOW _cw_unit_wpm_factor
movwf dividend+1
movlw HIGH _cw_unit_wpm_factor
movwf dividend+0
movfw speed_wpm
movwf divisor+1 ; lsb - divisor
movlw 0x00
movwf divisor+0 ; msb - divisor
call divide16bit
movf quotient+1, W ;load LSB of result
movwf cw_unit_counter+1
movf quotient+0, W ;load MSB of result
movwf cw_unit_counter+0
ifdef include_weighting_code
movlw LOW _cw_unit_wpm_factor
movwf dividend+1
movlw HIGH _cw_unit_wpm_factor
movwf dividend+0
movfw speed_wpm_dah
movwf divisor+1 ; lsb - divisor
movlw 0x00
movwf divisor+0 ; msb - divisor
call divide16bit
movf quotient+1, W ;load LSB of result
movwf cw_unit_counter_dah+1
movf quotient+0, W ;load MSB of result
movwf cw_unit_counter_dah+0
endif ;include_weighting_code
return
; ------------------
ifdef include_mode_button_hold_code
banksel PORTA
pagesel $
wait_for_mode_switch_release
btfss mode_switch
goto wait_for_mode_switch_release
call pause_100_ms
call pause_100_ms
bcf key_tx_active
return
endif
; ------------------
pause_100_ms
banksel PORTA ; for good measure
movlw _100ms_counter1_calibration
movwf counter1
movlw _100ms_counter2_calibration
movwf counter2
movlw _100ms_counter3_calibration
movwf counter3
looplooploop
ifndef exclude_delays_debug
decfsz counter1, F
goto looplooploop
decfsz counter2, F
goto looplooploop
decfsz counter3, F
goto looplooploop
endif ;exclude_delays_debug
return
; ------------------
pause_w_100ms
; pause W * 100 milliseconds
banksel PORTA ; for good measure
movwf count
ifndef exclude_delays_debug
loop_decrement
call pause_100_ms
decfsz count, F
goto loop_decrement
endif ;exclude_delays_debug
return
; ------------------
produce_wavesidetone
btfss sidetone ; is sidetone on right now ?
goto wavesidetone_off ; no, go turn the wavesidetone line off
incf wavesidetone_counter, F
movfw wavesidetone_counter_setting
subwf wavesidetone_counter, W
btfss STATUS, Z
goto wavesidetone_not_equal
btfss wavesidetone ; see what state we are in and toggle it
goto on_and_reset_wavesidetone_ctr ; wavesidetone is off right now, jump up and set it
nop
bcf wavesidetone ; wavesidetone is on right now, turn it off
goto reset_wavesidetone_counter ; jump ahead and reset counter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -