; === FOXBOX2 == REV. 1.1 == 31 May 1999 ========================= ; ; File Description: ; Modifications and French-to-English Translation ; by Charles Scharlau NZ0I & Karen Scharlau N7SRO ; History ; ; Version 1.1 - January 31, 2000 ; Changes to Rev 1.0 ; - Added a one-character delay prior to sending tx ; message. This prevents cut-off of first code element ; by a slow-keying transmitter (e.g., DJ-S11). ; Version 1.0 - June 7, 1999 ; Changes to VE2JX/VE2EMM Rev 3.1a ; - Changed ID code speed from 25 WPM to 20 WPM ; - Disabled turn-off; the controller now runs forever ; without shutting down. ; - Added software revision number; it gets sent in CW just ; before "de " is sent when setting call sign. ; ; ; === FOXBOX == REV. 3.1a == Feb 10, 98 ========================= ; ; Use Microchip MPASM assembler ; ; Written by Francois Tremblay VE2JX and Jacques Brodeur VE2EMM, ; Nov. 1997. ; ; Used for Montreal Fox Controller, "Homing In" for April 1998 ; This software can be reproduced freely only to be used by ; Amateur Radio Operators and Amateur Radio Clubs. Any other ; use is prohibited. ; ;**************************************************************** ; ; Use a 4.194304 MHz XTAL ; list P=16F84 radix HEX __CONFIG _WDT_OFF&_XT_OSC&_CP_OFF&_PWRTE_ON ; ;**************************************************************** ; ; List of memory addresses ; CBLOCK 0X0C ; variables used for sending CW NU_MESSAGE CHAR_INDEX ; index into message CW_CHAR ; NBR_SPACE ; length of Morse space being sent NBR_DIT ; length of Morse element being sent CTR_NBR CTR_DIT TONE ; sets audio tone frequency PORTX ; dummy port CW_SPEED ; CW code speed ; ----------------------------------- TMPW ; holds W for restoring W after interrupt TMPS ; holds STATUS for restoring STATUS... ; ...after interrupt DIVIDE16 ;* countdown register with the value of 16 SECONDS ;* seconds count TMP_1 ; temporary storage CW_SPEED_TMP ; temporary storage for CW_SPEED CYCLE_MINUTE ;* number of current minute in TX cycle MINS_IN_CYCLE ; holds total minutes per transmit cycle TIMER ;* holds hunt duration (10-minute increments) MESSAGE ; holds the number of TX in the hunt FLAG ; Flags TX_NUMBER ; sequence number in the transmit order TMPF1 TMPF2 TEN_MIN_COUNT ;* down counter of 10-minute intervals ENDC ;* Variables changed by the timer overflow interrupt. ; ; ----------------------------------- ; Assign labels to PIC registers ; TMR0 EQU 0X01 ; timer 0 PCL EQU 0X02 ; program count STATUS EQU 0X03 ; status register FSR EQU 0X04 ; file select register PORTA EQU 0X05 ; port A PORTB EQU 0X06 ; port B EEDATA EQU 0X08 ; EEPROM data register EEADR EQU 0X09 ; EEPROM address register PCLATH EQU 0X0A ; upper 5 bits of program counter INTCON EQU 0X0B ; interrupt control register TRISA EQU 0X85 ; port A data direction register TRISB EQU 0X86 ; port B data direction register EECON1 EQU 0X88 ; EEPROM control register 1 EECON2 EQU 0X89 ; EEPROM control register 2 ; ; ---------- List of symbolic values ; RP0 EQU 0X05 ; bank bit in STATUS register W EQU 0X00 ; file register designator = W F EQU 0X01 ; file register designator = F Z EQU 0X02 ; zero flag in STATUS C EQU 0X00 ; carry flag in STATUS WREN EQU 0X02 ; EECON1 write enable bit WR EQU 0X01 ; EECON1 write bit RD EQU 0X00 ; EECON1 read bit _CP_OFF EQU 0X3FFF ; code protection off _PWRTE_ON EQU 0X3FF7 ; power up timer enable ; 16C84 = 0X3FFF; 16F84 = 3FF7 _WDT_OFF EQU 0X3FFB ; watch dog timer off _XT_OSC EQU 0X3FFD ; crystal oscillator ; ; ============================================================ ; vector table ; ORG 0X000 GOTO START ; vector to start of program ORG 0X004 GOTO TIMER0_INTERRUPT ; timer overflow interrupt vector ;**************************************************************** ; MORSE MESSAGES ;**************************************************************** ORG 0X006 ; set start address to end of vectors MESSAGE0 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; RETLW 0X00 ; word space RETLW 0X07 ; "M" RETLW 0X0F ; "O" RETLW 0X00 ; word space RETLW 0XFF ; end of message MESSAGE1 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; RETLW 0X00 ; word space RETLW 0X07 ; "M" RETLW 0X0F ; "O" RETLW 0X02 ; "E" RETLW 0XFF ; end of message MESSAGE2 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; RETLW 0X00 ; word space RETLW 0X07 ; "M" RETLW 0X0F ; "O" RETLW 0X04 ; "I" RETLW 0XFF ; end of message MESSAGE3 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; RETLW 0X00 ; word space RETLW 0X07 ; "M" RETLW 0X0F ; "O" RETLW 0X08 ; "S" RETLW 0XFF ; end of message MESSAGE4 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; RETLW 0X00 ; word space RETLW 0X07 ; "M" RETLW 0X0F ; "O" RETLW 0X10 ; "H" RETLW 0XFF ; end of message MESSAGE5 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; RETLW 0X00 ; word space RETLW 0X07 ; "M" RETLW 0X0F ; "O" RETLW 0X20 ; "5" RETLW 0XFF ; end of message MESSAGE6 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; RETLW 0X00 ; word space RETLW 0X07 ; "M" RETLW 0X0F ; "O" RETLW 0X05 ; "N" RETLW 0XFF ; end of message MESSAGE7 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; RETLW 0X00 ; word space RETLW 0X07 ; "M" RETLW 0X0F ; "O" RETLW 0X09 ; "D" RETLW 0XFF ; end of message MESSAGE8 ; EEDATA code, "Sender's CALL" MOVF CHAR_INDEX, W ; load W w/ index to next char... ; ...to send MOVWF EEADR ; load it BSF STATUS, RP0 ; bank 1 BSF EECON1, RD ; command a read BCF STATUS, RP0 ; back to bank 0 MOVF EEDATA, W ; load the read value in W RETURN MESSAGE9 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; go to it RETLW 0X09 ; "D" RETLW 0X02 ; "E" RETLW 0X00 ; word space RETLW 0XFF ; end of message MESSAGE10 MOVF CHAR_INDEX, W ; load W w/ index to next char to send ADDWF PCL, F ; go to it RETLW 0x18 ; "V" RETLW 0X02 ; "E" RETLW 0x0A ; "R" RETLW 0x3E ; "1" RETLW 0x0A ; "R" RETLW 0x3E ; "1" RETLW 0x31 ; "BT pause" RETLW 0X00 ; word space RETLW 0XFF ; end of message ;**************************************************************** ; Record call sign ;**************************************************************** ; send the software version number in Morse code MEM_CALL MOVLW D'145' ; CW speed 8 WPM MOVWF CW_SPEED MOVLW D'10' ; send the software version number CALL SEND_MSG ; ;MEM_CALL BTFSC FLAG, 7 ; proceed if FLAG.7 not set ; GOTO FLASH ; ; MOVLW D'145' ; CW speed 8 WPM ; MOVWF CW_SPEED MOVLW D'9' ; Send "DE " CALL SEND_MSG ; MOVLW 0X00 ; EEDATA starting address 0X00 MOVWF CHAR_INDEX ; memory location NEXT_LETTER BTFSC PORTA, 3 ; read enter button GOTO NEXT_LETTER ; wait for enter MOVF CHAR_INDEX, W ; load starting address MOVWF EEADR ; MOVF PORTB, W ; get CW character from switches MOVWF EEDATA ; MOVWF CW_CHAR ; save the character BSF STATUS, RP0 ; go to bank 1 BSF EECON1, WREN ; write enable MOVLW 0X55 MOVWF EECON2 MOVLW 0XAA MOVWF EECON2 BSF EECON1, WR ; write command BCF EECON1, WREN ; disable the write enable BCF STATUS, RP0 ; back to bank 1 LOOP BTFSS PORTA, 3 ; wait for switch 2 closure GOTO LOOP ; MOVF PORTB, W XORLW 0XFF ; test for EOM character SKPNZ GOTO CALL_COMPL CALL SEND_ONE_CHAR ; send CW confirmation to user INCF CHAR_INDEX, F GOTO NEXT_LETTER ; CALL_COMPL MOVLW 0X03 ; send long beep MOVWF CW_CHAR MOVWF NBR_DIT MOVLW D'255' ; 1/4 second MOVWF CW_SPEED CALL SEND_ONE_CHAR ; BSF FLAG, 7 ; set FLAG.7 FOREVER GOTO FOREVER ; finish: wait for a RESET/SYNC ;**************************************************************** ; SEND_MSG ;**************************************************************** ; Generates 80m CW and MCW output. ; RA0 = MCW ; RA1 = Keyed CW/80 meters ; ;To send a message, enter the "SEND_MSG" routine with: ; - The # of the message to be transmitted in W ; - The speed of the CW in memory "CW_SPEED" ; 5 WPM = 240, 20 WPM = 60 ; ;To send a letter, enter the "SEND_ONE_CHAR" routine with: ; - the letter to be transmitted in memory "CW_CHAR" ; - The speed of the CW in memory "CW_SPEED" ; 5 WPM = 240, 20 WPM = 60 ; ;To generate a beep, enter the "SEND_TONE" routine with: ; - 250 in "CW_SPEED" = 1/4 second beep ; - # of 1/4 sec. in "NBR_DIT" ;============================================================= SEND_MSG MOVWF NU_MESSAGE ; save message # in NU_MESSAGE CLRF CHAR_INDEX ; initialize character index GET_MSG CLRC ; get next character to send RLF NU_MESSAGE, W ; multiply message # by 2 to... ; ...get jump value ADDWF PCL, F ; jump to the selected message CALL MESSAGE0 ; get message 0: MO GOTO SEND_CW CALL MESSAGE1 ; get message 1: "MOE" GOTO SEND_CW CALL MESSAGE2 ; get message 2: "MOI" GOTO SEND_CW CALL MESSAGE3 ; get message 3: "MOS" GOTO SEND_CW CALL MESSAGE4 ; get message 4: "MOH" GOTO SEND_CW CALL MESSAGE5 ; get message 5: "MO5" GOTO SEND_CW CALL MESSAGE6 ; get message 6: "MON" GOTO SEND_CW CALL MESSAGE7 ; get message 7: "MOD" GOTO SEND_CW CALL MESSAGE8 ; get message 8: call sign in EEPROM GOTO SEND_CW CALL MESSAGE9 ; get message 9: "DE" GOTO SEND_CW CALL MESSAGE10 ; get message 10: software version # SEND_CW MOVWF CW_CHAR ; load CW_CHAR with character to be sent MOVF CW_CHAR, F ; set zero flag in STATUS register SKPNZ ; test for a word space GOTO DO_WORD_SPACE ; send a word space MOVLW 0XFF ; FF = end of message XORWF CW_CHAR, W SKPNZ ; test for the end of message RETURN ; end of message CALL SEND_ONE_CHAR ; send a character NEXT_CHAR INCF CHAR_INDEX, F ; next letter MOVLW 0X02 ; add 2 dit periods MOVWF NBR_SPACE ; total 3 dit periods CALL SEND_SPACE ; GOTO GET_MSG ; get another letter DO_WORD_SPACE MOVLW 0X04 ; add 4 dit periods MOVWF NBR_SPACE ; total 7 dit periods CALL SEND_SPACE ; GOTO NEXT_CHAR ; get another letter ; ;================================================================ ;**************************************************************** ; SEND_ONE_CHAR ;**************************************************************** ; Sends a CW character. Activates MCW tone (port A.0) and 80m CW ; output (port A.1) ; CW character to be sent must be held in CW_CHAR ; ; dit = 1 period ; dah = 3 periods ; Space between characters = 1 period ; Space between letters = 3 periods ; Space between words = 7 periods ;================================================================ SEND_ONE_CHAR CLRC ; clear carry RRF CW_CHAR, F ; rotate a code element (dit... ; ...or dah) into the carry flag MOVF CW_CHAR, F SKPNZ RETURN ; zero means character is done SKPC ; jump if dah GOTO SEND_A_DIT ; bit at 0 SEND_A_DAH MOVLW 0X03 ; 1 dah = 3 dits MOVWF NBR_DIT MOVLW 0X01 ; MOVWF NBR_SPACE ; 1 space after the dah BSF PORTA,1 ; 80 Meters CW, Key ON CALL SEND_TONE BCF PORTA,1 ; 80 Meters CW, Key OFF CALL SEND_SPACE GOTO SEND_ONE_CHAR SEND_A_DIT MOVLW 0X01 ; 1 dit MOVWF NBR_DIT MOVWF NBR_SPACE ; 1 space after the dit BSF PORTA,1 ; 80 Meters CW, Key ON CALL SEND_TONE BCF PORTA,1 ; 80 Meters CW, Key OFF CALL SEND_SPACE GOTO SEND_ONE_CHAR ; ;================================================================ ;**************************************************************** ; SEND_TONE ;**************************************************************** ; ; SEND_TONE generates the audible tone on port A.0 in multiples ; of a dit length. The length of the tone to be sent must be ; held in NBR_DIT when this routine is called. ; ; SPEED OF A CYCLE, example: generate 1000 Hz with a ; XTAL of 4.194304 MHz. One instruction cycle = ; .95 usec. (4 clocks per instruction cycle) ; Time of 1 audio cycle : 1/1000 = 0.001 second ; Time of 1/2 audio cycle : 0.001/2 = 0.0005 second ; The time required for each decrement of TONE is 3 ; instruction cycles or 2.86 useconds. ; ; The number passed to do a half audio cycle at 1000 Hz is ; 0.0005/0.00000286 = 178 ; ; The length of a DIT for a MCW of 20 WPM is 0.060 seconds ; The numbers of cycles to is 0.060/0.001 = 60 for a dit. ; "CW_SPEED" = ; MCW @ 20 WPM = 60 ; MCW @ 15 WPM = 90 ; MCW @ 10 WPM = 120 ; MCW @ 08 WPM = 150 ; MCW @ 05 WPM = 240 ; ;================================================================ SEND_TONE MOVF NBR_DIT, W ; place # of space-dits in W MOVWF CTR_NBR DIT_LENGTH MOVF CW_SPEED, W ; dit period is set by CW_SPEED MOVWF CTR_DIT ; START_CYCLE BSF PORTA,0 ; set A.0=1 for first half cycle MOVLW D'178' ; # of times thru 1st half cycle MOVWF TONE ; set the tone frequency HIGH_HALF DECFSZ TONE, F ; count down to 0 GOTO HIGH_HALF BCF PORTA,0 ; set A.0=0 for second half cycle MOVLW D'178' ; MOVWF TONE LOW_HALF DECFSZ TONE, F ; wait until 0 to finish GOTO LOW_HALF DECFSZ CTR_DIT, F ; GOTO START_CYCLE DECFSZ CTR_NBR, F GOTO DIT_LENGTH ; do next cycle RETURN ; done ; ;================================================================ ;**************************************************************** ; SEND_SPACE ;**************************************************************** ; ; SEND_SPACE sends a space (i.e., silence/port A.0 not ; activated) in multiples of a dit length. The length of the ; space to be sent must be held in NBR_DIT when this routine ; is called. ; ; This routine is similar to SEND_TONE routine, but without sound ; It activates a "virtual speaker": PORTX. The timing is kept the ; same as for SEND_TONE. ;================================================================= SEND_SPACE MOVF NBR_SPACE, W ; place # of spaces into W MOVWF CTR_NBR DIT_LENGTH_SP MOVF CW_SPEED, W ; length of a dit period MOVWF CTR_DIT START_CYCLE_SP BSF PORTX,0 ; set X.0=0 for first half cycle MOVLW D'178' ; # of times thru this half cycle MOVWF TONE ; HIGH_HALF_SP DECFSZ TONE, F ; count down to 0 GOTO HIGH_HALF_SP BCF PORTX,0 ; set X.0=0 for second half cycle MOVLW D'178' ; MOVWF TONE LOW_HALF_SP DECFSZ TONE, F ; wait until 0 to finish GOTO LOW_HALF_SP DECFSZ CTR_DIT, F ; GOTO START_CYCLE_SP DECFSZ CTR_NBR, F GOTO DIT_LENGTH_SP ; do one more cycle RETURN ; done ; ;================================================================ ;**************************************************************** ; TIMER 0 Interrupt service routine ;**************************************************************** ; This interrupt occurs every time timer 0 overflows from ; 11111111 to 00000000. Since the timer zero prescaler is ; in effect, and set to divide the timer 0 input clock by ; 256, a timer overflow occurs every 256 * 256 = 65536 ; instruction cycles. One instruction cycle is 4 crystal ; oscillator clock cycles. So this interrupt occurs every ; 65535 * 4 = 262144 crystal oscillator cycles. ; ; With a 4.194304 MHz crystal the timer 0 interrupt period ; is 262144 / 4194304 = 0.0625 seconds, or 16 times a ; second. TIMER0_INTERRUPT MOVWF TMPW ; save contents of W SWAPF STATUS, W ; move STATUS into W MOVWF TMPS ; save STATUS in TMPS ;----------------------------------- DECFSZ DIVIDE16, F ; 16 interrupts = second GOTO POP ; not yet 1 second jump to POP MOVLW D'16' ; set W to 16 MOVWF DIVIDE16 ; re-initialize counter ;----------------------------------- DECFSZ SECONDS, F ; decrement seconds counter GOTO POP ; not yet 60 seconds jump to POP MOVLW D'60' ; re-initialize seconds counter MOVWF SECONDS DECFSZ TEN_MIN_COUNT ; decrement 10-minute counter GOTO DO_MIN MOVLW D'10' MOVWF TEN_MIN_COUNT ;----------------------------------- DECF TIMER, F ; count down hunt time in... ; ...10-minute increments SKPNZ BSF FLAG, 0 ; TIMER=0: set end-of-hunt flag DO_MIN INCF CYCLE_MINUTE, F ; minute of the transmit cycle... BSF FLAG,1 ; ...from 1 to MINS_IN_CYCLE MOVF CYCLE_MINUTE, W ; SUBWF MINS_IN_CYCLE, W ; compare current minute with... SKPZ ; ...number of minutes in a cycle GOTO POP MOVLW D'1' MOVWF CYCLE_MINUTE ; reset current minute count to 1 POP BCF INTCON, 2 ; reset TMR0 interrupt flag SWAPF TMPS, W ; restore W, STATUS, and F to... ; ...their pre-interrupt values MOVWF STATUS ; SWAPF TMPW, F ; SWAPF TMPW, W ; RETFIE ; return from interrupt ; ;================================================================ ;**************************************************************** ; Start of main program ;**************************************************************** START MOVLW B'00000111' OPTION ; load option register: ; bit 0 = 1 prescale by 256 ; bit 1 = 1 " ; bit 2 = 1 " ; bit 3 = 0 TMR0 use internal clk ; bit 4 n/a ; bit 5 = 0 timer mode ; bit 6 n/a ; bit 7 = 0 enable port B pullups CLRF PORTA ; clear port A CLRF PORTB ; clear port B MOVLW B'00011000' ; 1=input pin, 0=output pin TRIS PORTA ; initialize port A MOVLW B'11111111' ; port B is all inputs TRIS PORTB ; initialize port B ; ; check for the presence of jumper JP1 ; BTFSC PORTA, 3 ; see if the jumper is present GOTO MEM_CALL ; no jumper=change the call sign MOVLW D'1' MOVWF PCLATH GOTO FOX_CONTROL ; jumper is there=run fox hunt ; ; ; assembly instructions for controlling fox transmitter ; ; ORG 0X10A ; why was this address being set? FOX_CONTROL CLRF TMR0 ; CLRWDT ; CLRF INTCON ; BSF INTCON,7 ; enable interrupts BSF INTCON,5 ; enable TMR0 ovrflw interrupts MOVLW D'16' ; MOVWF DIVIDE16 ; generate seconds MOVLW D'60' ; MOVWF SECONDS ; generate minutes MOVLW D'10' ; 10-minute counter MOVWF TEN_MIN_COUNT CLRF FLAG ;--------------------------------------------------------------- CALL READ_SWITCHES ; read DIP switches TSTF TIMER ; if TIMER is zero start the hunt SKPZ CALL DELAYED_TIME ; wait until start of hunt ; MOVLW D'24' ; total hunt time... MOVLW D'96' ; ...in 10-minute increments ; 4 HOURS = 24, 8 HOURS = 48; ; 16 HOURS = 96 MOVWF TIMER ; do not set hunt time to zero CALL DO_TXCYCLE ; start hunt transmit cycles BCF INTCON,7 ; disable all interrupts SLEEP ; sleep (low-power wait state) NOP ; ;================================================================ ;**************************************************************** ; Subroutines ;**************************************************************** ; ; read switches 3-2-1 for the delay time ; READ_SWITCHES MOVF PORTB, W ; ANDLW B'00000111' ; mask off switches 3-2-1 CALL DELAY_START MOVWF TIMER GOTO SW4 ; read next switches ;**************************************************************** ; delay before start of the hunt ;**************************************************************** DELAY_START ADDWF PCL, F ; jump table indexed by W RETLW D'0' ; start now if all switches read 0 RETLW D'3' ; 30-minute delay if switches = 1 RETLW D'6' ; 60-minute delay if switches = 2 RETLW D'9' ; 90-minute delay if switches = 3 RETLW D'12' ; 120-minute delay if switches = 4 RETLW D'15' ; 150-minute delay if switches = 5 RETLW D'18' ; 180-minute delay if switches = 6 RETLW D'21' ; 210-minute delay if switches = 7 ;================================================================ ;**************************************************************** ; read switches 6-5-4 for transmit message and # of transmitters ;**************************************************************** ; SW4 MOVF PORTB, W ANDLW B'00111000' ; read switches 6-5-4 MOVWF TMP_1 CLRC ; clear carry RRF TMP_1, F RRF TMP_1, F RRF TMP_1, F MOVF TMP_1, W ; load W with value of switches 6-5-4 CALL TX_MESSAGE MOVWF MESSAGE ; save transmit message in MESSAGE MOVF TMP_1, W CALL TIME_CYCLE MOVWF TX_NUMBER ; save position of transmitter... ; ...in transmission cycle GOTO SW7 ; read next switches ;**************************************************************** ; transmit message ;**************************************************************** TX_MESSAGE ADDWF PCL, F ; jump table indexed by W RETLW D'0' ; MO RETLW D'1' ; MOE RETLW D'2' ; MOI RETLW D'3' ; MOS RETLW D'4' ; MOH RETLW D'5' ; MO5 RETLW D'6' ; MON RETLW D'7' ; MOD ;================================================================ ;**************************************************************** ; transmitter # and time to wait before repeating transmission ;**************************************************************** TIME_CYCLE ADDWF PCL, F ; jump table indexed by W RETLW D'1' ; 1 minute in cycle / transmitter 0 RETLW D'1' ; 1 minute in cycle / transmitter 1 RETLW D'2' ; 2 minutes in cycle / transmitter 2 RETLW D'3' ; 3 minutes in cycle / transmitter 3 RETLW D'4' ; 4 minutes in cycle / transmitter 4 RETLW D'5' ; 5 minutes in cycle / transmitter 5 RETLW D'6' ; 6 minutes in cycle / transmitter 6 RETLW D'7' ; 7 minutes in cycle / transmitter 7 ;================================================================ ;**************************************************************** ; read switches 9-8-7 for cycle time for repeating fox message ;**************************************************************** SW7 CLRF TMP_1 BTFSS PORTB,6 GOTO SW8 BSF TMP_1,0 SW8 BTFSS PORTB,7 GOTO SW9 BSF TMP_1,1 SW9 BTFSS PORTA,4 GOTO TX_CYCLE BSF TMP_1, 2 TX_CYCLE MOVF TMP_1, W CALL TIME_CYCLE ADDLW D'1' MOVWF MINS_IN_CYCLE ; minutes in the transmit cycle MOVF MINS_IN_CYCLE, W ; is TX # > minutes in cycle? SUBWF TX_NUMBER, W BTFSC STATUS,C CALL ALARM ; if yes, signal trouble (more... ; ...foxes than minutes!) RETURN ;================================================================ ;**************************************************************** ; alarm routine ;**************************************************************** ALARM MOVF DIVIDE16, W ; flash the LED ANDLW B'00000010' SKPZ BSF PORTA,1 SKPNZ BCF PORTA,1 GOTO ALARM ; ;================================================================ ;**************************************************************** ; delay prior to hunt ;**************************************************************** DELAYED_TIME BCF FLAG,0 REDO_WAIT MOVF DIVIDE16, W ANDLW B'0001111' SKPNZ BSF PORTA,1 ; blink LED to show the timer is running SKPZ BCF PORTA,1 BTFSS FLAG,0 ; check whether time has expired GOTO REDO_WAIT ; BCF PORTA,1 ; finish with the LED extinguished RETURN ; ;================================================================ ;**************************************************************** ; send transmitter message MOx for one minute ;**************************************************************** DO_TXCYCLE MOVLW D'1' ; init CYCLE_MINUTE to min #1 MOVWF CYCLE_MINUTE CLRF FLAG ; ; wait for the right minute to transmit ; WAIT_UR_TURN BCF FLAG, 2 MOVF CYCLE_MINUTE, W ; put current cycle minute into W XORWF TX_NUMBER, W ; compare W with transmit... ; ...sequence number SKPZ BSF FLAG, 2 ; Note: if the following two lines are commented out then the ; fox controller will send its transmit message forever, never ; automatically shutting down. To enable automatic shutdown be ; sure the following two lines are *not* commented out. ; BTFSC FLAG,0 ; check whether the hunt is finished ; RETURN ; end the hunt BTFSC FLAG, 2 GOTO WAIT_UR_TURN ; ;**************************************************************** ; 1-minute transmission ;**************************************************************** ; BCF FLAG,1 ; reset transmission minute done flag BSF PORTA, 2 ; turn on transmitter MOVLW D'145' ; 8 WPM MOVWF CW_SPEED MOVLW 0X00 MOVWF PCLATH ; page 0 MOVF MESSAGE, W ; send message at the start of the cycle CALL SEND_MSG SEC54 MOVF SECONDS, W ; send message at 6 sec. into the cycle XORLW D'54' SKPZ GOTO SEC54 MOVF MESSAGE, W CALL SEND_MSG SEC48 MOVF SECONDS, W XORLW D'48' ; send message at 12 sec. into the cycle SKPZ GOTO SEC48 MOVF MESSAGE, W CALL SEND_MSG SEC42 MOVF SECONDS, W ; send message at 18 sec. into the cycle XORLW D'42' SKPZ GOTO SEC42 MOVF MESSAGE, W CALL SEND_MSG SEC36 MOVF SECONDS, W ; send message at 24 sec. into the cycle XORLW D'36' SKPZ GOTO SEC36 MOVF MESSAGE, W CALL SEND_MSG SEC30 MOVF SECONDS, W ; send message at 30 sec. into the cycle XORLW D'30' SKPZ GOTO SEC30 MOVF MESSAGE, W CALL SEND_MSG SEC24 MOVF SECONDS, W ; send message at 36 sec. into the cycle XORLW D'24' SKPZ GOTO SEC24 MOVF MESSAGE, W CALL SEND_MSG SEC18 MOVF SECONDS, W ; send message at 42 sec. into the cycle XORLW D'18' SKPZ GOTO SEC18 MOVF MESSAGE, W CALL SEND_MSG SEC12 MOVF SECONDS, W ; send message at 48 sec. into the cycle XORLW D'12' SKPZ GOTO SEC12 MOVF MESSAGE, W CALL SEND_MSG SEC6 MOVF SECONDS, W ; send call sign at 54 sec... ; ...into the cycle XORLW D'6' SKPZ GOTO SEC6 ; MOVLW D'45' ; send the call sign at 25 WPM MOVLW D'60' ; send the call sign at 20 WPM MOVWF CW_SPEED MOVLW D'9' ; send "DE " CALL SEND_MSG MOVLW D'8' ; send call sign CALL SEND_MSG MOVLW D'1' ; back to page number 1 MOVWF PCLATH ; WAIT_TX_DONE BTFSS FLAG,1 ; wait for end of the 1-minute... ; ...transmission GOTO WAIT_TX_DONE BCF PORTA, 2 GOTO WAIT_UR_TURN ; ;**************************************************************** ; ;**************************************************************** ; ORG 0X0200 ; why was this address being set? ; ;FLASH BSF PORTA,1 ; CALL LOOP_BEGIN ; BCF PORTA,1 ; CALL LOOP_BEGIN ; GOTO FLASH ; ;LOOP_BEGIN MOVLW 0XFF ; MOVWF TMPF1 ; MOVWF TMPF2 ; ;LOOP_WAIT DECFSZ TMPF1, F ; GOTO LOOP_WAIT ; MOVLW 0XFF ; MOVWF TMPW ; DECFSZ TMPF2, F ; GOTO LOOP_WAIT ; RETURN ; ;--- EEDATA ----------------------------------------------------- ; ; Default setting of EEDATA memory ; ORG 0X2100 ; start address of the EEDATA DE 0x14 ; "F" call sign, EEDATA ADR. 0X00 DE 0x0F ; "O" DE 0x19 ; "X" DE 0x11 ; "B" DE 0x0F ; "O" DE 0x19 ; "X" DE 0XFF ; end of message END ; ; THE END ; ;================================================================= ; ; MORSE ENCODING ; ; One Morse character per BYTE, bitwise, LSB to MSB. ; ; 0 = dit, 1 = dah. The byte is shifted to the right bit ; by bit, until the last 1 is left, this 1 is an end of ; character indicator. A maximum of 7 Morse code elements ; can be encoded. Thus the error symbol (8 dits) is not ; supported. ; ; SEND_MSG MSB LSB assembly to copy ; ----------- --- --- --------------------------------- ; KN -.--. 00101101 RETLW 0x2D ; "KN go only" ; SK ...-.- 01101000 RETLW 0x58 ; "SK clear" ; AR .-.-. 00101010 RETLW 0x2A ; "AR over" ; BT -...- 00110001 RETLW 0x31 ; "BT pause" ; AS .-... 00100010 RETLW 0x22 ; "AS stand by" ; ? ..--.. 01001100 RETLW 0x49 ; "?" ; / -..-. 00101001 RETLW 0x29 ; "/" ; 0 ----- 00111111 RETLW 0x3F ; "0" ; 1 .---- 00111110 RETLW 0x3E ; "1" ; 2 ..--- 00111100 RETLW 0x3C ; "2" ; 3 ...-- 00111000 RETLW 0x38 ; "3" ; 4 ....- 00110000 RETLW 0x30 ; "4" ; 5 ..... 00100000 RETLW 0x20 ; "5" ; 6 -.... 00100001 RETLW 0x21 ; "6" ; 7 --... 00100011 RETLW 0x23 ; "7" ; 8 ---.. 00100111 RETLW 0x27 ; "8" ; 9 ----. 00101111 RETLW 0x2F ; "9" ; A .- 00000110 RETLW 0x06 ; "A" ; B -... 00010001 RETLW 0x11 ; "B" ; C -.-. 00010101 RETLW 0x15 ; "C" ; D -.. 00001001 RETLW 0x09 ; "D" ; E . 00000010 RETLW 0x02 ; "E" ; F ..-. 00010100 RETLW 0x14 ; "F" ; G --. 00001011 RETLW 0x0B ; "G" ; H .... 00010000 RETLW 0x10 ; "H" ; I .. 00000100 RETLW 0x04 ; "I" ; J .--- 00011110 RETLW 0x1E ; "J" ; K -.- 00001101 RETLW 0x0D ; "K" ; L .-.. 00010010 RETLW 0x12 ; "L" ; M -- 00000111 RETLW 0x07 ; "M" ; N -. 00000101 RETLW 0x05 ; "N" ; O --- 00001111 RETLW 0x0F ; "O" ; P .--. 00010110 RETLW 0x16 ; "P" ; Q --.- 00011011 RETLW 0x1B ; "Q" ; R .-. 00001010 RETLW 0x0A ; "R" ; S ... 00001000 RETLW 0x08 ; "S" ; T - 00000011 RETLW 0x03 ; "T" ; U ..- 00001100 RETLW 0x0C ; "U" ; V ...- 00011000 RETLW 0x18 ; "V" ; W .-- 00001110 RETLW 0x0E ; "W" ; X -..- 00011001 RETLW 0x19 ; "X" ; Y -.-- 00011101 RETLW 0x1D ; "Y" ; Z --.. 00010011 RETLW 0x13 ; "Z" ; SPACE 00000000 RETLW 0x00 ; "word space" ; EOM 11111111 RETLW 0xFF ; "end of message" ; ; ;======================================================= ; ; DIP SWITCH TIMING CONTROL SETTINGS ; ; The settings of the DIP switches at reset (or power up) ; determine the transmit cycle time, transmit ; message (and order), and whether there is any delay ; before the hunt is to begin. ; ; Set the DIP switches as follows: ; ; switches 9-8-7: (Number of transmitters) ; ; 0 0 0 send continuously (i.e., 1 transmitter) ; 0 0 1 send continuously (i.e., 1 transmitter) ; 0 1 0 2-minute cycle (i.e., 2 transmitters) ; 0 1 1 3-minute cycle (i.e., 3 transmitters) ; 1 0 0 4-minute cycle (i.e., 4 transmitters) ; 1 0 1 5-minute cycle (i.e., 5 transmitters) ; 1 1 0 6-minute cycle (i.e., 6 transmitters) ; 1 1 1 7-minute cycle (i.e., 7 transmitters) ; ; switches 6-5-4 (Message & transmit order) ; ; 0 0 0 send "MO" continuously ; 0 0 1 send "MOE" in 1st minute or continuously ; 0 1 0 send "MOI" in 2nd minute ; 0 1 1 send "MOS" in 3rd minute ; 1 0 0 send "MOH" in 4th minute ; 1 0 1 send "MO5" in 5th minute ; 1 1 0 send "MON" in 6th minute ; 1 1 1 send "MOD" in 7th minute ; ; switches 3-2-1 (Pre-hunt delay) ; ; 0 0 0 no delay = start transmitting immediately ; 0 0 1 30 minute delay ; 0 1 0 60 minute delay ; 0 1 1 90 minute delay ; 1 0 0 120 minute delay ; 1 0 1 150 minute delay ; 1 1 0 180 minute delay ; 1 1 1 210 minute delay