diff -ur ../ge-x2212-2/src/callbacks.c ./src/callbacks.c
--- ../ge-x2212-2/src/callbacks.c	2010-09-15 17:10:17.000000000 -0700
+++ ./src/callbacks.c	2012-06-14 02:20:04.000000000 -0700
@@ -9,6 +9,11 @@
 #include "interface.h"
 #include "support.h"
 
+#ifdef USE_PPI_DEV
+#include <dev/ppbus/ppi.h>
+#include <dev/ppbus/ppbconf.h>
+#endif
+
 
 #ifdef __GLIBC__
 #include <sys/io.h>
@@ -20,6 +25,7 @@
 #define DIRBIT 0x20
 
 extern  GtkWidget *app1;
+extern gboolean uhf;
 
 // new port defines to get 0x378 working on lp0
 #define LPTBASE 0x378
@@ -76,6 +82,36 @@
                     "ch09cct", "ch10cct", "ch11cct", "ch12cct",
                     "ch13cct", "ch14cct", "ch15cct", "ch16cct" };
                     
+#ifdef USE_PPI_DEV
+static void ppi_outb(u_int8_t outb_val, int addr) {
+	int			outb_action=-1;
+
+	if(addr==LPTBASE || addr==LPTDAT)
+		outb_action=PPISDATA;
+	else if(addr==LPTSTAT)
+		outb_action=PPISSTATUS;
+	else if(addr==LPTCTRL)
+		outb_action=PPISCTRL;
+	ioctl(fd0, outb_action, &outb_val);
+}
+
+static u_int8_t ppi_inb(int addr)
+{
+	u_int8_t ret=0;
+
+	if(addr==LPTBASE || addr==LPTDAT)
+		ioctl(fd0, PPIGDATA, &ret);
+	else if(addr==LPTSTAT)
+		ioctl(fd0, PPIGSTATUS, &ret);
+	else if(addr==LPTCTRL)
+		ioctl(fd0, PPIGCTRL, &ret);
+	return ret;
+}
+
+#define outb(v,a)	ppi_outb((v),(a))
+#define inb(a)		ppi_inb(a)
+#endif
+
 /* convert 2 ascii chars in hex to a decimal number */
 static int hex2( unsigned char a, unsigned char b)
 {
@@ -111,7 +147,9 @@
     /* release parallel port */
     if (fd0 > 0)
         close(fd0);
+#ifndef USE_PPI_DEV
     ioperm(LPTDAT, 3, 0);
+#endif
 }
 //=====================================================================
 // 
@@ -209,6 +247,7 @@
         case 0x03: space = 6250.0;      break;
         default: fprintf(stderr,"Invalid channel spacing code %d\n",r);
         }
+        if(uhf) space *= 3;
 
 //      g_print("ref = %fhz, spacing = %fhz \n",ref,space);        
         
@@ -736,6 +775,35 @@
     return 0;
 }
 
+gboolean freq_good(double freq)
+{
+	if(uhf)
+		return ( freq >= 134.33*3 && freq <= 185.66*3 );
+	return ( freq >= 136.0 && freq <= 174.0 );
+}
+
+int calc_divisor(double freq, double space, gboolean is_rx)
+{
+	int divisor = (((freq + (is_rx?45.0:0))*1e6) + (space/2.0)) / space;
+	/* Out of range... */
+	if(divisor > 0xffff || divisor < 0)
+		divisor=0;
+	return divisor;
+}
+
+double calc_realfreq(int divisor, double space, gboolean is_rx)
+{
+	return ((divisor * space ) - (is_rx?45e6:0))/1e6;  /* in mhz */
+}
+
+void fill_ch(unsigned char *chbuff, int divisor)
+{
+	chbuff[1] = ( divisor & 0x8000) >> 12;
+	chbuff[2] = (divisor & 0x780) >> 7;
+	chbuff[3] = (divisor & 0x7800) >> 11;
+	chbuff[4] = divisor & 0xf;
+	chbuff[5] = ((divisor & 0x30) >> 4) + ((divisor & 0x40) >> 3);
+}
 
 //=====================================================================
 // 
@@ -743,15 +811,37 @@
 //=====================================================================
 void encoderom( void )
 {
-    int i;
+    int i,j;
     int chan; 
-    double freq, realfreq;
+    double realfreq;
+    double rx_freq;
+    double tx_freq;
     int divisor;
     unsigned char *chbuff;
-    
+    double spaces[3];
+    double errors[3];
+    int spacecode[3];
+    int sc_idx;
+
+    if(uhf) {
+		spaces[0]=12500.0;
+		spaces[1]=15000.0;
+		spaces[2]=18750.0;
+		spacecode[0]=1;
+		spacecode[1]=2;
+		spacecode[2]=3;
+	}
+    else {
+		spaces[0]=5000.0;
+		spaces[1]=12500.0/3.0;
+		spaces[2]=6250.0;
+		spacecode[0]=2;
+		spacecode[1]=1;
+		spacecode[2]=3;
+    }
     GtkWidget *wid;
     G_CONST_RETURN gchar *txt;
-    
+
     /* start with a clean image */
     memset(x2212,0,sizeof(x2212));
 
@@ -778,55 +868,61 @@
         /* single digit conversion */
         x2212[0x40] = hex2bin(txt[0]) - 1;
 
-    /* number of channels in radio... to do this we need to look    */
-    /* at all the rx channels and count any in the range of 136-174 */
-    chan = 0;
-    for ( i = 0; i<16; i++ )
-    {
-        wid = lookup_widget(app1,rxfreq[i]);
-        txt = gtk_entry_get_text((GtkEntry *)wid);
-        freq = atof(txt);
-        if ( freq >= 136.0 && freq <= 174.0 ) chan++;
-    }
-    if ( chan < 1 )
-        fprintf(stderr,"Warning, no valid channels found\n");
-    x2212[0x80] = chan - 1;
-    
+	chan=0;
     /* now lets fill in all the channels */
     for ( i = 0; i<16; i++ )
     {
         /* rx freq lookup off the screen */
         wid = lookup_widget(app1,rxfreq[i]);
         txt = gtk_entry_get_text((GtkEntry *)wid);
-        freq = atof(txt);
+        rx_freq = atof(txt);
+
+       	if ( !freq_good(rx_freq) ) {
+			if(rx_freq > 0)
+				g_printf("Warning, ignoring and removing invalid channel %d\n",i+1);
+       		continue;
+       	}
+       	chan++;
+		if(chan != i+1)
+			g_printf("Warning, channel %d will be renumbered to %d\n",i+1,chan);
+
+        /* tx freq lookup off the screen */
+        wid = lookup_widget(app1,txfreq[i]);
+        txt = gtk_entry_get_text((GtkEntry *)wid);
+        tx_freq = atof(txt);
+
+		for(j=0; j<3; j++) {
+            divisor = calc_divisor(rx_freq, spaces[j], TRUE);
+            realfreq = calc_realfreq(divisor, spaces[j], TRUE);  /* in mhz */
+            errors[j] = fabs(rx_freq-realfreq);
+            divisor = calc_divisor(tx_freq, spaces[j], FALSE);
+            realfreq = calc_realfreq(divisor, spaces[j], FALSE);  /* in mhz */
+            errors[j] += fabs(tx_freq-realfreq)*2;
+		}
+		sc_idx=0;
+		for(j=1; j<3; j++) {
+			if(errors[j] < errors[sc_idx])
+				sc_idx=j;
+		}
+//		if(sc_idx)
+//			g_printf("Using non-standard spacing of %fHz for channel %d\n",spaces[sc_idx],i+1);
 
-        /* 3 gross assumptions!!!, timebomb below */
         ref = 13.2e6;
-        space = 5000.0;
-#define REFCODE 2        
 
         /* point to the 8 bytes of rx channel data for specified channel */
-        chbuff = &x2212[0] + (((i+1) % 16) * 16);
+        chbuff = &x2212[0] + ((chan % 16) * 16);
         /* there are 20 packed bits of freq info... lets build the numbers */
         
         /* fill in info for valid rx channels */
-        if ( freq >= 136.0 && freq <= 174.0 )
+        if ( freq_good(rx_freq) )
         {
-            /* we have a choice of 3 ch spacings when building info */
-            /* for a particular rx and tx channel pair              */
-            /* as a start, we assume 5khz will do.. should probably */
-            /* try all 3 and use the one with the least error       */
-            divisor = (((freq + 45.0)*1e6) + (space/2.0)) / space;
-            realfreq = ((divisor * space ) - 45e6)/1e6;  /* in mhz */
-            if ( fabs(freq-realfreq) > 0.001 )
+            divisor = calc_divisor(rx_freq, spaces[sc_idx], TRUE);
+            realfreq = calc_realfreq(divisor, spaces[sc_idx], TRUE);  /* in mhz */
+            if ( fabs(rx_freq-realfreq) > 0.001 )
                 fprintf(stderr,"Warning ch %d freq error: %f <> %fmhz\n",
-                        i+1,realfreq,freq); 
-            chbuff[1] = REFCODE + (( divisor & 0x8000) >> 12);
-            chbuff[2] = (divisor & 0x780) >> 7;
-            chbuff[3] = (divisor & 0x7800) >> 11;
-            chbuff[4] = divisor & 0xf;
-            chbuff[5] = ((divisor & 0x30) >> 4) + ((divisor & 0x40) >> 3);
-
+                        i+1,realfreq,rx_freq); 
+			fill_ch(chbuff, divisor);
+            chbuff[1] |= spacecode[sc_idx];
         }
         /* fill in the rx cg code (1st 2 digits of entrybox) */
         wid = lookup_widget(app1,rxcg[i]);
@@ -835,28 +931,19 @@
         chbuff[7] = hex2bin(txt[1]);
 
         /* now fill in the tx info */
-        /* tx freq lookup off the screen */
-        wid = lookup_widget(app1,txfreq[i]);
-        txt = gtk_entry_get_text((GtkEntry *)wid);
-        freq = atof(txt);
-
         /* point to the 8 bytes of tx channel data for specified channel */
-        chbuff = &x2212[0] + (((i+1) % 16) * 16) + 8;
+        chbuff = &x2212[0] + ((chan % 16) * 16) + 8;
         /* there are 20 packed bits of freq info... lets build the numbers */
         
         /* fill in info for valid tx channels */
-        if ( freq >= 136.0 && freq <= 174.0 )
+        if ( freq_good(tx_freq) )
         {
-            divisor = ((freq*1e6) + (space/2.0)) / space;
-            realfreq = divisor * space /1e6;  /* in mhz */
-            if ( fabs(freq-realfreq) > 0.001 )
+            divisor = calc_divisor(tx_freq, spaces[sc_idx], FALSE);
+            realfreq = calc_realfreq(divisor, spaces[sc_idx], FALSE);  /* in mhz */
+            if ( fabs(tx_freq-realfreq) > 0.001 )
                 fprintf(stderr,"Warning ch %d freq error: %f <> %fmhz\n",
-                        i+1,realfreq,freq); 
-            chbuff[1] = ( divisor & 0x8000) >> 12;
-            chbuff[2] = (divisor & 0x780) >> 7;
-            chbuff[3] = (divisor & 0x7800) >> 11;
-            chbuff[4] = divisor & 0xf;
-            chbuff[5] = ((divisor & 0x30) >> 4) + ((divisor & 0x40) >> 3);
+                        i+1,realfreq,tx_freq);
+			fill_ch(chbuff, divisor);
         }
         /* fill in the tx cg code (1st 2 digits of entrybox) */
         wid = lookup_widget(app1,txcg[i]);
@@ -869,6 +956,11 @@
         if (gtk_toggle_button_get_active((GtkToggleButton *)wid))
             chbuff[1] = chbuff[1] + 0x04;
     }
+    /* number of channels in radio... to do this we need to look    */
+    /* at all the rx channels and count any in the range of 136-174 */
+    if ( chan < 1 )
+        fprintf(stderr,"Warning, no valid channels found\n");
+    x2212[0x80] = chan - 1;
 }
 
 
@@ -1148,19 +1240,30 @@
     }
 
     /* to read and write to the parallel port, we need it open as root */
+#ifdef USE_PPI_DEV
+    fd0 = open("/dev/ppi0", O_RDWR | O_NONBLOCK);
+#else
     fd0 = open("/dev/lp0", O_RDWR | O_NONBLOCK);
+#endif
     if (fd0 >= 0) 
     {
+#ifndef USE_PPI_DEV
         int stat = ioperm(LPTDAT, 3, 1);
     	if ( stat == -1 )
 	        perror("ioperm failed ");
+#endif
     }
     else
     {
+#ifdef USE_PPI_DEV
+        fprintf(stderr,"\n\n*** open on /dev/ppi0 failed...Do you have permission?\n");
+    	perror("/dev/lp0");
+#else
         fprintf(stderr,"\n\n*** open on /dev/lp0 failed...Do you have permission?\n");
         fprintf(stderr,"*** you may need to 'sudo modprobe parport_pc'\n");
         fprintf(stderr,"*** 'sudo ge-x2212-2'\n");
     	perror("/dev/lp0");
+#endif
         done();
     }
 //  g_print("Using port: 0x%x \n", LPTDAT);
diff -ur ../ge-x2212-2/src/callbacks.h ./src/callbacks.h
--- ../ge-x2212-2/src/callbacks.h	2004-09-27 13:13:40.000000000 -0700
+++ ./src/callbacks.h	2012-06-07 09:34:52.000000000 -0700
@@ -1,5 +1,8 @@
 #include <gnome.h>
 
+#ifdef __FreeBSD__
+#define USE_PPI_DEV
+#endif
 
 void
 on_new1_activate                       (GtkMenuItem     *menuitem,
diff -ur ../ge-x2212-2/src/interface.c ./src/interface.c
--- ../ge-x2212-2/src/interface.c	2010-09-15 17:33:07.000000000 -0700
+++ ./src/interface.c	2012-06-14 02:09:15.000000000 -0700
@@ -18,6 +18,8 @@
 #include "interface.h"
 #include "support.h"
 
+extern gboolean uhf;
+
 #define GLADE_HOOKUP_OBJECT(component,widget,name) \
   gtk_object_set_data_full (GTK_OBJECT (component), name, \
     gtk_widget_ref (widget), (GtkDestroyNotify) gtk_widget_unref)
@@ -267,7 +269,7 @@
   GtkWidget *combo_entry5;
   GtkWidget *appbar1;
 
-  app1 = gnome_app_new ("Ge-x2212-2", "GE Phoenix SX X2212 EEProm programmer (VHF 16ch scan) by Lawrence Glaister VE7IT 15-Sept-2010");
+  app1 = gnome_app_new ("Ge-x2212-2", uhf?"GE Phoenix SX X2212 EEProm programmer (UHF 16ch scan) by Lawrence Glaister VE7IT 15-Sept-2010":"GE Phoenix SX X2212 EEProm programmer (VHF 16ch scan) by Lawrence Glaister VE7IT 15-Sept-2010");
 
   bonobodock1 = GNOME_APP (app1)->dock;
   gtk_widget_show (bonobodock1);
@@ -678,7 +680,7 @@
   gtk_table_attach (GTK_TABLE (table1), ch01rx, 1, 2, 1, 2,
                     (GtkAttachOptions) (0),
                     (GtkAttachOptions) (0), 2, 2);
-  gtk_entry_set_text (GTK_ENTRY (ch01rx), "146.5200");
+  gtk_entry_set_text (GTK_ENTRY (ch01rx), uhf?"446.0000":"146.5200");
   gtk_entry_set_width_chars (GTK_ENTRY (ch01rx), 9);
 
   ch02rx = gtk_entry_new ();
@@ -742,7 +744,7 @@
   gtk_table_attach (GTK_TABLE (table1), ch01tx, 3, 4, 1, 2,
                     (GtkAttachOptions) (0),
                     (GtkAttachOptions) (0), 2, 2);
-  gtk_entry_set_text (GTK_ENTRY (ch01tx), "146.5200");
+  gtk_entry_set_text (GTK_ENTRY (ch01tx), uhf?"446.0000":"146.5200");
   gtk_entry_set_width_chars (GTK_ENTRY (ch01tx), 9);
 
   ch02tx = gtk_entry_new ();
diff -ur ../ge-x2212-2/src/main.c ./src/main.c
--- ../ge-x2212-2/src/main.c	2004-09-26 22:10:30.000000000 -0700
+++ ./src/main.c	2012-06-13 22:04:32.000000000 -0700
@@ -14,14 +14,31 @@
 
 /* globval so we can do widget lookups */
 GtkWidget *app1;
+gboolean uhf=FALSE;
 
 int
 main (int argc, char *argv[])
 {
+  gchar **remaining_args = NULL;
+  GOptionEntry option_entries[] = {
+	  { "uhf", 
+	  	'u', 
+	  	0, 
+	  	G_OPTION_ARG_NONE, 
+	  	&uhf, 
+	  	"Use UHF rather than VHF calculations",
+	  	NULL
+	  },
+	  { NULL }
+  };
+  GOptionContext *option_context;
+  option_context = g_option_context_new (NULL);
+  g_option_context_add_main_entries (option_context, option_entries, NULL);
 
   gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE,
                       argc, argv,
                       GNOME_PARAM_APP_DATADIR, PACKAGE_DATA_DIR,
+                      GNOME_PARAM_GOPTION_CONTEXT, option_context,
                       NULL);
 
   /*
@@ -31,7 +48,6 @@
    */
   app1 = create_app1 ();
 
-  
   gtk_widget_show (app1);
 
   gtk_main ();
