

' FILE NAME: StnPro_code_8/11/2009.bs2
' Written by Jim Garland W8ZR      w8zr@arrl.net
' Program may be freely copied or modified (for non-commercial use only).

' {$STAMP BS2}    BS2 Stamp directive - required statement
' {$PBASIC 2.5}   Enable PBASIC v.2.5 enhanced features

' ====================================================================================
'   Program controls Station Pro II. After initialization, display shows 2 sec flash screen
'   and then defaults to the prior transceiver selection. No amplifier is selected at initial
'   startup. The program then scans the front panel switches and selects the appropriate
'   transceiver, amplifier, or other function, while the LCD shows the selected choices. A selected
'   amplifier can be bypassed by pressing its selection lever a second time. Other features include an
'   tuneup pulser to assist amplifier tuning; a memory "swap" feature, which allows the
'   previously selected transceivers and amplifiers to be conveniently recalled,and an elapsed
'   time monitor, which provides a ten minute ID reminder. The ID reminder can be a one-time-only or
'   a repeating reminder. If the timer button is pressed at power-on, then the display shows
'   an "odometer" of the accumulated hours & minutes the Station Pro II has been used.
'   Up to three Station Pro IIs can be networked together, allowing a
'   total of nine transceivers and nine amplifiers to be controlled. When any selection lever on
'   a networked Station Pro II is pressed, the other Station Pro IIs automatically go off-line.
'   Miscellaneous other program features: (1)If "Swap" is pressed after startup, but before
'   selecting an amplifier, then only the transceiver will be swapped. (2)Pressing "Amp Tune"
'   starts the amplifier pulser,which times out in 10 sec with a confirming beep. Pressing
'   "Amp Tune" before it times out cancels the pulser; a flashing red LED shows
'   the pulser is on.(3) The user can easily customize the display to show
'   a user's actual transceiver and amplifier models. (4) Two microphones are selectable from
'   the front panel, with the mic jacks easily changed and configured for different kinds
'   of microphones. (4) A built-in amplifier keying circuit allows transceivers to control virtually
'   any commercial amplifer keying relay, up to 400V AC or DC of either polarity. The keying
'   circuit does not use a mechanical relay, so it is fast enough for QSK use. (5) Jacks on the rear
'   panel are available for switching RF relays for transferring antennas, switching in amplifiers, etc.

'=====================================================+===============================
'   Port Definitions & INPUT/OUTPUT Status


'     P0    TRX1SW  IN    TRX1 select button
'                   OUT   TRX1 LED

'     P1    TRX2SW  IN    TRX2 select button
'                   OUT   TRX2 LED

'     P2    TRX3SW  IN    TRX3 select button
'                   OUT   TRX3 LED

'     P3    AMP1SW  IN    AMP1 select button
'                   OUT   AMP1 LED

'     P4    AMP2SW  IN    AMP2 select button
'                   OUT   AMP2 LED

'     P5    AMP3SW  IN    AMP3 select button
'                   OUT   AMP3 LED

'     P6    SWAPSW  IN    swap current & prev. TRX & AMP selection
'           BEEP    OUT   beep out TO speaker

'     P7    TUNUPSW IN    amp 2-tone/pulser select switch
'                   OUT   2-tone/pulser LED (blinks on pulser)

'     P8    ELAPSW  IN    elapsed time switch
'                   OUT   2-tone/pulser audio TO Mic+

'     P9    REMOUT  OUT   relay control TO remote IN/OUT Jacks
'
'     P10   REMSNSE IN    READ on-line pulse from remote stns.
'                   OUT   WRITE on-line pulse from local stn.

'     P11   RLYENA  OUT   enable TRX & AMP relays

'     P12   AMPADD1 OUT   amplifer select address Bit 1

'     P13   AMPADD2 OUT   amplifier select address Bit 2

'     P14   TRXADD1 OUT   transceiver select address Bit 1

'     P15   TRXADD2 OUT   transceiver select address Bit 2

'     SOUT  SOUT    OUT   serial data out to program port
'           LCDDATA OUT   serial data out to LCD

'=====================================================================================

'   SYMBOL TABLE

'   ========================
'   OWNER SUPPLIED DATA -- enter station equipment and fill out with spaces to
'   make all descriptions exactly 15 characters. Note that quotation marks around
'   each description are required
      DATA @$030,  "Amplifier 1    "   'Enter AMP1 Info in quotes
      DATA @$040,  "Amplifier 2    "   'Enter AMP2 Info in quotes
      DATA @$050,  "Amplifier 3    "   'Enter AMP3 Info in quotes
      DATA @$060,  "Transceiver 1  "   'Enter TRX1 Info in quotes
      DATA @$070,  "Transceiver 2  "   'Enter TRX2 Info in quotes
      DATA @$080,  "Transceiver 3  "   'Enter TRX3 Info in quotes
'   ==================================================================================
      DATA @$090,  "   AMP BYPASS  "   'Do not change this line
      DATA @$0A0,  "  ** NO AMP ** "   'Do not change this line
      DATA @$0B0,  " ** OFF LINE **"   'Do not change this line
'   ==================================================================================
'    OTHER READ/WRITE DATA IN EEPROM -- preload to 0
     DATA  @$000,0 'preloads $000-$00F with 0
'             memory locations of stored variables
'                  $000  trx
'                  $001  oldtrx
'                  $002  mins
'                  $003  hrs.LOWBYTE
'                  $004  hrs.LOWBYTE
'   ==================================================================================
'   SYMBOL TABLE
      bpflag     VAR   Bit      'bypass flag =1 when amp bypassed
      startflag  VAR   Bit      'startup flag =1 at startup, 0 thereafter
      timerflag  VAR   Bit      'timerflag=1 when elapsed time mode engaged, 0 otherwise
      autoflag   VAR   Bit      'timer auto flag = 1 when 10 min timer in autorepeat mode
      remflag    VAR   Bit      'remflag=1 if controller is off-line
'-----------------------------------------------------------------
      trx        VAR   Nib      'values 0=trx1, 1=trx2, 2=trx3
      amp        VAR   Nib      'values 3=amp1, 4=amp2, 5=amp3
      oldtrx     VAR   Nib      'previous value of trx
      oldamp     VAR   Nib      'previous value of amp
'-----------------------------------------------------------------
      btnwk0     VAR   Byte     'TRX1 button variable
      btnwk1     VAR   Byte     'TRX2 button variable
      btnwk2     VAR   Byte     'TRX3 button variable
      btnwk3     VAR   Byte     'AMP1 button variable
      btnwk4     VAR   Byte     'AMP2 button variable
      btnwk5     VAR   Byte     'AMP3 button variable
      btnwk6     VAR   Byte     'SWAP button variable
      btnwk7     VAR   Byte     'AMP TUNE button variable
      btnwk8     VAR   Byte     'ELAPSED TIME button variable
      mins0      VAR   Byte     'ten minute timer variabale
      mins       VAR   Byte     'long term minutes variable,mod 10
      add        VAR   Byte     'trx and amp data address
      x          VAR   Byte     'gen purpose counter
      '----------------------------------------------------------------
      hrs        VAR   Word     'long term hours variable
      m          VAR   Word     'minutes counter variable
  '----------------------------------------------------------------

      N24        CON   $418C    'LCD 2400 baud
      I          CON   254      'LCD instruction toggle
      CLR        CON   1        'LCD clear display
      cal0       CON   1946     'calibration constant: 1 minute LOOP COUNT, bpflag=0
      cal1       CON   370      'calibration constant: 1 minute loop count, bpflag=1

    DIRS=%1111100000000000      'P0-P10 set to input, P11-P15 set to output
'======================================================================================
'      PROGRAM BEGINS HERE

'Read input data, initialize LCD, display flash screen, set startup flag
   IF IN3=0 THEN GOSUB resettime 'resets timer to zero if AMP1 button pressed at startup
   READ $003,hrs.LOWBYTE    'set hrs to previous stored value
   READ $004,hrs.HIGHBYTE
   READ $002,mins           'set mins to previous stored value (=10,20,30,etc.)
   READ $000,trx            'read TRX and prior trx selection at previous powerdown
   READ $001,oldtrx
   GOSUB CWSP               'Send "SP" CW startup msg while LCD wakes up
   SEROUT 16,N24,[I,CLR]    'clear LCD
   IF IN8=0 THEN GOSUB elapsetme    'display hrs, mins if timer button pressed at pwr-on
   SEROUT 16,N24,["  StationPro II ",I,194,"Rev. 8-11-09"] 'display flash screen on LCD
   PAUSE 2000               'wait 2 secs and
   GOSUB beeplong           'send three-tone beep
   SEROUT 16,N24,[I,CLR]    'clear LCD
   HIGH 11                  'disable relays
   startflag=1              'set startflag to startup value = 1
   GOTO rempulse            'pulae P10 to grab conrol
'================================Main Body of Program Follows==========================

startup:

          ON trx GOSUB trx1sel,trx2sel,trx3sel   'recall TRX (trx=0 calls trx1sel, etc.)

'the following sets "NO AMP" mode and then scans buttons
          LOW 9               'grab control by enabling remote relay port
          HIGH 12              'set ampadd1 and ampadd2 to bypass mode
          HIGH 13
          LOW 11               'enable relays
          SEROUT 16,N24,[I,2]  'move cursor to beginning of first line
          add=$0A0             'address of "** NO AMP ** " string
          GOSUB stringout      'send "** NO AMP **" to LCD
          GOTO rd_buttons

'======================================================================================
 ' rd_buttons scans the buttons. A subtlety is that each port (P0 through P7) is used
 ' both as an input port and an output port. As the program loops, the "low trx" and "low
 ' amp" commands change the specified port to output and light the LED. The BUTTON
 ' command then changes it back to input. The duty cycle is increased by
 ' "PAUSE 20" command, which increases the brightness of the LED.

rd_buttons:       'note that button command automatically changes its port to INPUT mode
      IF IN10=0 AND remflag=0 THEN Offline            'go off-line if on-line and remote pulse detected
      GOSUB loopcnt                     '10min counter, convert loops to mins, hrs
      BUTTON 0,0,255,0,btnwk0,1,trx1    'trx1 button
      BUTTON 1,0,255,0,btnwk1,1,trx2    'trx2 button
      BUTTON 2,0,255,0,btnwk2,1,trx3    'trx3 button
      BUTTON 3,0,255,0,btnwk3,1,amp1    'amp1 button
      BUTTON 4,0,255,0,btnwk4,1,amp2    'amp2 button
      BUTTON 5,0,255,0,btnwk5,1,amp3    'amp3 button
      BUTTON 6,0,255,0,btnwk6,1,swap    'swap button
      BUTTON 7,0,255,0,btnwk7,1,tuneup  'amp tuneup button
      BUTTON 8,0,10,255,btnwk8,1,timer  'elapsed time button (two functions)
      IF remflag=1 THEN jmp1            'don't turn on LEDs if offline
      LOW trx                           'change trx port to OUTPUT mode,light TRX LED
      IF startflag=1 THEN jmp1          'do not light amp LED if startflag=1
      IF bpflag=1 THEN blinkled         'go to amp bypass mode and blink selected amplifier LED
      LOW amp                           'amp port to output,light LED (unless in bypass mode)
 jmp1:PAUSE 20                          'pause 20msec to increase LED duty cycle
      GOTO rd_buttons                   'loop

'======================================================================================
    trx1:
      IF remflag=1 THEN rempulse   'jf off-line send pulse to remote port to grab control
      oldtrx=trx             'updtate oldtrx
      trx=0                  'new TRX
      GOSUB store_data:      'store trx
      GOSUB trx1sel          'select trx1
      GOTO rd_buttons

    trx2:
      IF remflag=1 THEN rempulse   'send pulse to remote port to grab control
      oldtrx=trx             'updtate oldtrx
      trx=1                  'new TRX
      GOSUB store_data       'store trx
      GOSUB trx2sel          'select trx2
      GOTO rd_buttons

    trx3:
      IF remflag=1 THEN rempulse   'send pulse to remote port to grab control
      oldtrx=trx            'updtate oldtrx
      trx=2                 'new TRX
      GOSUB store_data:     'store trx
      GOSUB trx3sel         'select trx3
      GOTO rd_buttons


    amp1:
      IF remflag=1 THEN rempulse    'send pulse to remote port to grab control
      startflag=0               'exit startup mode
      IF bpflag=1 THEN amp11    'if already in bypass mode, then exit
      IF amp=3 THEN ampbypass   'if not already in bypass mode, then enter it

    amp11: GOSUB amp1sel        'select amp1
           bpflag=0             'exit bypass mode
           GOTO rd_buttons


    amp2:
      IF remflag=1 THEN rempulse    'send pulse to remote port to grab control
      startflag=0               'exit startup mode
      IF bpflag=1 THEN amp21    'if already in bypass mode, then exit
      IF amp=4 THEN ampbypass   'if not alreadyin bypass mode, then enter it

    amp21: GOSUB amp2sel        'select amp2
          bpflag=0              'exit bypass mode
          GOTO rd_buttons


    amp3:
      IF remflag=1 THEN rempulse   'send pulse to remote port to grab control
      startflag=0               'exit startup mode
      IF bpflag=1 THEN amp31    'If already in bypass mode, then exit
      IF amp=5 THEN ampbypass   'if not already in bypass mode, then enter it

    amp31: GOSUB amp3sel        'select amp3
           bpflag=0             'exit bypass mode
           GOTO rd_buttons
'======================================================================================
    swap:
      IF remflag=1 THEN Offline            'skip if off-line
      BRANCH oldtrx,[trx1swap,trx2swap,trx3swap]   'if oldtrx=0 then trx1swap, etc.

          trx1swap:
            oldtrx=trx    'updtate oldtrx and trx
            trx=0
            GOSUB trx1sel
            GOTO ampswap

          trx2swap:
            oldtrx=trx    'updtate oldtrx and trx
            trx=1
            GOSUB trx2sel
            GOTO ampswap

          trx3swap:
            oldtrx=trx    'updtate oldtrx and trx
            trx=2
            GOSUB trx3sel
            GOTO ampswap

      ampswap:
          GOSUB store_data                           'store TRX data (doesn't store AMP data)
          bpflag=0                                   'cancel bypass mode
          IF startflag=1 THEN rd_buttons             'skip amp swap if startflag=1
          ON oldamp-3 GOSUB amp1sel,amp2sel,amp3sel  'if oldamp=3 then call amp1swap,etc.
          GOTO rd_buttons                            'and then scan buttons

'======================================================================================

    tuneup:                     'Send tuneup tone bursts to microphone input for 10 secs
          IF remflag=1 THEN Offline            'skip if off-line
          GOSUB tuneup1
          GOTO rd_buttons       'scan buttons when through

               tuneup1:
                 OUTPUT 7                       'change tuneup button (P7) to output
                 GOSUB beep                     'mark start of pulse tones
                 FOR x = 1 TO 100               'output 50msec 1000Hz bursts to Mic for 10sec
                 IF IN10=0 THEN offline         'exit and go offline if another controller grabs control
                 FREQOUT 8,50,1000
                 LOW 7                          'turn on LED for 50 msec, each loop
                 PAUSE 50
                 BUTTON 7,0,255,1,btnwk0,1,exittune 'set P7 to input, exit tuneup if pressed
                 NEXT

              exittune:
                 HIGH 7                          'leave P7 HIGH
                 GOSUB beeplong                  'mark end of pulse tones
                 RETURN

'======================================================================================
' Toggle timer flag bit on/off, send audible cw confirmation, and
' display "*" (single mode) or "#" (auto repeat mode)on LCD when 10min timer enabled.

    timer:
       IF remflag=1 THEN Offline            'skip if off-line
       mins0=0                           'reset timer minutes variable
       SEROUT 16,N24,[I,207]             'move cursor TO END of second line
       IF btnwk8=255 AND timerflag=1 THEN GOTO autorepeat
       ON timerflag GOSUB timer1,timer2  'test timerflag=0 or 1 and branch
       GOTO rd_buttons                   'scan buttons when done

         timer1:                      'if timerflag is off (=0)
                 timerflag=1          'toggle timerflag bit on
                 SEROUT 16,N24,["*"]  'display "*" on LCD if timer enabled
                 GOSUB CWID           'send ID in cw
                 RETURN

         timer2:                       'if timerflag is on (=1)
                 timerflag=0           'toggle timerflag bit off
                 autoflag=0            'toggle autoflag bit off
                 SEROUT 16,N24,[" "]   'blank LCD timer indication
                 GOSUB CWK             'send K in cw
                 RETURN

         autorepeat: autoflag=1        'set ten minute timer flag to auto repeat
                 GOSUB beep         'confirm with beep
                 SEROUT 16,N24,["#"]  'display "#" on LCD to indicate automatic repeat mode
                 GOTO rd_buttons

' Note: this subroutine checks status of Elapsed Time button, P8. The button loop counter
' btnwk8=10 when the button is pressed briefly. With a brief press, the routine toggles
' the timerflag, indicates the timer on/off status on the LCD, and sends "ID" in CW
' to show timer is on. If the button is held down, the button status is checked again
' after a delay. Now, the loop counter btnwk8=255, and the autorepeat flag is set to
' autoflag=1. The auto timer status is confirmed with a (2kHz) beep and a different
' character (#) on the LCD.  Either the auto timer mode or single timer mode can be
' cancelled with a brief button press.

'=====================================================================================



 ' Count program loops as the buttons are scanned and keep track of the
 ' elapsed minutes and hours. If timerflag=1, then send cw "ID"
 ' after 10 minutes, blank the LCD timer indicator, and turn off timer flag.
 ' Note that CAL1 and CAL0 adjust for the different loop transit times,
 ' depending on whether the controller is in amplifier bypass mode or not.

 loopcnt:
      m=m+1                                      'increment m for each loop
      IF bpflag=1 AND m=cal1 THEN GOSUB loopcnt1 'branch IF amp bypass mode is enabled
      IF m=cal0 THEN GOSUB loopcnt1              'cal0 loops = 1 min with bpflag=0
      RETURN

      loopcnt1:
              m=0                              'reset m=0 after 1 minute
              mins=mins+1                      'increment minutes
 '            GOSUB beep                      'UNCOMMENT for 1 min beeps to adjust cal0 & cal1
              IF mins//10=0 THEN GOSUB strmins 'store mins in ten minute blocks
              mins0=mins0+1                    'increment timer minutes
              IF timerflag=1 AND mins0//10=0 THEN GOSUB IDtimer 'branch every 10 mins
              RETURN

                strmins:
                  IF mins=60 THEN GOSUB addhrs
                  WRITE $002,mins              'update mins (ten minute blocks)
                  RETURN

                addhrs:
                  mins=0                      'reset mins
                  hrs=hrs+1                   'update hrs
                  WRITE $003, hrs.LOWBYTE     'and store
                  WRITE $004, hrs.HIGHBYTE
                  RETURN


    IDtimer:  GOSUB CWID                         'send "ID" in cw (after ten minutes)
              IF autoflag=0 THEN GOSUB IDtimer1  'branch if auto repeat mode is off
              RETURN

                IDtimer1:
                    timerflag=0                  'turn off timer flag
                    SEROUT 16,N24,[I,207]        'move LCD cursor to end of second line
                    SEROUT 16,N24,[" "]          'blank LCD timer indicator
                    RETURN

'============================= SUBROUTINES FOLLOW ====================================
'=====================================================================================
elapsetme:  'display elapsed time if timer button pressed at power-on
       GOSUB beep
       SEROUT 16,N24,[I,2,"Hrs = ",DEC hrs,"        "] 'disp hours top line
       SEROUT 16,N24,[I,192,"Mins = ",DEC mins,"       "]  'disp minutes 2nd line
       PAUSE 4000                                        'wait 4 secs
       SEROUT 16,N24,[I,CLR]    'clear LCD
       GOSUB beep
       RETURN
'=====================================================================================
resettime:  'reset elapsed time to zero if swap button pressed at power-on
       WRITE $002,0 'resets mins to 0
       WRITE $003,0 'resets hrs.LOWBYTE to 0
       WRITE $004,0 'resets hrs.HIGHBYTE to 0
       PAUSE 1000
       SEROUT 16,N24,[I,2," **RESET TIME** ",DEC hrs,"        "] 'disp hours top line
       PAUSE 4000                                        'wait 4 secs
       SEROUT 16,N24,[I,CLR]    'clear LCD
       GOSUB beeplong
       RETURN
'=====================================================================================
rempulse:  'output a 10 msec pulse to the remote output line

      HIGH 10               'set P10 output state to high
      PULSOUT 10,50000      '100 msec pulse low (output state returns to high when done)
      INPUT 10              'set P10 to INPUT
      remflag=0             'set remflag to ON-LINE
      startflag=1           'turn on startup flag
      GOTO startup
'=====================================================================================
offline:  'take controller off-line when low pulse seen on P10

      IF remflag=1 THEN rd_buttons  'skip if already off-line, conrinue if not
      HIGH 9                'deselect (turn off) remote relay port
      HIGH 11               'disable relays
      remflag=1             'turn on off-line flag
      HIGH oldtrx:HIGH oldamp     'turn off LEDs
      SEROUT 16,N24,[I,CLR] 'clear LCD
      SEROUT 16,N24,[I,2]   'move cursor to beginning of first line
      add=$0B0              'address of "** OFF LINE ** " string
      GOSUB stringout       'send "** OFF LINE **" to LCD
      GOSUB beep          'confirm with beep
      GOTO rd_buttons       'back to buttons,P10 still in INPUT state


'=====================================================================================

trx1sel:                  'subroutine -- set relays and LCD display for TRX1
      LOW 14                 'set trxadd1 (P14)to L
      LOW 15                 'set trxadd2 (p15)to L,
      LOW 11                 'enable relays (P11), TRX1 selected
      SEROUT 16,N24,[I,192]  'move cursor to beginning of second line
      add=$060               'go to trx1 data
      GOSUB stringout        'display TRX1 on LCD
      RETURN
 '====================================================================================
trx2sel:                 'subroutine -- set relays and LCD display for TRX2
      HIGH 14               'set trxadd1 to H
      LOW 15                'set trxadd2 to L,
      LOW 11                'enable relays (P11),TRX2 selected
      SEROUT 16,N24,[I,192] 'move cursor to beginning of second line
      add=$070              'go to trx2 data
      GOSUB stringout       'display TRX2 on LCD
      RETURN
 '====================================================================================
trx3sel:                 'subroutine -- set relays and LCD display for TRX3
      LOW 14                'set trxadd1 to H
      HIGH 15               'set trxadd2 to L,
      LOW 11                'enable relays (P11),TRX3 selected
      SEROUT 16,N24,[I,192] 'move cursor to beginning of second line
      add=$080              'go to trx3 data
      GOSUB stringout       'display TRX3 on LCD
      RETURN

'=====================================================================================
amp1sel:                 'subroutine -- set relays and LCD display for AMP1
      oldamp=amp           'set oldamp to previous amp selection
      amp=3                'update amplifier selection
      LOW 12               'set ampadd1 to L
      LOW 13               'set ampadd2 to L,
      LOW 11               'enable relays (P11), AMP1 selected
      SEROUT 16,N24,[I,2]  'move cursor to beginning of first line
      add=$030             'go to AMP1 data
      GOSUB stringout      'display AMP1 on LCD
      RETURN

 '====================================================================================
amp2sel:                'subroutine -- set relays and LCD display for AMP2
      oldamp=amp           'set oldamp to previous amp selection
      amp=4                'update amplifier selection
      HIGH 12              'set ampadd1 to H
      LOW 13               'set ampadd2 to L,
      LOW 11               'enable relays (P11), AMP2 selected
      SEROUT 16,N24,[I,2]  'move cursor to beginning of first line
      add=$040             'go to AMP2 data
      GOSUB stringout      'display AMP2 on LCD
      RETURN
 '====================================================================================
amp3sel:                'subroutine -- set relays and LCD display for AMP3
      oldamp=amp           'set oldamp to previous amp selection
      amp=5                'update amplifier selection
      LOW 12               'set ampadd1 to H
      HIGH 13              'set ampadd2 to L,
      LOW 11               'enable relays (P11), AMP3 selected
      SEROUT 16,N24,[I,2]  'move cursor to beginning of first line
      add=$050             'go to AMP3 data
      GOSUB stringout      'display AMP3 on LCD
      RETURN

 '====================================================================================

 ampbypass:            'implement ampifier bypass mode

          bpflag=1             'change bpflag from 0 to 1
          HIGH 11              'disable relays
          HIGH 12              'set ampadd1 and ampadd2 to bypass mode
          HIGH 13
          LOW 11               'enable relays
          SEROUT 16,N24,[I,2]  'move cursor to beginning of first line
          add=$090             'point stringout subroutine to "amp bypass" string
          GOSUB stringout      'send string to LCD
          GOTO rd_buttons

 '====================================================================================
  blinkled:              'blink amplifier LED in bypass mode

      LOW amp
      PAUSE 100
      HIGH amp
      PAUSE 50
      GOTO rd_buttons

 '====================================================================================
  stringout:             'Subroutine -- send TRX and AMP strings to LCD
      READ add,x            'read address of data string
      IF x <>0 THEN cont1   'look for zero at end of string
      GOTO cont2            'and end if zero found
    cont1:
      SEROUT 16,N24,[x]
      add=add+1
      GOTO stringout
    cont2:
      GOSUB beep
      RETURN


'=====================================================================================

CWSP:       'subroutine - Send "SP" in CW

      FREQOUT 6,90,1000
      PAUSE 90
      FREQOUT 6,90,1000
      PAUSE 90
      FREQOUT 6,90,1000
      PAUSE 240
      FREQOUT 6,90,1000
      PAUSE 90
      FREQOUT 6,240,1000
      PAUSE 90
      FREQOUT 6,240,1000
      PAUSE 90
      FREQOUT 6,90,1000
      HIGH 6                 'leave P6 HIGH to avoid conflict with swap button
      RETURN

'=====================================================================================

CWID:      'subroutine - Send "ID" in CW

      FREQOUT 6,90,1000
      PAUSE 90
      FREQOUT 6,90,1000
      PAUSE 240
      FREQOUT 6,240,1000
      PAUSE 90
      FREQOUT 6,90,1000
      PAUSE 90
      FREQOUT 6,90,1000
      HIGH 6                 'leave P6 HIGH to avoid conflict with swap button
      RETURN

'=====================================================================================

CWK:      'subroutine - send "K" in CW

      FREQOUT 6,240,1000
      PAUSE 90
      FREQOUT 6,90,1000
      PAUSE 90
      FREQOUT 6,240,1000
      HIGH 6                 'leave P6 HIGH to avoid conflict with swap button
      RETURN

 '====================================================================================

beep:    'subroutine -- short 2 KHz beep

      FREQOUT 6,120,2000     'send 2000Hz for 120 msec to P6
      HIGH 6                 'Leave P6 HIGH to avoid conflict with swap button
      RETURN

      '===============================================================================

beeplong:  'subroutine -- long (3-tone) beep

      FREQOUT 6,60,2000      'send 2000Hz for 60 msec to P6
      FREQOUT 6,60,2500      'send 2500Hz for 60 msec to P6
      FREQOUT 6,100,3000     'send 3000Hz for 100 msec to P6
      HIGH 6                 'leave P6 HIGH to avoid conflict with swap button
      RETURN


 '====================================================================================
store_data:   'subroutine -- store trx and oldtrx in eeprom memory
      WRITE $000,trx
      WRITE $001,oldtrx
      RETURN

'  * * * * END OF PROGRAM * * * *