📄 keyer-3.0.18.asm
字号:
movlw 0x02 ; exiting dit
call pause_w_100ms
bsf sending_dit
call send_dit_or_dah
bcf dit_buffer ; clean out buffers in case they got set in loop_cw_unit
bcf dah_buffer
return
tune_dit_pressed
bcf tune_latch_mode ; get out of latch mode
ifdef include_txwake_line_code
bsf txwake
endif
bsf key ; key tx
ifdef include_toggle_sidetone_on_off_code
btfss sidetone_off_during_tx
endif ;include_toggle_sidetone_on_off_code
bsf sidetone ; key sidetone
call loop_cw_unit ;
goto tune_mode_check_for_exit
tune_dah_pressed
bsf tune_latch_mode ; go into latch mode
btfss key
goto tune_key
bcf key
bcf sidetone
call pause_100_ms
ifdef include_txwake_line_code
bcf txwake
endif
goto tune_dah_pressed_loop
tune_key
ifdef include_txwake_line_code
bsf txwake
endif
bsf key
ifdef include_toggle_sidetone_on_off_code
btfss sidetone_off_during_tx
endif ;include_toggle_sidetone_on_off_code
bsf sidetone
call loop_cw_unit ;
tune_dah_pressed_loop ; wait for dah to be released
call loop_cw_unit
btfss dit ; if dit is pressed,
goto tune_mode_check_for_exit ; blow out of the loop because both dit and dah are squeezed
btfss dah ; if dah is not pressed, skip over
goto tune_dah_pressed_loop
goto tune_mode_check_for_exit
endif ;include_tune_mode_code
; ------------------
ifdef include_calibration_code
calibration_check_mode
; this mode allows you to check the cw unit timing calibration
; hold down the dit paddle for a minute or half minute
; after releasing the paddle, the number of dits will be announced in CW
; use the formula below to determine the proper number of dits for the wpm setting
; speed in wpm = dits per min / 25
; 20 WPM equals 500 dits per minute or 250 dits per 20 seconds
clrf binary2bcd_binary_in+0
clrf binary2bcd_binary_in+1
bsf sending_dit
calibration_check_mode_wait_loop
btfsc dit ; loop while waiting for dit to be pressed
goto calibration_check_mode_wait_loop
calibration_dit_loop
call send_dit_or_dah ; send a dit
incf binary2bcd_binary_in+1, F ; increment the dit counter
btfsc STATUS, Z ; did the lower byte roll over ?
incf binary2bcd_binary_in+0, F ; if so, increment the upper byte
btfss dit ; if dit is still pressed
goto calibration_dit_loop ; continue to loop
movlw 0x05
call pause_w_100ms
call binary2bcd
; break out lower nibble of middle BCD digit
movfw BCD1
andlw b'00001111'
movwf bcd_low_nibble
addwf bcd_low_nibble, F ; double it so we're in the right spot in cw_table
movfw bcd_low_nibble ; send the low nibble BCD digit in CW
call cw_table
movwf cw_char_to_send+0
movfw bcd_low_nibble
addlw 0x01
call cw_table
movwf cw_char_to_send+1
errorlevel -306
pagesel send_cw
call send_cw
errorlevel +306
; send least signficant BCD digit
call send_BCD2_in_cw
return
endif
; ------------------
program_memory
; parms
; memory_number (0 = callsign memory)
;
; calls
; send_dit_or_dah
; check_paddles
; pause_w_100ms
; divide16bit
; send a dit or boop_beep to signify start
movlw 0x02
call pause_w_100ms
ifdef include_funky_beeps_code
call boop_beep
else
bsf sending_dit
call send_dit_or_dah
endif
; initialize counters
clrf cw_unit_count
bcf temp_memory_dirty
movlw b'11000000'
movwf temp_memory_mask
clrf temp_memory
; get parameters for this memory
movlw eeprom_memory_locations ; get the *address* of memory location array
movwf FSR
movfw memory_number ; add for the appropriate memory location
addwf FSR, F
movfw INDF
movwf temp_memory_eeprom_pointer ; initialize the live eeprom pointer
movwf start_of_memory_location ; initialize the static starting location
incf temp_memory_eeprom_pointer, F ; actual recording starts at +1
initial_recording_loop
; check if mode button was hit
pagesel we_are_done_with_programming
errorlevel -306
btfss mode_switch
goto we_are_done_with_programming
errorlevel +306
pagesel check_paddles
errorlevel -306
call check_paddles
errorlevel +306
btfsc dit_buffer
goto add_dit_or_dah_to_memory
btfsc dah_buffer
goto add_dit_or_dah_to_memory
goto initial_recording_loop
init_recording_loop_counters
movlw 0x00
movwf recording_loop_counter1
movwf recording_loop_counter2
recording_loop
ifdef include_function_button_code
btfss switch0
goto we_are_done_with_programming
btfss switch1
goto we_are_done_with_programming
btfss switch2
goto we_are_done_with_programming
endif
pagesel we_are_done_with_programming
errorlevel -306
btfss mode_switch
goto we_are_done_with_programming
errorlevel +306
pagesel check_paddles
errorlevel -306
call check_paddles
errorlevel +306
btfsc dit_buffer
goto store_cw_unit_in_temp_memory
btfsc dah_buffer
goto store_cw_unit_in_temp_memory
; nothing is active right now, increment the inactive counters
incfsz recording_loop_counter1, F
goto recording_loop
movfw recording_loop_counter2
sublw 0xFF
btfss STATUS, Z
incf recording_loop_counter2, F
goto recording_loop
we_are_done_with_programming
; store the last byte if temp_memory is dirty
btfsc temp_memory_dirty
call store_temp_memory_to_eeprom
movfw cw_unit_count ;see if cw_unit_count is zero
btfsc STATUS,Z
decf cw_unit_count,F ;if so, store FF in cw_unit_count to signify blank memory
; store the cw_unit_count in the first byte
movfw start_of_memory_location
errorlevel -302
banksel EEADR
movwf EEADR
errorlevel +302
banksel PORTA
movfw cw_unit_count
errorlevel -302
banksel EEDATA
movwf EEDATA
errorlevel +302
banksel PORTA
call write_eeprom
movlw 0x03
call pause_w_100ms
ifdef include_funky_beeps_code
call beep_boop
else
bsf sending_dit
call send_dit_or_dah
endif
return ; we are totally done
;------------- sub-subroutines
store_cw_unit_in_temp_memory
; store the silent timee before the cw_unit
; first, calculate the ratio between the silent and the cw unit time
movfw cw_unit_counter+1
movwf divisor+1
movfw cw_unit_counter+0
movwf divisor+0
movfw recording_loop_counter1 ; recording_loop_counter / cw_unit_counter = space ratio
movwf dividend+1 ; this is used below to determine if we have an intercharacter space
movfw recording_loop_counter2 ; or an interword space
movwf dividend+0
call divide16bit
movfw quotient+0 ; check if quotient MSB is zero
btfsc STATUS, Z
goto measure_up_silent_time ; if so, skip over this stuff
movlw 0xff ; if not, set LSB to FF
movwf quotient
measure_up_silent_time
movfw quotient+1 ; see how many cw_unit lengths we had silent before this cw_unit
sublw d'1' ; is this an intercharacter space ? was 10
btfsc STATUS, C
goto add_dit_or_dah_to_memory ; no, it's negative, don't add a space cw_unit
movfw quotient+1 ; is this an interword space ?
sublw d'14' ; was 70
btfsc STATUS, C
goto skip_over_1 ; result is negative, we have less than 6 cw_units
movlw b'00000000' ; 00 = 6 cw_unit space
goto skip_over_2
skip_over_1
movlw b'10101010' ; 10 = 2 cw_unit space
skip_over_2
call store_w_in_temp_memory
add_dit_or_dah_to_memory
btfss dit_buffer
goto skip_over_dit
bsf sending_dit
call send_dit_or_dah
movlw b'01010101' ; 01 = dit
bcf dit_buffer ; clean out dit buffer
goto skip_over_dah
skip_over_dit
bcf sending_dit
call send_dit_or_dah
movlw b'11111111' ; 11 = dah
bcf dah_buffer ; clean out dah buffer
skip_over_dah
call store_w_in_temp_memory
; enforce cw unit limit count so we don't run over into another memory
; get cw_unit count limit
movlw eeprom_memory_loc_limits+0
movwf FSR
movfw memory_number ; add for the appropriate memory location
addwf FSR, F
movfw INDF
subwf cw_unit_count, W ; does cw_unit_count = cw_unit count limit ?
btfss STATUS, Z
goto init_recording_loop_counters ; no, go back for more
bsf sidetone ; yes, lock up the sidetone
wait_for_user_to_realize
ifdef include_funky_beeps_code
call low_beep
endif
call pause_100_ms
btfss dit
goto wait_for_user_to_realize
btfss dah
goto wait_for_user_to_realize
bcf sidetone
bcf dit_buffer
bcf dah_buffer
goto we_are_done_with_programming
;cleanup
store_w_in_temp_memory
andwf temp_memory_mask, W ; apply the mask to W
addwf temp_memory, F ; add the cw_unit to temp_memory
;increment cw_unit count
incf cw_unit_count, F
;setup_for_next_store_w
bsf temp_memory_dirty
rrf temp_memory_mask, F ; move the bit mask over
rrf temp_memory_mask, F
btfsc STATUS, C ; if we carried, we need to start a new byte
call store_temp_memory_to_eeprom
return
store_temp_memory_to_eeprom
movwf temp_w ; preserve w
; write the temp memory byte to eeprom
movfw temp_memory_eeprom_pointer
errorlevel -302
banksel EEADR
movwf EEADR
errorlevel +302
banksel PORTA
movfw temp_memory
errorlevel -302
banksel EEDATA
movwf EEDATA
errorlevel +302
banksel PORTA
errorlevel -306
pagesel check_paddles
call check_paddles
errorlevel +306
call write_eeprom
errorlevel -306
pagesel check_paddles
call check_paddles
errorlevel +306
;get things ready for new byte
movlw b'11000000'
movwf temp_memory_mask
clrf temp_memory
; point to the next eeprom byte to be written
incf temp_memory_eeprom_pointer, F
; TODO - check if we're at the limit for this memory
movfw temp_w ; restore w
bcf temp_memory_dirty
return
; endif
; ------------------
read_eeprom
; read eeprom address in w
; return data in w
errorlevel -302
banksel EEADR
movwf EEADR
banksel EECON1
bsf EECON1, RD
banksel EEDATA
movfw EEDATA
errorlevel +302
banksel PORTA
return
; ------------------
check_for_button_hit
btfss dit
retlw 1
btfss dah
retlw 1
btfss mode_switch
retlw 1
ifdef include_function_button_code
btfss switch0
retlw 1
btfss switch1
retlw 1
btfss switch2
retlw 1
endif
retlw 0
; ------------------
loop_check_for_button_hit
call check_for_button_hit
sublw 0x01
btfsc STATUS,Z
goto loop_check_for_button_hit
call pause_100_ms
return
; ------------------
play_memory
ifdef include_function_button_code
bcf memory_playback_manual_exit ; clear flag to tell calling subroutines if user manaully exited
endif
; get parameters for this memory
movlw eeprom_memory_locations ; get the *address* of memory location array
movwf FSR
movfw memory_number ; add for the appropriate memory location
addwf FSR, F
movfw INDF
movwf temp_memory_eeprom_pointer ; initialize the live eeprom pointer
; read the cw_unit count for this memory
call read_eeprom
movwf cw_unit_count
; check for blank memory
movlw 0xFF
subwf cw_unit_count, W ; is the cw_unit count 0xFF ?
btfss STATUS, Z
goto byte_loop ; no, skip over this
ifdef include_funky_beeps_code
call low_beep
else
bsf sending_dit ; yes, send three dits and blow out
bcf key_tx_active
call send_dit_or_dah
call send_dit_or_dah
call send_dit_or_dah
bsf key_tx_active
endif ;include_funky_beeps_code
return
byte_loop
; get a byte from eeprom
incf temp_memory_eeprom_pointer, F ; move to the next byte
movfw temp_memory_eeprom_pointer
call read_eeprom
movwf temp_memory
movlw 0x04 ; four cw_units in a byte
movwf temp_memory_mask ; use temp_memory_mask as a cw_unit within a byte counter
cw_unit_loop
; TODO - exit if a switch or paddle is hit
rlf temp_memory, F
btfsc STATUS, C
goto first_bit_1
;first_bit_0
rlf temp_memory, F
btfsc STATUS, C
goto cw_unit_01
;cw_unit_00 - 6 cw_unit space
call loop_cw_unit
call loop_cw_unit
call loop_cw_unit
call loop_cw_unit
call loop_cw_unit
call loop_cw_unit
goto next_cw_unit_setup
first_bit_1
rlf temp_memory, F
btfsc STATUS,C
goto cw_unit_11
;cw_unit_10 - 2 cw_unit space
call loop_cw_unit
call loop_cw_unit
goto next_cw_unit_setup
cw_unit_11 ; dah
bcf sending_dit
call send_dit_or_dah
goto next_cw_unit_setup
cw_unit_01
bsf sending_dit
call send_dit_or_dah
next_cw_unit_setup
decf cw_unit_count, F
btfsc STATUS, Z ; did we do the last cw_unit ?
return ; yes, blow out
call check_for_button_hit
sublw 0x01
btfsc STATUS,Z
goto button_hit_loop
decf temp_memo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -