📄 keyer-3.0.18.asm
字号:
on_and_reset_wavesidetone_ctr
bsf wavesidetone ; turn on wavesidetone line
reset_wavesidetone_counter
clrf wavesidetone_counter
goto end_of_wavesidetone ;-------------------------------------------
wavesidetone_off
bcf wavesidetone
nop ; time padding with nops
nop ; this evens things out so each run through this
nop ; soubroutine should be the same amount of time
nop ; regardless of the state or branches
nop
wavesidetone_not_equal
nop
nop
nop
nop
nop
nop
nop
end_of_wavesidetone
return
; ------------------
loop_cw_unit
; this subroutine loops for one CW unit (i.e. a dit)
; if the sidetone line has been set high it will produce a square wave sidetone signal on the wavesidetone line
; during the looping, the dit and dah paddles are checked and dit_buffer and dah_buffer set if either are pressed
; this enables dit and dah insertion for iambic operation
; initialize counters with calculated values
movfw cw_unit_counter+0
movwf counter1 ;MSB
movfw cw_unit_counter+1
movwf counter2 ;LSB
ifdef include_paddle_reverse_code
btfsc paddle_reverse ; are we in reverse paddle mode?
goto loop_cw_unit_reverse_paddle ; yes, go to subroutine for reverse paddle mode
endif
loop_de_loop_init
movlw d'3'
movwf counter3
loop_de_loop
btfss sending_dit ; skip next line if we are sending dit
goto check_for_dit ; if we are sending dit, check dah paddle
btfss dah ; check the dah paddle, if = 1, skip over next line
bsf dah_buffer ; dah is keyed, set buffer
goto skip_over_check_for_dit ; skip over check_for_dit
check_for_dit ; we're sending a dah, check the dit paddle
btfss dit ; if dit is not keyed, skip over next line
bsf dit_buffer ; set the dit buffer
nop
skip_over_check_for_dit
call produce_wavesidetone
decfsz counter3,F
goto loop_de_loop
decfsz counter2, F
goto loop_de_loop_init
decfsz counter1, F
goto loop_de_loop_init
return
ifdef include_paddle_reverse_code
loop_cw_unit_reverse_paddle
loop_de_loop_init_rev
movlw d'3'
movwf counter3
loop_de_loop_rev
btfss sending_dit ; skip next line if we are sending dit
goto check_for_dit_rev ; if we are sending dit, check dah paddle
btfss dit ; check the dit paddle, if = 1, skip over next line
bsf dah_buffer ; dah is keyed, set buffer
goto skip_over_check_for_dit_rev ; skip over check_for_dit
check_for_dit_rev ; we're sending a dah, check the dit paddle
btfss dah ; if dah is not keyed, skip over next line
bsf dit_buffer ; set the dit buffer
nop
skip_over_check_for_dit_rev
call produce_wavesidetone
decfsz counter3,F
goto loop_de_loop_rev
decfsz counter2, F
goto loop_de_loop_init_rev
decfsz counter1, F
goto loop_de_loop_init_rev
return
endif ;include_reverse_paddle_code
; ------------------
loop_6_cw_units
call loop_cw_unit
call loop_cw_unit
call loop_cw_unit
call loop_cw_unit
call loop_cw_unit
call loop_cw_unit
return
; ------------------
send_dit_or_dah
; send a dit or dah
; parms:
;
; sending_dit
; 1 = send dit
; 0 = send dah
; key_tx_active
; 1 = key tx line
; 0 = do not key tx line
;
; notes:
;
; - sidetone line is always keyed (unless sidetone_off_during_tx is true and key_tx_active is true)
ifdef include_toggle_sidetone_on_off_code
btfsc sidetone_off_during_tx
btfss key_tx_active
endif
bsf sidetone ; turn on sidetone
btfsc key_tx_active ; if key_tx is clear, jump - don't key tx line
bsf key ; key tx line
btfss sending_dit ; are we sending a dit ?
goto send_a_dah ; if not, jump to send_a_dah
call loop_cw_unit ; loop for one unit, a dit
goto clear_lines ; get out and clear all the lines
send_a_dah
ifdef include_weighting_code
movfw cw_unit_counter+1 ; store the regular counter values
movwf cw_unit_counter_dit+1
movfw cw_unit_counter+0
movwf cw_unit_counter_dit+0
movfw cw_unit_counter_dah+1 ; switch in the dah values for weighting
movwf cw_unit_counter+1
movfw cw_unit_counter_dah+0
movwf cw_unit_counter+0
endif ;include_weighting_code
call loop_cw_unit ; key for three lengths (dah)
call loop_cw_unit
call loop_cw_unit
ifdef include_weighting_code
movfw cw_unit_counter_dit+1 ; put regular counter values back
movwf cw_unit_counter+1
movfw cw_unit_counter_dit+0
movwf cw_unit_counter+0
endif ;include_weighting_code
clear_lines
bcf sidetone ; deactivate sidetone
bcf key ; deactivate key line
call loop_cw_unit ; loop while unkeyed for inter-cw_unit spacing
ifdef include_nnnnn_code ; this code blows, so I keep it turned off.
; only use if you're too cheap to buy a mode switch
; keep a history of dits and dahs
; history is stored in a word consisting of ditdah_history1 and 2
; each bit is one cw_unit : 0 = dit, 1 = dah
; m l m l
; s s s s
; b b b b
; cw_units are pushed like this --> ditdah_history1 --> ditdah_history2
btfss key_tx_active ; are we actually keying the tx ?
return ; if not, blow out and do not add to history
bsf STATUS, C ; set the carry bit, 1 = dah
btfsc sending_dit ; did we just send a dit ?
bcf STATUS, C ; if so, clear the carry bit, 0 = dit
rrf ditdah_history1, F ; place bit into history register
rrf ditdah_history2, F ; carry over into the second byte
movlw 0xff
movwf ditdah_history_timer1
endif ;include_nnnnn_code
return
; ------------------
ifdef include_freq_counter_code
store_freq_offset_in_eeprom
errorlevel -302
movlw eeprom_freq_offset_high
banksel EEADR
movwf EEADR
banksel freq_offset_binary
movfw freq_offset_binary+0
banksel EEDATA
movwf EEDATA
banksel PORTA
call write_eeprom
movlw eeprom_freq_offset_low
banksel EEADR
movwf EEADR
banksel freq_offset_binary
movfw freq_offset_binary+1
banksel EEDATA
movwf EEDATA
banksel PORTA
call write_eeprom
return
errorlevel +302
endif ;include_freq_counter_code
; ------------------
initialize_eeprom_first_time
errorlevel -302
movlw eeprom_addr_speed_wpm ; address 0x00 last wpm speed
banksel EEADR
movwf EEADR
movlw initial_speed_wpm
banksel EEDATA
movwf EEDATA
banksel PORTA
call write_eeprom
; write wavesidetone freq to eeprom
movlw eeprom_wavesidetone_setting
banksel EEADR
movwf EEADR
movlw _initial_wavesidetone_setting
banksel EEDATA
movwf EEDATA
banksel PORTA
call write_eeprom
;clean out memory locations
movlw eeprom_memory_location_0
banksel EEADR
movwf EEADR
movlw 0xff
banksel EEDATA
movwf EEDATA
banksel PORTA
call write_eeprom
movlw eeprom_memory_location_1
banksel EEADR
movwf EEADR
banksel PORTA
call write_eeprom
movlw eeprom_memory_location_2
banksel EEADR
movwf EEADR
banksel PORTA
call write_eeprom
errorlevel +302
ifdef include_freq_counter_code
errorlevel -302
movlw eeprom_freq_calib_high
banksel EEADR
movwf EEADR
movlw high _frequency_counter_calib
banksel EEDATA
movwf EEDATA
banksel PORTA
call write_eeprom
movlw eeprom_freq_calib_low
banksel EEADR
movwf EEADR
movlw low _frequency_counter_calib
banksel EEDATA
movwf EEDATA
banksel PORTA
call write_eeprom
call store_freq_offset_in_eeprom
errorlevel +302
endif ;include_freq_counter_code
; clear eeprom_settings1 location
clrf eeprom_settings1
call write_eeprom_settings1
ifndef exclude_delays_debug
ifdef include_funky_beeps_code
call beep_boop
call beep_boop
call beep_boop
endif ;include_funky_beeps_code
endif ;exclude_delays_debug
banksel PORTA
return
; ------------------
write_eeprom_settings1
errorlevel -302
movlw eeprom_settings1_location
banksel EEADR
movwf EEADR
banksel eeprom_settings1
movfw eeprom_settings1
banksel EEDATA
movwf EEDATA
banksel PORTA
call write_eeprom
errorlevel +302
banksel PORTA
return
; ------------------
initialize
ifndef exclude_delays_debug
movlw d'2' ; pause to make sure everything is settled down on power up
call pause_w_100ms
endif ;exclude_delays_debug
;bcf OPTION_REG,NOT_RBPU
errorlevel -302
ifndef processor_low_end
banksel CMCON
movlw 0x07 ; setup Port A for I/O, not comparator mode
movwf CMCON
endif ;processor_low_end
errorlevel +302
; initialize IO Ports
errorlevel -302
banksel TRISA
movlw B'00010111'
movwf TRISA
movlw B'00001101' ; 1 = input, 0 = output
movwf TRISB
errorlevel -302
banksel PORTA
bcf dit_buffer
bcf dah_buffer
bcf key
bcf sidetone
ifdef include_txwake_line_code
bcf txwake
endif
bsf key_tx_active
ifdef include_nnnnn_code
clrf ditdah_history1
clrf ditdah_history2
endif
; see if eeprom has been written to before
movlw 0x00
errorlevel -302
banksel EEADR
movwf EEADR
banksel EECON1
bsf EECON1, RD ; read address 0x00
banksel EEDATA
btfsc EEDATA,0x07 ; is bit 7 set high ?
call initialize_eeprom_first_time ; if so, we got a new chip here
banksel PORTA
errorlevel +302
; read the last wpm stored in eeprom
movlw eeprom_addr_speed_wpm
call read_eeprom
movwf speed_wpm
ifdef include_weighting_code
movwf speed_wpm_dah
endif
call calculate_cw_unit_values
; setup eeprom memory locations
movlw eeprom_memory_location_0
movwf eeprom_memory_locations+0
movlw eeprom_memory_location_1
movwf eeprom_memory_locations+1
movlw eeprom_memory_location_2
movwf eeprom_memory_locations+2
movlw eeprom_memory_loc_0_cw_units
movwf eeprom_memory_loc_limits+0
movlw eeprom_memory_loc_1_cw_units
movwf eeprom_memory_loc_limits+1
movlw eeprom_memory_loc_2_cw_units
movwf eeprom_memory_loc_limits+2
;read eeprom_settings1 from eeprom
movlw eeprom_settings1_location
call read_eeprom
movwf eeprom_settings1
movlw eeprom_wavesidetone_setting
call read_eeprom
movwf wavesidetone_counter_setting
clrf wavesidetone_counter
ifdef include_interrupt_code
; set up interrupt stuff
errorlevel -302
banksel OPTION_REG
bcf OPTION_REG, T0CS ; TIMER0 clock source set to internal clock (clock / 4)
bcf OPTION_REG, PSA ; assign prescaler to TIMER0 clock
bsf OPTION_REG, PS0 ; set TIMER0 prescaler to 111 ( / 256 )
bsf OPTION_REG, PS1
bsf OPTION_REG, PS2
banksel TMR0
movlw d'150'
movwf TMR0
banksel INTCON
bsf INTCON, T0IE ; enable TIMER0 overflow interrupt
bsf INTCON, GIE ; enable interrupts
errorlevel -302
banksel PORTA
endif
ifdef include_cw_rx_practice_code
movlw 0x30 ; seed random number generator
movwf randomnum+0
movlw 0x45
movwf randomnum+1
endif
ifdef include_freq_counter_code
movlw eeprom_freq_calib_high
call read_eeprom
movwf frequency_counter_calib+0
movlw eeprom_freq_calib_low
call read_eeprom
movwf frequency_counter_calib+1
; read freq_offset from EEPROM
movlw eeprom_freq_offset_high
call read_eeprom
movwf freq_offset_binary+0
movlw eeprom_freq_offset_low
call read_eeprom
movwf freq_offset_binary+1
endif ;include_freq_counter_code
ifdef include_serial_port_rx_code
errorlevel -302
banksel TRISB
bsf TRISB,0x01 ; make RB1 an input
banksel TXSTA
; bsf TXSTA,BRGH ; high speed bit generator
bcf TXSTA,BRGH ; low speed bit generator
movlw d'25' ; 9600 baud with 4Mhz clock / 2400 with low speed bit generator
banksel SPBRG
movwf SPBRG
banksel TXSTA
bcf TXSTA,SYNC ; asyncronous mode
;bcf STATUS,RP0 ; select bank 0
banksel RCSTA
bsf RCSTA,SPEN
bsf RCSTA,CREN ; enable serial receive
read_rx_fifo_loop
call pause_100_ms
banksel PIR1
btfss PIR1,RCIF ; do we have something in the buffer?
goto read_rx_fifo_loop_exit ; no, blow out of here
banksel RCREG
movfw RCREG ; pull byte out of the serial rx FIFO
goto read_rx_fifo_loop
read_rx_fifo_loop_exit
errorlevel +302
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -