;---------------------------------------- ; atsprint 3 dds ;---------------------------------------- ; ; Radio hardware design and initial software design by Steven Weber KD1JV ; Changes and modifications to software by Michael Harnage W1MT ; ; Copyright (c) 2005,2006 Steven Weber KD1JV and Michael Harnage W1MT ; ; Permission is hereby granted, free of charge, to any person obtaining ; a copy of this software and associated documentation files (the ; "Software"), to deal in the Software without restriction, including ; without limitation the rights to use, copy, modify, merge, publish, ; distribute, sublicense, and/or sell copies of the Software, and to ; permit persons to whom the Software is furnished to do so, subject to ; the following conditions: ; ; The above copyright notice and this permission notice shall be included ; in all copies or substantial portions of the Software. ; ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ; ; ;---------------------------------------- #include "msp430x11x1.h" ; ; This is where you set up what kind of radio you are flashing ; This code supports the ATS2, the ATS3 and the ATS3A ; ; To choose the ATS2, make sure that the following 3 define's are ; commented out. ; ; To choose the ATS3, uncomment the ATS3 and WIDE define's (leave ; OSC_50 commented out). ; ; To choose the ATS3A uncomment the ATS3 and the OSC_50 define's (leave ; WIDE commented out). ; #define ATS3 1 ;#define OSC_50 1 #define WIDE 1 ; ; Change the SIDETONE_DELAY will affect the sidetone ; ; 27 -> 606Hz default ; 28 -> 585Hz Steve's original choice ; 33 -> 496Hz close enuf to 500Hz ; 37 -> 442Hz for the musician's ; 41 -> 400Hz lowest we dare go ; ; DONT ALTER THIS YET -- OTHER PLACES IN CODE WILL HAVE TO CHANGE TOO #define SIDETONE_DELAY 27 ; Other misc defines #define STEALTH 1 #define MULTI_MUTE 1 #define SCAN 1 #define MILLISEC_DELAY 32 ; ; The following are options that may or may not work ; They are left for others who may want their functionality ; ;#define ANYBUTTON ;#define PAUSE ORG 00200h flags: DW 00000h ; general flags bits fbin: DW 00000h ; Tx DDS phase word, low DW 00000h ; Tx DDS phase word, high fbin_other: DW 00000h ; other phase words, for split mode / 2 words DW 00000h fbcd: DW 00000h ; BCD freq lsw DW 00000h ; BCD freq msw 7.040.000 would be "0704 0000" fbcd_other: DW 00000h DW 00000h ; the other vfo, double word fbc: DW 00000h ; Tx freq in binary, low byte, output of bcd2bin routine DW 00000h ; Tx freq in binary, high byte, output of bcd2bin routine bandstep_up: DW 00050h ; and step can be 10,50, [or 1000000] Hz / 2 words DW 00000h ; initialized to 50Hz bandstep_dn: DW 09949h ; band step can be 10,50, [or 1000000] Hz / 2 words DW 09999h ; initialized to -50Hz #ifdef SCAN scan_a: DW 00000h ; start of scanning, lsb DW 00000h ; scan_b: DW 00000h ; end of scanning, lsb DW 00000h ; #endif ; ; The following need to stay in the same order :) ; Especially important that fref be first. ; fref: DW 00000h ; DDS reference freq in binary DW 00000h ; DDS reference freq in binary ofst: DW 00000h ; IF offset freq, DDS phase word, low DW 00000h ; IF offset freq, DDS phase word, high bflag: DW 00000h ; second flag bit register command_speed: DW 00000h ; command output speed word keyer_speed: DW 00000h ; keyer speed word ENDOFVARRAM: DW 0ffffh ORG 00240h rammem: DW 00000h ; keyer memory start ORG 002bch ramend: DW 0ffffh ; keyer memory stop, will allow 124 chars (it's inclusive) DW 0ffffh ; Don't want to get too close to 0300h as that is where ; the stack starts. Since one block of flash it 128 and I want ; keep the last two bytes 0ffffh this works out nicely. ; P1.0 J1-2 P2.0 Dah ; P1.1 Menu P2.1 Dit ; P1.2 Tune Down P2.2 Tune Up ; P1.3 Transmit P2.3 RIT ; P1.4 SDATA dds P2.4 J1-3 ; P1.5 SCLK dds P2.5 Sidetone ; P1.6 FSYNC dds ; P1.7 Mute #ifdef ATS3 #define PI_DAH 01h,&P2IN #define PI_DIT 02h,&P2IN #define PI_TUNEUP 04h,&P2IN #define PI_SPLIT 08h,&P2IN #define PI_J13 010h,&P2IN #define PO_SIDETONE 020h,&P2OUT #define PI_J12 01h,&P1IN #define PI_MENU 02h,&P1IN #define PI_TUNEDN 04h,&P1IN #define PO_TRANSMIT 08h,&P1OUT #define PO_SDATA 010h,&P1OUT #define PO_SCLK 020h,&P1OUT #define PO_FSYNC 040h,&P1OUT #define PO_MUTE 080h,&P1OUT #else ; ; then ats2 ; #define PI_DIT 01h,&P2IN #define PI_SPLIT 02h,&P2IN #define PI_DAH 04h,&P2IN #define PI_TUNEUP 08h,&P2IN #define PI_TUNEDN 010h,&P2IN #define PO_SIDETONE 020h,&P2OUT #define PI_MENU 01h,&P1IN #define PI_J11 02h,&P1IN #define PI_J12 04h,&P1IN #define PO_TRANSMIT 08h,&P1OUT #define PO_SDATA 010h,&P1OUT #define PO_SCLK 020h,&P1OUT #define PO_FSYNC 040h,&P1OUT #define PO_MUTE 080h,&P1OUT #endif ; ; Setup the flags symbols ; #define F_SIDETONE 00001h #define F_DAH 00002h #define F_DIT 00004h #define F_SCANMODE 00008h #define F_STRAIGHTKEY 00010h #define F_VFO 00020h #define F_SPLIT 00040h #define F_WIDEMODE 00080h ;00100h TRY NOT TO USE HIGH BITS AS THEY DO NOT TAKE ADVANTAGE OF THE NUMBER GENERATOR (R3) ;00200h ;00400h ;00800h ;01000h ;02000h ;04000h ;08000h ;BF_AFA when set will keep mute on till cleared, useful for afa'ing several chars ; or when you don't want to listen to rf, but quite possibly not needed with a little ; code changing :) #ifdef MULTI_MUTE #define BF_AFA 00001h #endif #define BF_ENTERFREQ 00002h #define BF_MEMSTORE 00004h #define BF_DITDAH 00008h #define BF_MEMPLAY 00010h #define BF_BEACON 00020h #define BF_IMODE 00040h #define BF_80M 00080h #define BF_20M 00100h #define BF_MHZ 00200h ;00400h OOOPS, HAVE USED Three BITS ;00800h TRY NOT TO USE HIGH BITS AS THEY DO NOT TAKE ADVANTAGE OF THE NUMBER GENERATOR (R3) #ifdef STEALTH #define BF_STEALTH 01000h #endif ;02000h ;04000h ;08000h ; ; Set up interrupt vectors ; ORG 0FFFEh DW reset ; 0xFFF0 Timer A CC1-2, TA ORG 0fff0h DW timer ; 0xFFF2 Timer A CC0 ORG 0fff2h DW millisecond_isr ;---------------------------------------- ; ; ; The clock ticks 32768 times a second. ; ;---------------------------------------- ORG 0F000h millisecond_isr: ; Start of handler Interrupt for TACCR0 CCIFG add #MILLISEC_DELAY,&TACCR0 inc r6 reti timer: add &TAIV,PC ; add offset to Jump table reti ; Vector 0: no interrupt jmp ccifg_1_hnd ; Vector 2: TACCR1 jmp ccifg_2_hnd ; Vector 4: TACCR2 reti ; Vector 6: reserved reti ; Vector 8: reserved taifg: reti ; Vector 10: TAIFG ;---------------------------------------- ; sidetone timer isr ;---------------------------------------- ccifg_1_hnd: add #SIDETONE_DELAY,&TACCR1 ; SIDETONE_DELAY clock cycles for timer bit #F_SIDETONE,&flags ; sidetone jnc nost xor.b #PO_SIDETONE ; sidetone reti nost: #ifdef WIDE bit #F_WIDEMODE,&flags ; wide mode jc dcon #endif bic.b #PO_SIDETONE ; sidetone reti #ifdef WIDE dcon: bis.b #PO_SIDETONE ; sidetone reti #endif ;---------------------------------------- ; keyer timer isr ;---------------------------------------- ccifg_2_hnd: add @r4,&TACCR2 inc r5 reti ;---------------------------------------- ; main entry point - configure mpu ;---------------------------------------- reset: mov #0300h,SP ; initialize stack pointer mov #WDTPW+WDTHOLD,&WDTCTL ; stop watchdog timer #ifdef ATS3 mov.b #0f8h,&P1DIR mov.b #PO_FSYNC ; set PO_FSYNC mov.b #020h,&P2DIR bic.b #PO_SIDETONE ; clr PO_SIDETONE #else mov.b #0f8h,&P1DIR bic.b #078h,&P1OUT ; PO_SDATA+PO_SCLK+PO_FSYNC+PO_TRANSMIT mov.b #020h,&P2DIR #endif bis.b #DCO0+DCO1+DCO2,&DCOCTL ; DCO0+DCO1+DCO2 bis.b #RSEL0+RSEL1+RSEL2,&BCSCTL1 ; RSEL0+RSEL1+RSEL2 , set max DCO freq mov #TASSEL0+MC1,&TACTL ; TASSEL0+MC1[+TAIE] mov #OUTMOD2+CCIE,&TACCTL0 ; OUTMOD2+CCIE mov #OUTMOD2+CCIE,&TACCTL1 ; OUTMOD2+CCIE mov #OUTMOD2+CCIE,&TACCTL2 ; OUTMOD2+CCIE mov #MILLISEC_DELAY,&TACCR0 ; just to start it mov #SIDETONE_DELAY,&TACCR1 ; just to start it mov #default_speed,r4 mov &default_speed,&TACCR2 ; just to start it mov #band_step_lut_5,r15 mov @r15+,&bandstep_up mov @r15+,&bandstep_dn mov @r15+,&bandstep_up+2 mov @r15+,&bandstep_dn+2 clr &flags rstent: mov #02100h,r15 call #out16 ; open dds serial line eint clr r6 rstdly: cmp #300,r6 jl rstdly ; wait a little ;---------------------------------------- ; get user options ;---------------------------------------- rst6: mov #flash_fref, r13 mov #fref,r14 get_loop: mov @r13+,0(r14) incd r14 cmp #ENDOFVARRAM,r14 jne get_loop bic #-1-BF_IMODE,&bflag ; ignore all but the iambic bit #ifdef MULTI_MUTE bis #BF_AFA,&bflag ; enable sidetone for morse bic.b #PO_MUTE ; P1.7 Mute on #endif ;---------------------------------------- ; test for calibrate mode ;---------------------------------------- clr r6 rst0: cmp #300,r6 jl rst0 #ifdef ATS3 bit.b #00ch,&P2IN ; ck for RIT and Tune Up #else bit.b #00ah,&P2IN #endif jnz rst2 br #calref ;---------------------------------------- ; test for straight key mode ;---------------------------------------- rst2: bit.b #PI_DAH ; check for Dah jc rst3 bis #F_STRAIGHTKEY,&flags ; set straight key flag ;---------------------------------------- ; morse output 'ats-' ;---------------------------------------- rst3: ;;; mov #0503h,r14 ; "at" ;;; call #mrsout ;;; call #mrsout ;;; mov #0831h,r14 ; "s-" ;;; call #mrsout ;;; call #mrsout ;---------------------------------------- ; test for band load band values ;---------------------------------------- #ifdef ATS3 bit.b #PI_J12 ; P1.0 J1-2 band check jc bntst2 #else mov.b &P1IN,r15 bic #0fff9h,r15 cmp #0004h,r15 jne bntst1 #endif ; 40 meters #ifdef ATS3 bit.b #PI_J13 ; P2.4 J1-3 band check jnc bntst1 #endif mov #BAND_40,r13 jmp bntst4 ;30 meters bntst1: #ifndef ATS3 cmp #0002h,r15 jne bntst2 #endif mov #BAND_30,r13 jmp bntst4 ; 20 meters bntst2: #ifdef ATS3 bit.b #PI_J13 ; P2.4 J1-3 band check jnc bntst3 #else cmp #0006h,r15 jne bntst3 #endif mov #BAND_20,r13 bis #BF_20M,&bflag ; 20m flag jmp bntst4 ; 80 meters bntst3: mov #BAND_80,r13 bis #BF_80M,&bflag ; 80m flag bntst4: mov @r13+,&fbcd+2 ; load from BAND_ lut mov @r13+,&fbcd mov @r13+,r14 call #mrsout ; send '4'|'3'|'2'|'8' depending on band mov #00307h,r14 ; load "0M" to be set next call #mrsout ; send '0' (zero) call #mrsout ; send 'M' #ifdef SCAN mov @r13+,&scan_a+2 mov #00000h,&scan_a mov @r13+,&scan_b+2 mov #00000h,&scan_b #endif bic #F_VFO,&flags ; vfo flag, set to A mov &fbcd,&fbcd_other ; save freq in other vfo mov &fbcd+2,&fbcd_other+2 ; high word call #calc_new_freq mov &fbin,&fbin_other ; init the other fbin mov &fbin+2,&fbin_other+2 ; high word mov #02000h,r15 call #out16 ; close dds serial line #ifdef MULTI_MUTE bic #BF_AFA,&bflag bis.b #PO_MUTE ; P1.7 Mute off #endif jmp wait ;---------------------------------------- ; main loop - input polling ;---------------------------------------- waitr: mov #00a00h,r14 ; 'r' call #mrsout #ifdef SCAN bic #F_SCANMODE,&flags ; clr scan mode #endif wait: bit #F_STRAIGHTKEY,&flags ; straight key flag jnc wait3 #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit #endif jc wait4 stky: br #strkey wait3: #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit #endif jc wait3a br #padin_dit wait3a: #ifdef STEALTH call #isDah #else bit.b #PI_DAH ; P2.0 Dah #endif jc wait4 br #padin_dah wait4: bit.b #PI_SPLIT ; P2.3 Split/Rit jnc split bit.b #PI_TUNEUP ; P2.2 Tune Up jnc tnup #ifdef STEALTH bit #BF_STEALTH,&bflag jc wait #endif bit.b #PI_TUNEDN ; P1.2 Tune Down jnc tndn bit.b #PI_MENU ; P1.1 Menu jnc fun jmp wait ;---------------------------------------- ; Calculate new frequency routine(s) ;---------------------------------------- calc_new_freq_spl: push r15 #ifdef SCAN ; test for scan mode bit #F_SCANMODE,&flags jc calc_new_freq_spl_a #endif call #kilo_beep #ifdef SCAN calc_new_freq_spl_a: #endif call #calc_new_freq pop r15 ret calc_new_freq: call #bcd2bin ; calc bin for phase accumulator of dds call #offset ; send lo freq to dds, lo= f(rx,if) ret ;---------------------------------------- ; tune up ;---------------------------------------- tnup: #ifdef SCAN ; short wait clr r6 tnup_short_wait: cmp #100,r6 jl tnup_short_wait ; if tndn ; enter scan mode bit.b #PI_TUNEDN ; P1.2 Tune Down jnc scan_mode_start_scanning ; fi #endif mov #1200,r15 tnok: clrc dadd &bandstep_up,&fbcd ; add bandstep dadd &bandstep_up+2,&fbcd+2 tu1: call #calc_new_freq_spl clr r6 tu_lp2: #ifdef SCAN bit #F_SCANMODE,&flags ; scan flag jnc tnup_noscan_continue tnup_scan: bit.b #PI_MENU ; P1.1 Menu jnc wait_for_menu_up ; check for past upper scan limit cmp &fbcd+2,&scan_b+2 ; ck highest bytes jl reset_scan jnz tnup_scan_continue cmp &fbcd,&scan_b ; ck lower bytes jl reset_scan jmp tnup_scan_continue reset_scan: mov &scan_a,&fbcd mov &scan_a+2,&fbcd+2 mov #00800h,r14 ; 's' call #mrsout call #calc_new_freq_spl jmp tnup_scan_continue tnup_noscan_continue: #endif bit.b #PI_TUNEUP ; P2.2 Tune Up jc wait #ifdef SCAN tnup_scan_continue: #endif cmp r15,r6 jl tu_lp2 mov #120,r15 jmp tnok ;---------------------------------------- ; tune down ;---------------------------------------- tndn: #ifdef SCAN ; short wait clr r6 tndn_short_wait: cmp #100,r6 jl tndn_short_wait ; if tnup ; enter scan mode bit.b #PI_TUNEUP ; P2.2 Tune Up jnc scan_mode_start_scanning ; fi #endif mov #1200,r15 tdok: setc dadd &bandstep_dn,&fbcd ; subtract bandstep dadd &bandstep_dn+2,&fbcd+2 td1: call #calc_new_freq_spl clr r6 td_lp2: bit.b #PI_TUNEDN ; P1.2 Tune Down jc wait cmp r15,r6 jl td_lp2 mov #120,r15 jmp tdok ;---------------------------------------- ; Kilohertz boundary beep routine ; add a beep if 1000Hz boundary hit ;---------------------------------------- kilo_beep: mov &fbcd,r14 and #00fffh,r14 jnz kilo_beep_ex mov #0200h,r14 ; 'e' call #mrsout kilo_beep_ex: ret ;---------------------------------------- ; band step size change ;---------------------------------------- band_step_loop: call #mrsout band_step: bit.b #PI_TUNEUP jnc band_step_up bit.b #PI_TUNEDN jnc band_step_dn bit.b #PI_SPLIT jnc band_step_sp bit.b #PI_MENU jc band_step wait_for_menu_up: bit.b #PI_MENU ; wait till menu button released jnc wait_for_menu_up br #waitr band_step_sp: mov #band_step_lut_M,r15 bis #BF_MHZ,&bflag ; set MHz mode flag jmp band_step_work band_step_dn: mov #band_step_lut_5,r15 jmp band_step_work band_step_up: mov #band_step_lut_1,r15 ;;; jmp band_step_work ; just fall thru band_step_work: mov @r15+,&bandstep_up mov @r15+,&bandstep_dn mov @r15+,&bandstep_up+2 mov @r15+,&bandstep_dn+2 mov @r15,r14 jmp band_step_loop ;---------------------------------------- ; Split/rit menu options ;---------------------------------------- split: clr r6 split_4: bit.b #PI_SPLIT ; Split button jc keyer_memory cmp #667,r6 jl split_4 split_rtn: clr r6 split_1: bit.b #PI_SPLIT ; Split button jc switch_vfo cmp #667,r6 jl split_1 mov #01b00h,r14 ; 'y' (synchronize) call #mrsout clr r6 split_6: bit.b #PI_SPLIT ; Split button jc synchronize_vfos cmp #667,r6 jl split_6 mov #00608h,r14 ; load "ns" bit #F_SPLIT,&flags ; check split/rit flag 0=normal 1=split jnc split_2 swpb r14 split_2: call #mrsout clr r6 split_3: bit.b #PI_SPLIT ; Split button jc switch_vfo_mode cmp #667,r6 jl split_3 #ifdef SCAN mov #08a00h,r14 ; 'sc' (scan mode) call #mrsout clr r6 split_8: bit.b #PI_SPLIT ; Split button jc scan_mode cmp #667,r6 jl split_8 #endif mov #04000h,r14 ; 'ss' (step size) call #mrsout clr r6 split_7: bit.b #PI_SPLIT ; Split button jc band_step cmp #667,r6 jl split_7 split_exit: mov #01900h,r14 ; 'x' call #mrsout split_5: bit.b #PI_SPLIT ; Split button released? jnc split_5 jmp wait ;---------------------------------------- ; switch vfo routine ;---------------------------------------- switch_vfo_mode: xor #F_SPLIT,&flags ; switch mov #00608h,r14 ; load "ns" bit #F_SPLIT,&flags ; what are we really? jnc split_vfo_mode_announce swpb r14 split_vfo_mode_announce: call #mrsout call #offset br #wait keyer_memory: br #kmemout ; goto memory play function ;---------------------------------------- ; switch vfo's ;---------------------------------------- switch_vfo: ; switch VFO's here mov &fbin,&fbin_other ; save current fbin to fbin_other mov &fbin+2,&fbin_other+2 mov &fbcd,r14 ; switch them mov &fbcd_other,&fbcd mov r14,&fbcd_other mov &fbcd+2,r14 mov &fbcd_other+2,&fbcd+2 mov r14,&fbcd_other+2 xor #F_VFO,&flags ; switch mov #00518h,r14 ; load "ab" bit #F_VFO,&flags ; test vfo flag a=0 b=1 jnc switch_vfo_a swpb r14 switch_vfo_a: call #mrsout call #calc_new_freq jmp wait ;---------------------------------------- ; Synchronize vfo's - make the other vfo ; the same as the current vfo ;---------------------------------------- synchronize_vfos: mov &fbin,&fbin_other ; save current fbin to fbin_other mov &fbin+2,&fbin_other+2 mov &fbcd,&fbcd_other mov &fbcd+2,&fbcd_other+2 jmp waitr ; could be waitr vice wait if want confirmation ;---------------------------------------- ; scan mode ;---------------------------------------- #ifdef SCAN scan_mode: ; if tunedown button then bit.b #PI_TUNEDN jc scan_mode_vfo_button ; vfo -> scan mov &fbcd,&scan_a mov &fbcd+2,&scan_a+2 mov &fbcd_other,&scan_b mov &fbcd_other+2,&scan_b+2 ; beep mov #0200h,r14 ; 'e' call #mrsout ; endif scan_mode_vfo_button: ; if vfo button then bit.b #PI_SPLIT ; P2.3 jc scan_mode_menu_button ; set scan flag scan_mode_start_scanning: bis #F_SCANMODE,&flags mov #0800h,r14 ; 's' call #mrsout jmp tnup ; endif scan_mode_menu_button: ; if menu button then bit.b #PI_MENU jnc wait_for_menu_up ; endif ; if tuneup button then get the scan memories to vfo's bit.b #PI_TUNEUP jc scan_mode ; scan -> vfo mov &scan_a,&fbcd mov &scan_a+2,&fbcd+2 mov &scan_b,&fbcd_other mov &scan_b+2,&fbcd_other+2 ; beep mov #0200h,r14 ; 'e' call #mrsout ; endif jmp scan_mode #endif ;---------------------------------------- ; menu button functions ;---------------------------------------- fun: clr r6 fun_lp1: bit.b #PI_MENU ; P1.1 Menu jc afa ; frequency cmp #667,r6 jl fun_lp1 mov #0800h,r14 ; 's' call #mrsout clr r6 fun_lp2: bit.b #PI_MENU ; P1.1 Menu mov #keyer_speed,r7 jc cdsp ; transmit speed cmp #667,r6 jl fun_lp2 bit #F_STRAIGHTKEY,&flags ; if straight key then skip a few functions jc fun_lp4a mov #0200h,r14 ; 'e' call #mrsout clr r6 fun_lp3: bit.b #PI_MENU ; P1.1 Menu jc enfreq cmp #667,r6 jl fun_lp3 mov #0300h,r14 ; 't' call #mrsout clr r6 fun_lp5: bit.b #PI_MENU ; P1.1 Menu jc tune cmp #667,r6 jl fun_lp5 mov #0700h,r14 ; 'm' call #mrsout clr r6 fun_lp6: bit.b #PI_MENU ; P1.1 Menu jc kmemint cmp #667,r6 jl fun_lp6 fun_lp4a: #ifdef WIDE mov #0b00h,r14 ; 'w' call #mrsout clr r6 fun_lp9: bit.b #PI_MENU ; P1.1 Menu jc dcrx cmp #667,r6 jl fun_lp9 #endif mov #01a00h,r14 ; 'c' call #mrsout clr r6 fun_lp2a: bit.b #PI_MENU ; P1.1 Menu mov #command_speed,r7 ; carry bit not affected by a mov jc cdsp ; command_speed cmp #667,r6 jl fun_lp2a mov #01600h,r14 ; 'p' call #mrsout clr r6 fun_lp7: bit.b #PI_MENU ; P1.1 Menu jc setup cmp #667,r6 jl fun_lp7 mdexit: mov #01900h,r14 ; 'x' call #mrsout fun_lp8: bit.b #PI_MENU jnc fun_lp8 jmp wait ;---------------------------------------- ; setup ;---------------------------------------- setup: #ifdef MULTI_MUTE bic.b #PO_MUTE ; P1.7 Mute on #endif setup1: bit.b #PI_TUNEUP ; P2.2 Tune Up jnc imode ; iambic mode setup bit.b #PI_MENU ; P1.1 Menu jnc str_su ; save prefs in flash jmp setup1 str_su: call #wrsup jmp waitr imode: xor #BF_IMODE,&bflag ; switch iambic mode mov #0518h,r14 ; load "ab" bit #BF_IMODE,&bflag ; test iambic mode jnc imode_ex swpb r14 imode_ex: call #mrsout jmp setup ;---------------------------------------- ; Jump points ;---------------------------------------- cdsp: br #spd_entry afa: br #mfrqout ;---------------------------------------- ; Enter frequency mode ;---------------------------------------- enfreq: #ifdef MULTI_MUTE bic.b #PO_MUTE ; P1.7 Mute on bis #BF_AFA,&bflag ; enable sidetone for morse #endif bis #BF_ENTERFREQ,&bflag ; enter freq flag clr r8 br #few1 ;---------------------------------------- ; Enter keyer memory ;---------------------------------------- kmemint: #ifdef MULTI_MUTE bic.b #PO_MUTE ; P1.7 Mute on bis #BF_AFA,&bflag ; enable sidetone for morse #endif mov #rammem,r8 bis #BF_MEMSTORE+BF_ENTERFREQ,&bflag ; memory and enter freq flag br #kmlp2 ;---------------------------------------- ; Wide mode toggle ; ; might need to change so that assume is not used rather direct checking instead -- listen to see ; leave as is -- it "clicks" when going to wide ; and is more silent when going to normal ;---------------------------------------- #ifdef WIDE dcrx: xor #F_WIDEMODE,&flags bic.b #PO_SIDETONE ; P2.5 Sidetone off, assume normal bit #F_WIDEMODE,&flags jnc exdc bis.b #PO_SIDETONE ; P2.5 Sidetone on, it is wide exdc: br #wait #endif ;---------------------------------------- ; calc LO offset (LO=f(tx,offset) ;---------------------------------------- offset: mov &ofst,r12 mov &ofst+2,r13 mov &fbin,r15 mov &fbin+2,r14 bit #BF_80M,&bflag ; 80m flag jc offj_1 sub r12,r15 ; 80m condition subc r13,r14 jmp offj_2 offj_1: add r12,r15 ; 40m,30m,20m condition addc r13,r14 offj_2: call #ddsout ret ;---------------------------------------- ; talk to the dds chip routine ;---------------------------------------- talk_2_dds: rla r15 rlc r14 rla r15 rlc r14 ; r14 x4 rrc r15 rrc r15 ; r15 essentially unchanged bis r12,r15 call #out32 ; this could be out16 with no effect mov r14,r15 bis r12,r15 call #out16 ret ;---------------------------------------- ; send LO to dds ;---------------------------------------- ddsout: mov #04000h,r12 call #talk_2_dds ;---------------------------------------- ; send tx freq to dds ;---------------------------------------- txdds: ; load current fbin mov &fbin,r15 ; assume split off and load fbin mov &fbin+2,r14 ; if split/rit then bit #F_SPLIT,&flags ; Split/Rit flag jnc txdds_a ; load fbin_other mov &fbin_other,r15 ; split on, so load fbin_other mov &fbin_other+2,r14 ; endif txdds_a: #ifdef WIDE mov #219924/SIDETONE_DELAY,r12 ; ((32768 * 6.7108864) + 21) / SIDETONE_DELAY ; the 21 is to help with rounding ; 6.7108864 = 2^28/40M bit #F_WIDEMODE,&flags ; wide mode flag jnc txnos bit #BF_20M,&bflag ; 20m flag jnc test80 add r12,r15 ; 20m so add adc r14 jmp txnos test80: bit #BF_80M,&bflag ; 80m flag jnc txnos sub r12,r15 ; 80m so subtract sbc r14 txnos: #endif mov #08000h,r12 call #talk_2_dds ret ;---------------------------------------- ; Serial out to dds ;---------------------------------------- out32: out16: out: mov #16,r13 bic.b #PO_FSYNC ; P1.6 FSYNC dds, tell dds data is coming, frame sync mbits: rlc r15 jc one bic.b #PO_SDATA ; 0, P1.4 SDATA dds, send 0 dclok: nop ;;; jmp $+2 ; NOP 2 cycles 1 word, trying to see if I can monitor via butterfly board ;;; jmp $+2 ; NOP 2 cycles 1 word ;;; jmp $+2 ; NOP 2 cycles 1 word bic.b #PO_SCLK ; P1.5 SCLK dds, trigger dds clock in nop ;;; jmp $+2 ; NOP 2 cycles 1 word, trying to see if I can monitor via butterfly board ;;; jmp $+2 ; NOP 2 cycles 1 word ;;; jmp $+2 ; NOP 2 cycles 1 word bis.b #PO_SCLK ; P1.5 SCLK dds, reset dec r13 jne mbits bis.b #PO_FSYNC ; P1.6 FSYNC dds, no more data outout: ret one: bis.b #PO_SDATA ; 1, P1.4 SDATA dds, send 1 jmp dclok ;---------------------------------------- ; Any button clicked routine ;---------------------------------------- #ifdef ANYBUTTON anyButton: bit.b #PI_MENU ; exit on any button jnc anyButton_set bit.b #PI_SPLIT jnc anyButton_set bit.b #PI_TUNEDN jnc anyButton_set bit.b #PI_TUNEUP jnc anyButton_set clrc ret anyButton_set: setc ret #endif ;---------------------------------------- ; Tune mode ;---------------------------------------- tune: bit.b #PI_DAH ; P2.0 Dah jnc en_tx #ifdef ANYBUTTON call #anyButton jnc tune #else bit.b #PI_MENU ; P1.1 Menu jc tune #endif tu_w5: #ifdef ANYBUTTON clr r5 tu_wdly: cmp #0015h,r5 ; word space jl tu_wdly #else tu_w5a: bit.b #PI_MENU ; P1.1 Menu jc tu_w5a #endif br #waitr en_tx: bis #F_SIDETONE,&flags ; enable sidetone bic.b #PO_MUTE ; P1.7 Mute on mov #0838h,r15 ; txfreq call #out16 bis.b #PO_TRANSMIT ; P1.3 Transmit enable tu_w2: bit.b #PI_DIT ; Dit jnc de_tx #ifdef ANYBUTTON call #anyButton jc de_tx #endif jmp tu_w2 de_tx: bic.b #PO_TRANSMIT ; P1.3 Transmit disable bic #F_SIDETONE,&flags ;stop sidetone clr r6 tu_w3: cmp #9,r6 jl tu_w3 mov #02000h,r15 call #out16 ; close dds serial line clr r6 tu_w4: cmp #15,r6 jl tu_w4 bis.b #PO_MUTE ; P1.7 Mute off jmp tune ;---------------------------------------- ; straight key mode ;---------------------------------------- strkey: bis #F_SIDETONE,&flags ; enable sidetone bic.b #PO_MUTE ; P1.7 Mute on mov #0838h,r15 ; txfreq call #out16 bis.b #PO_TRANSMIT ; P1.3 Transmit enable sk_lp: #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit ; test for straight key #endif jnc sk_lp sk_lp2: bic.b #PO_TRANSMIT ; P1.3 Transmit disable bic #F_SIDETONE,&flags ;stop sidetone clr r6 sk_lp3: cmp #9,r6 jl sk_lp3 mov #02000h,r15 call #out16 ; close dds serial line clr r6 sk_lp4: cmp #15,r6 jl sk_lp4 bis.b #PO_MUTE ; P1.7 Mute off br #wait ;---------------------------------------- ; paddle mode ;---------------------------------------- padinb_dit: bis #F_DIT,&flags; jmp padinb padinb_dah: bis #F_DAH,&flags; jmp padinb padin_dit: bis #F_DIT,&flags; jmp padin padin_dah: bis #F_DAH,&flags; ; jmp padin ; fall thru padin: mov #0001h,r7 ; start marker bit padinb: bis #F_SIDETONE,&flags ; enable sidetone bic.b #PO_MUTE ; P1.7 Mute on bit #BF_ENTERFREQ,&bflag ; Enter freq flag jc padntx mov #0838h,r15 ; dds call #out16 bis.b #PO_TRANSMIT ; P1.3 Transmit enable padntx: mov &keyer_speed,r4 clr r5 ; reset keyer timer bit #F_DAH,&flags ; dah jc dash bit #F_DIT,&flags ; dit jc dot jmp space ;just in case! ;---------------------------------------- dot: clrc rlc r7 bic #F_DIT,&flags dota: cmp #1,r5 jl dota dot2: #ifdef STEALTH call #isDah #else bit.b #PI_DAH ; P2.0 Dah #endif jc dot1 bis #F_DAH,&flags dot1: cmp #3,r5 jl dot2 bit #BF_DITDAH,&bflag jnc space bis #F_DAH,&flags jmp space ;---------------------------------------- dash: setc rlc r7 bic #F_DAH,&flags dasha: cmp #2,r5 jl dasha dash2: #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit #endif jc dash1 bis #F_DIT,&flags dash1: cmp #9,r5 jl dash2 bit #BF_DITDAH,&bflag jnc space bis #F_DIT,&flags ;---------------------------------------- space: clr r5 clr r6 bic.b #PO_TRANSMIT ; P1.3 Transmit disable bit #BF_IMODE,&bflag ; iambic flag jnc sp_lp2 bic #BF_DITDAH,&bflag #ifdef STEALTH call #isDit jc sp_lp2 call #isDah jc sp_lp2 #else bit.b #PI_DIT jc sp_lp2 bit.b #PI_DAH jc sp_lp2 #endif bis #BF_DITDAH,&bflag sp_lp2: cmp #9,r6 jl sp_lp2 bic #F_SIDETONE,&flags ; disable sidetone mov #02000h,r15 call #out16 ; close dds serial line splp: cmp #3,r5 jl splp bit #F_DAH,&flags ; dah flag jc padinb bit #F_DIT,&flags ; dit flag jc padinb bit #BF_ENTERFREQ,&bflag ; enter freq flag jc ltrsp bis.b #PO_MUTE ; P1.7 Mute off br #wait3 ; should this be wait vice wait3? ;---------------------------------------- ; test for letter space ;---------------------------------------- ltrsp: clr r5 ltrsp1: bit.b #PI_DIT ; P2.1 Dit jc ltrsp1a jmp padinb_dit ltrsp1a: bit.b #PI_DAH ; P2.0 Dah jc ltrsp1b jmp padinb_dah ltrsp1b: cmp #5,r5 ; make this smaller to help with entering code , vice orig of #9 jl ltrsp1 bit #BF_MEMSTORE,&bflag jc kmem br #decode ;---------------------------------------- ; keyer mem temp store ;---------------------------------------- kmem: mov.b r7,0(r8) inc r8 cmp #ramend,r8 ; mem limit test jeq strkmem_out clr r5 kmlp1: bit.b #PI_DAH ; P2.0 Dah jc kmlp1a jmp padin_dah kmlp1a: bit.b #PI_DIT ; P2.1 Dit jc kmlp1b jmp padin_dit kmlp1b: cmp #21,r5 jl kmlp1 mov #0200h,r14 ; 'e' call #mrsout ; put out a 'e' here to let user know a word space was added clr r7 mov.b r7,0(r8) inc r8 cmp #ramend,r8 ; mem limit test jeq strkmem_out kmlp2: bit.b #PI_DIT ; P2.1 Dit jc kmlp2a jmp padin_dit kmlp2a: bit.b #PI_DAH ; P2.0 Dah jc kmlp2b jmp padin_dah kmlp2b: bit.b #PI_MENU ; P1.1 Menu jnc strkmem jmp kmlp2 ;---------------------------------------- ; store keyer message ;---------------------------------------- strkmem_out: mov #0ffffh,0(r8) ; put ff in last two bytes jmp strkmem_j2 strkmem: mov.b #0ffh,0(r8) ; put ff in last byte ; put one or two more in if necessary bit.b #001h,r8 ; odd memory? jnc strkmem_j1 inc r8 mov #0ffffh,0(r8) ; yes, put ff in next two bytes jmp strkmem_j2 strkmem_j1: ; no it is even, put ff in next one byte inc r8 mov.b #0ffh,0(r8) strkmem_j2: mov #rammem,r8 jmp kmelp1 ;---------------------------------------- ; send keyer message ;---------------------------------------- kmemout: bis #BF_MEMPLAY,&bflag ; memory flag mov #flash_rammem,r8 ; ; this is where the logic for multiple memory goes ; clr r6 mem_choice: #ifdef STEALTH bit.b #PI_SPLIT jc mem_choice_4 xor #BF_STEALTH,&bflag ; toggle flag bic #BF_MEMPLAY,&bflag ; memory flag bit #BF_STEALTH,&bflag ; test stealth mode jc stealth_beep br #waitr ; send 'r' to indicate normal stealth_beep: mov #00200h,r14 ; send 'e' to indicate stealth call #mrsout br #wait mem_choice_4: #endif bit.b #PI_MENU jnc kmelp1 bit.b #PI_TUNEDN jc mem_choice_tuneup mem_choice_1: inc r8 cmp.b #0ffh,-1(r8) ; skip to byte after next ff jne mem_choice_1 jmp kmelp1 mem_choice_tuneup: bit.b #PI_TUNEUP jc mem_choice_loop mem_choice_2: inc r8 cmp.b #0ffh,-1(r8) ; skip to byte after next ff jne mem_choice_2 mem_choice_3: inc r8 cmp.b #0ffh,-1(r8) ; skip to byte after next ff jne mem_choice_3 jmp kmelp1 mem_choice_loop: cmp #333,r6 ; 1/3 second delay jl mem_choice bic #BF_MEMPLAY,&bflag ; memory flag br #split_rtn kmemout1: bis #BF_MEMPLAY,&bflag ; memory flag mov #flash_rammem,r8 kmelp1: mov.b @r8+,r14 cmp.b #000h,r14 ; is a word space? jeq kwds cmp.b #0ffh,r14 ; is at end? jne kmelp2 bit #BF_MEMPLAY,&bflag ; sending memory? jc eostrg cmp.b #0ffh,0(r8) jeq eostrg ; only exit if 2 ff in a row kmelp2: swpb r14 call #mrst ; transmit character! #ifdef PAUSE bit #F_STRAIGHTKEY,&flags ; straight key flag jc kmelp3 #ifdef STEALTH call #isDah #else bit.b #PI_DAH ; P2.0 Dah #endif jnc kpause #endif kmelp3: bit.b #PI_MENU ; P1.1 Menu jnc intbmod #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit #endif jnc exkm jmp kmelp1 ;---------------------------------------- ; message word space delay ;---------------------------------------- kwds: clr r5 kwdslp: cmp #0015h,r5 ; word space jl kwdslp jmp kmelp1 #ifdef PAUSE ;---------------------------------------- ; message pause ;---------------------------------------- kpause: #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit #endif jnc intbmod #ifdef STEALTH call #isDah #else bit.b #PI_DAH ; P2.0 Dah #endif jnc kpause jmp kmelp1 #endif eostrg: bit #BF_BEACON,&bflag ; beacon flag jc beacm bit #BF_MEMSTORE+BF_ENTERFREQ,&bflag ; memory and enter freq flags jc kmemfs bic #BF_MEMPLAY,&bflag ; memory flag br #wait exkm: #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit #endif jnc exkm bic #BF_MEMPLAY+BF_BEACON,&bflag ; beacon and memory flags br #wait intbmod: bit #BF_BEACON,&bflag ; test beacon flag jnc intbmod_1 ; not set so enter beacon mode jmp exbcnm ; set so exit beacon mode intbmod_1: bis #BF_BEACON,&bflag ; beacon flag clr r6 bis #F_SIDETONE,&flags ; enable sidetone ibmd_j2: cmp #250,r6 ; short beep for feedback jl ibmd_j2 bic #F_SIDETONE,&flags ; disable sidetone ibmd_j: #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit #endif jnc ibmd_j jmp kmelp1 beacm: clr r6 bealp1: ; test for SK mode bit #F_STRAIGHTKEY,&flags ; straight key jc beac_sk #ifdef STEALTH call #isDah #else bit.b #PI_DAH ; P2.0 Dah #endif jnc exbcnm beac_sk: #ifdef STEALTH call #isDit #else bit.b #PI_DIT ; P2.1 Dit #endif jnc exbcnm cmp #3500,r6 ; delay between beacons jl bealp1 jmp kmemout1 exbcnm: bic #BF_MEMPLAY+BF_BEACON,&bflag ; beacon and memory flags ; test for SK mode bit #F_STRAIGHTKEY,&flags ; straight key jnc padin br #wait ;---------------------------------------- kmemfs: bit.b #PI_MENU ; P1.1 Menu jnc km_l1 bit.b #PI_SPLIT ; P2.3 Rit jnc km_l2 jmp kmemfs km_l1: bic #BF_MEMSTORE+BF_ENTERFREQ,&bflag ; memory and enter freq flags mov #rammem,r8 mov #flash_rammem,r13 call #cl_flash km_l3: mov @r8+,r14 call #wr_flsh ; write flash cmp #0ffffh,r14 jeq mwrdone incd r13 jmp km_l3 km_l2: mov #0200h,r14 ; 'e' call #mrsout mov #0700h,r14 ; 'm' call #mrsout br #kmemint mwrdone: mov #0200h,r14 ; 'e' call #mrsout #ifdef MULTI_MUTE bic #BF_AFA,&bflag ; disable sidetone for morse bis.b #PO_MUTE ; P1.7 Mute off #endif br #wait ;---------------------------------------- ;output morse character ;---------------------------------------- mrst: mov &keyer_speed,r4 jmp mrs_lp4 mrsout: mov &command_speed,r4 mrs_lp4: mov #9,r12 ; limit bits to look at bic.b #PO_MUTE ; P1.7 Mute on mrs_lp1: dec r12 jz mrs_ext rlc r14 ; find marker bit (1) jnc mrs_lp1 mrs_lp3: dec r12 jz mrs_ext ; no more bits, now exit bit #BF_MEMPLAY,&bflag ; memory flag jnc mrs_lp2 mov #0838h,r15 call #out16 bis.b #PO_TRANSMIT ; P1.3 Transmit enable mrs_lp2: clr r5 bis #F_SIDETONE,&flags ; enable sidetone rlc r14 ; get next bit (1=dah 0=dit) jc mdash mdot: cmp #0003h,r5 ; dit jl mdot jmp mspace mdash: cmp #0009h,r5 ; dah jl mdash mspace: bit #BF_MEMPLAY,&bflag ; Memory flag jnc msp1 bic.b #PO_TRANSMIT ; P1.3 Transmit disable clr r6 tw_lp: cmp #9,r6 jl tw_lp mov #02000h,r15 call #out16 ; close dds serial line msp1: bic #F_SIDETONE,&flags ; space clr r5 ms_lp: cmp #0003h,r5 jl ms_lp jmp mrs_lp3 ; loop till done mrs_ext: cmp #0009h,r5 ; exit jl mrs_ext #ifdef MULTI_MUTE bit #BF_AFA,&bflag jc mrs_lp7 #endif bis.b #PO_MUTE ; P1.7 Mute off mrs_lp7: ret ;---------------------------------------- ;change code speed ; ; input: r7 points to index ; output: r7 points to new index ;---------------------------------------- spd_lut: mov #0200h,r14 ; 'e' spd_lut_announce: call #mrsout spd_entry: bit #F_STRAIGHTKEY,&flags ; straight key jc spd_lp2 bit.b #PI_DAH ; P2.0 Dah jnc spdup bit.b #PI_DIT ; P2.1 Dit jnc spddn spd_lp2: bit.b #PI_TUNEUP ; P2.2 Tune Up jnc spdup bit.b #PI_TUNEDN ; P1.2 Tune Down jnc spddn bit.b #PI_MENU jc spd_entry call #wrsup ; save to flash br #waitr ; out an 'r' spdup: decd 0(r7) cmp #sp_lut-2,0(r7) jne spd_lut incd 0(r7) jmp sp_end spddn: incd 0(r7) cmp #sp_lut_end,0(r7) jne spd_lut decd 0(r7) sp_end: mov #0400h,r14 ; 'i' jmp spd_lut_announce ;---------------------------------------- ; Announce frequency in morse ;---------------------------------------- mfrqout: clr r5 #ifdef MULTI_MUTE bis #BF_AFA,&bflag bic.b #PO_MUTE ; P1.7 Mute on #endif mxxx1: cmp #0015h,r5 ; word space delay before sending characters jl mxxx1 ; add check for split/rit bit #F_SPLIT,&flags ; check split/rit flag jnc check_vfo mov #00800h,r14 ; 's' call #mrsout check_vfo: ; add the vfo mov #00518h,r14 ; "ab" bit #F_VFO,&flags ; VFO flag a=0 jnc out_vfo swpb r14 out_vfo: call #mrsout clr r5 mxxx: cmp #0015h,r5 ;word space delay before sending characters jl mxxx bit #BF_MHZ,&bflag ; have we entered MHz mode? jnc no_mhz mov &fbcd+2,r9 call #mconv ; 10MHz, costs too much program space to test for 0 so leave it call #mconv ; 1MHz mov #0a00h,r14 ; send 'r' call #mrsout no_mhz: mov.b &fbcd+2,r9 ; this is duplicated elsewhere maybe make a routine for it swpb r9 mov.b &fbcd+1,r8 add r8,r9 call #mconv ;convert BCD digit to morse character and output call #mconv call #mconv mov #0a00h,r14 ; send 'r' call #mrsout call #mconv #ifdef ANNOUNCE_10HZ mov.b &fbcd,r9 ; out the 10Hz digit if not zero swpb r9 and #0f000h,r9 jz mfrqout_end call #mconv #endif mfrqout_end: #ifdef MULTI_MUTE bic #BF_AFA,&bflag ; clr morse flag bis.b #PO_MUTE ; P1.7 Mute off #endif br #wait ;---------------------------------------- ; convert decimal to morse ;---------------------------------------- mconv: clr r7 clrc mov #4,r14 mconv_loop: rlc r9 ;shift upper 4 bits of r9 into lower 4 bits of r7 rlc r7 ;at the same time, positions next BCD nibble in upper dec r14 ;4 bits of r9 jnz mconv_loop mconv1: mov #mlut,r8 ;initalize table pointer add r7,r8 ;add in offset mov.b @r8,r14 ;get value in table swpb r14 call #mrsout ; send decimal in morse ret ;---------------------------------------- ; Rotate 4 bits left (nibble) ;---------------------------------------- rot4l: rla r7 rla r7 rla r7 rla r7 ret ;---------------------------------------- ; Enter frequency - dfe mode ;---------------------------------------- fewait: mov #0200h,r14 ; 'e' call #mrsout ;---------------------------------------- ; paddle switch wait ;---------------------------------------- few1: bit.b #PI_DAH ; P2.0 Dah jc few1a br #padin_dah few1a: bit.b #PI_DIT ; P2.1 Dit jc few1b br #padin_dit few1b: bit.b #PI_MENU ; P1.1 Menu jnc fe_ex jmp few1 ;---------------------------------------- ; morse to decimal ;---------------------------------------- decode: cmp #002fh,r7 jne dcd1 mov #1,r7 jmp dcdx dcd1: cmp #0003h,r7 jne dcd2 clr r7 jmp dcdx dcd2: cmp #0027h,r7 jne dcd3 mov #2,r7 jmp dcdx dcd3: cmp #0023h,r7 jne dcd4 mov #3,r7 jmp dcdx dcd4: cmp #0021h,r7 jne dcd5 mov #4,r7 jmp dcdx dcd5: cmp #0020h,r7 jne dcd6 mov #5,r7 jmp dcdx dcd6: cmp #0030h,r7 jne dcd7 mov #6,r7 jmp dcdx dcd7: cmp #0038h,r7 jne dcd8 mov #7,r7 jmp dcdx dcd8: cmp #003ch,r7 jne dcd9 mov #8,r7 jmp dcdx dcd9: cmp #003eh,r7 jne dcd0 mov #9,r7 jmp dcdx dcd0: cmp #003fh,r7 jne nngod clr r7 ;---------------------------------------- ; pack BCD digits ;---------------------------------------- dcdx: inc r8 cmp #1,r8 jne tst2 swpb r7 call #rot4l mov r7,r10 jmp fewait tst2: cmp #2,r8 jne tst3 swpb r7 add r7,r10 jmp fewait tst3: cmp #3,r8 jne tst4 call #rot4l add r7,r10 jmp fewait tst4: add r7,r10 jmp calnf nngod: mov #04c00h,r14 ; '?' call #mrsout jmp few1 ;---------------------------------------- ; calc new freq ;---------------------------------------- calnf: mov.b r10,&fbcd+1 ; move the lb of R10 to the second byte of fbcd swpb r10 mov.b r10,&fbcd+2 ; move the hb of r10 to the third byte of fbcd mov.b #000h,&fbcd ; clr the 10's and 1's Hz fe_ex: bic #BF_ENTERFREQ,&bflag ; enter freq flag call #calc_new_freq jmp mfrqout #ifdef STEALTH ;---------------------------------------- ; isDit ; ;---------------------------------------- isDit: bit #BF_STEALTH,&bflag jnc isDit_normal bit.b #PI_MENU ret isDit_normal: bit.b #PI_DIT isDitDah_exit: ret ;---------------------------------------- ; isDah ; ;---------------------------------------- isDah: bit #BF_STEALTH,&bflag jnc isDah_normal bit.b #PI_TUNEDN ret isDah_normal: bit.b #PI_DAH ret #endif ;---------------------------------------- ; mult10 - multiply by 10. ; ; inputs: r12,r11 ; outputs: r12,r11 ;---------------------------------------- mult10: rla r11 rlc r12 ; 2* mov r11,r14 mov r12,r15 ; save the 2* temp to add back in later rla r11 rlc r12 ; 2* (cumulative 4*) rla r11 rlc r12 ; 2* (cumulative 8*) clrc add r14,r11 ; add the temp 2* to the 8* to get 10*. addc r15,r12 ret ;---------------------------------------- ; bcd2bin ; ; inputs: fbcd+2, fbcd ; outputs: fbc+2, fbc ; ; where number is abcdefgh here is the formula ; ((((((((((((((a*10)+b)*10)+c)*10)+d)*10)+e)*10)+f)*10)+g)*10)+h) ; 8 shifts ; 7 mult10 ; 7 add's plus 1 at the beginning where the zero is added, making 8 adds ;---------------------------------------- bcd2bin: mov &fbcd,r8 mov &fbcd+2,r9 clr r11 ; to hold the accumulations clr r12 mov #8,r13 ; counter bcd2bin_loop: clr r10 ; to hold the bcd nibble mov #4,r14 bcd2bin_loop1: clrc rla r8 rlc r9 rlc r10 dec r14 jnz bcd2bin_loop1 ; r10 now has the next nibble in lsb clrc add r10,r11 ; since r12,r11 clr'd at beginning so the extra add of 0 is OK adc r12 dec r13 jz bcd2bin_exit call #mult10 jmp bcd2bin_loop bcd2bin_exit: mov r11,&fbc mov r12,&fbc+2 ; jmp bindiv ; fall thru ;---------------------------------------- ; bindiv - mult by 2^28 and div by fref ;---------------------------------------- bindiv: clr r7 clr r8 mov &fbc,r9 mov &fbc+2,r10 clr r11 clr r12 mov #65,r15 ; load up counter for 65 bits (8 bytes or so) clrc d28_1: rlc r7 ; originally cleared rlc r8 ; originally cleared rlc r9 ; originally fbc rlc r10 ; originally fbc+2 push sr dec r15 jnz d28_2 pop sr ; prep to exit bindiv mov #4,r14 d28_1_1: clrc rrc r8 rrc r7 dec r14 jnz d28_1_1 mov r7,&fbin mov r8,&fbin+2 ret d28_2: pop sr ; do this 64 times (2^64 ?) rlc r11 ; originally cleared rlc r12 ; originally cleared, complete left shift through all 6 words r12-r7 sub &fref,r11 ; subtract from fref (dividing) subc &fref+2,r12 jc d28_3 ; only if bit set add &fref,r11 ; otherwise add it back addc &fref+2,r12 clrc ; push a 0 on the output (r8,r7) jmp d28_1 d28_3: setc ; push a 1 on the output line (r8,r7) jmp d28_1 ;---------------------------------------- ; Calibration mode - dds ref freq ;---------------------------------------- calref: mov #01107h,r14 ; "vm" call #mrsout call #mrsout mov #02330h,r14 ; "36 call #mrsout call #mrsout mov #01a12h,r14 ; "cf" call #mrsout call #mrsout #ifdef OSC_50 mov #0f080h,&fref ; load start freq ref mov #02fah,&fref+2 ; 02faf080h = 50,000,000. #else mov #05a00h,&fref ; load start freq ref mov #0262h,&fref+2 ; 02625a00h = 40,000,000. #endif mov #01000h,&fbcd+2 mov #00000h,&fbcd call #bcd2bin bic.b #PO_MUTE ; P1.7 Mute on call #txdds mov #02838h,r15 call #out16 cfw: bit.b #PI_TUNEUP ; P2.2 Tune Up jnc cfw cfwait: bit.b #PI_TUNEUP ; P2.2 Tune Up jnc cfdn bit.b #PI_TUNEDN ; P1.2 Tune Down jnc cfup bit.b #PI_MENU ; P1.1 Menu jnc adjoff ; continue to calibrate offset jmp cfwait cfup: add #0ah,&fref ; fref + 10Hz addc #0,&fref+2 jmp cfwait1 cfdn: sub #000ah,&fref ; fref - 10Hz subc #0,&fref+2 cfwait1: call #bindiv call #txdds clr r6 cfdly: cmp #300,r6 jl cfdly jmp cfwait ;---------------------------------------- ; Write to flash ;---------------------------------------- wr_flsh: dint nop mov #FWKEY+FSSEL0+FN3+FN2+FN0,&FCTL2 mov #FWKEY,&FCTL3 mov #FWKEY+WRT,&FCTL1 mov r14,0(r13) mov #FWKEY,&FCTL1 mov #FWKEY+LOCK,&FCTL3 enable_int: ; must add a few ticks to the TACCRx's because the writing takes longer than SIDETONE_DELAY ticks push &TAR add #SIDETONE_DELAY,0(SP) pop &TACCR1 mov &TACCR1,&TACCR2 mov &TACCR1,&TACCR0 eint ret ;---------------------------------------- ; Clear flash - memory ; r13 tells us which bank to clear 01000h ; or 01080h ;---------------------------------------- cl_flash: dint nop mov #FWKEY+FSSEL0+FN3+FN2+FN0,&FCTL2 mov #FWKEY,&FCTL3 mov #FWKEY+ERASE,&FCTL1 clr 0(r13) mov #FWKEY+LOCK,&FCTL3 jmp enable_int ;---------------------------------------- ; Calibrate IF freq offset ;---------------------------------------- adjoff: mov #01a0fh,r14 ; "co" call #mrsout call #mrsout ad_lp: bit.b #PI_MENU jnc ad_lp #ifdef OSC_50 mov #09fc1h,&fbin ; put init value 4914844.185...Hz mov #0192h,&fbin+2; for 50Mhz clock #else mov #047b1h,&fbin ; put init value 4914844.185...Hz mov #01f7h,&fbin+2; for 40MHz clock #endif #ifdef MULTI_MUTE bis.b #PO_MUTE ; P1.7 Mute off #endif call #txdds mov #02800h,r15 call #out16 ofwait: bit.b #PI_TUNEUP jnc ofup bit.b #PI_TUNEDN jnc ofdn bit.b #PI_MENU jnc ofdone jmp ofwait ofup: #ifdef OSC_50 add #01bh,&fbin ; 5Hz for 50MHz clock #else add #022h,&fbin ; 5Hz for 40MHz clock #endif addc #0,&fbin+2 jmp ofwait1 ofdn: #ifdef OSC_50 sub #01bh,&fbin ; 5Hz for 50MHz clock #else sub #022h,&fbin ; 5Hz for 50MHz clock #endif subc #0,&fbin+2 ofwait1: call #txdds clr r6 ofdly: cmp #300,r6 jl ofdly jmp ofwait ofdone: mov &fbin,&ofst mov &fbin+2,&ofst+2 call #wrsup br #rst2 ;---------------------------------------- ; write user prefs to flash ;---------------------------------------- wrsup: ; write user prefs (cal constants + iambic flags + morse speed constants) to flash mov #ENDOFVARRAM,r14 ; get ram start address so can save some of the flash stuff first mov #BAND_40,r13 ; get flash address of start of LUT's su_lp: mov @r13+,0(r14) ; copy LUT's from flash to ram incd r14 ; cmp #ENDOFFLASH,r13 ; jne su_lp ; loop mov #fref,r12 ; start of ram to copy to flash mov #flash_fref,r13 ; where to copy to in flash call #cl_flash ; clear flash su_lp2: mov @r12+,r14 ; copy ram to register call #wr_flsh ; write flash, write 2 bytes at a time ; must use multiples of 2 bytes !!! ; mov r14,0(r13) incd r13 cmp #ENDOFFLASH,r13 jne su_lp2 ;;; bis.b #PO_MUTE ; P1.7 Mute off ret ;---------------------------------------- ; Set up initial keyer memory ; ;---------------------------------------- ORG 01000h flash_rammem: #define W1MT_MEMORIES #ifdef W1MT_MEMORIES DW 01d1ah ; q c DW 00800h ; s _ DW 00016h ; _ p DW 02f0bh ; 1 w DW 00307h ; t m DW 00bffh ; w mkr DW 0072fh ; m 1 DW 0ff03h ; mkr t DW 02020h ; 5 5 DW 00006h ; _ n DW 00511h ; a v DW 02700h ; 2 _ DW 0ff0bh ; mkr w #endif DW 0ffffh ; mkr mkr ;---------------------------------------- ; Set up initial flash values, ; saved variable plus all the LUT's ;---------------------------------------- ORG 01080h ;fref flash_fref: #ifdef OSC_50 DW 0f080h DW 002fah #else DW 05a00h DW 00262h #endif ;ofst flash_ofst: #ifdef OSC_50 DW 09fc1h DW 00192h #else DW 047b1h DW 001f7h #endif ;bflags flash_bflags: DW 00000h ;morse ndx's flash_command_speed: DW default_speed flash_keyer_speed: DW default_speed ; ; ; setup band data ; BAND_40: DW 00704h DW 00000h DW 02100h #ifdef SCAN DW 00703h DW 00705h #endif BAND_30: DW 01011h DW 00000h DW 02300h #ifdef SCAN DW 01010h DW 01012h #endif BAND_20: DW 01406h DW 00000h DW 02700h #ifdef SCAN DW 01405h DW 01407h #endif BAND_80: DW 00356h DW 00000h DW 03c00h #ifdef SCAN DW 00355h DW 00357h #endif band_step_lut_M: DW 00000h DW 09999h DW 00100h DW 09899h DW 00700h band_step_lut_5: DW 00050h DW 09949h DW 00000h DW 09999h DW 02000h ;;; DW 00000h band_step_lut_1: DW 00010h DW 09989h DW 00000h DW 09999h DW 02f00h ;;; DW 00000h ; ; code speed timer LUT ; ; if you think the standard word "PARIS" has 50 dits then ;#define SPEED_CONSTANT 13107 ; if you think the standard word "PARIS" has 48 dits then #define SPEED_CONSTANT 13653 sp_lut: ; DW (SPEED_CONSTANT/50) ; 50 wpm ; DW (SPEED_CONSTANT/48) ; 48 wpm ; DW (SPEED_CONSTANT/46) ; 46 wpm ; DW (SPEED_CONSTANT/44) ; 44 wpm ; DW (SPEED_CONSTANT/42) ; 42 wpm DW (SPEED_CONSTANT/40) ; 40 wpm DW (SPEED_CONSTANT/38) ; 38 wpm DW (SPEED_CONSTANT/36) ; 36 wpm DW (SPEED_CONSTANT/34) ; 34 wpm DW (SPEED_CONSTANT/32) ; 32 wpm DW (SPEED_CONSTANT/30) ; 30 wpm DW (SPEED_CONSTANT/28) ; 28 wpm DW (SPEED_CONSTANT/26) ; 26 wpm DW (SPEED_CONSTANT/24) ; 24 wpm DW (SPEED_CONSTANT/22) ; 22 wpm default_speed: DW (SPEED_CONSTANT/20) ; 20 wpm =abt 32768*1.25/3/20 probably need to fix this table.... SPEED_CONSTANT/wpm DW (SPEED_CONSTANT/18) ; 18 wpm DW (SPEED_CONSTANT/16) ; 16 wpm DW (SPEED_CONSTANT/14) ; 14 wpm DW (SPEED_CONSTANT/12) ; 12 wpm DW (SPEED_CONSTANT/10) ; 10 wpm ; DW (SPEED_CONSTANT/8) ; 8 wpm ; DW (SPEED_CONSTANT/6) ; 6 wpm sp_lut_end: ;---------------------------------------- ; decimal to morse LUT ;---------------------------------------- mlut: DW 02f03h ; '1' 't' DW 02327h ; '3' '2' DW 02021h ; '5' '4' DW 03830h ; '7' '6' DW 03e3ch ; '9' '8' ENDOFFLASH: DW 0ffffh END