diff -Naur avrdude/Makefile.am avrdude-ftbb/Makefile.am
--- avrdude/Makefile.am	2005-06-19 14:38:03.000000000 -0700
+++ avrdude-ftbb/Makefile.am	2005-08-18 11:25:48.978993600 -0700
@@ -42,7 +42,7 @@
 
 AM_YFLAGS    = -d
 
-avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\"
+avrdude_CPPFLAGS = -DCONFIG_DIR=\"$(sysconfdir)\" -I/cygdrive/c/FTDI/Drivers/D2XX
 
 avrdude_CFLAGS   = @ENABLE_WARNINGS@  
 
@@ -67,6 +67,8 @@
 	crc16.h \
 	fileio.c \
 	fileio.h \
+	ftbb.c \
+	ftbb.h \
 	jtagmkII.c \
 	jtagmkII.h \
 	jtagmkII_private.h \
@@ -97,6 +99,8 @@
 	term.h \
 	usb_libusb.c
 
+avrdude_LDADD=/cygdrive/c/FTDI/Drivers/D2XX/FTD2XX.lib
+
 man_MANS = avrdude.1
 
 sysconf_DATA = avrdude.conf
diff -Naur avrdude/avrdude.conf.in avrdude-ftbb/avrdude.conf.in
--- avrdude/avrdude.conf.in	2005-08-17 12:40:21.000000000 -0700
+++ avrdude-ftbb/avrdude.conf.in	2005-08-18 11:51:45.657387200 -0700
@@ -432,6 +432,18 @@
   vcc   = 6;
 ;
 
+programmer
+  id       = "ezdop";
+  desc     = "AE6HO EZ-Doppler";
+  type     = ftbb;
+  baudrate = 230400;
+  reset    = 5;
+  sck      = 3;
+  mosi     = 2;
+  miso     = 1;
+;
+
+
 
 #
 # PART DEFINITIONS
diff -Naur avrdude/config_gram.y avrdude-ftbb/config_gram.y
--- avrdude/config_gram.y	2005-05-11 13:06:23.000000000 -0700
+++ avrdude-ftbb/config_gram.y	2005-08-14 14:38:04.861038400 -0700
@@ -38,6 +38,7 @@
 #include "butterfly.h"
 #include "avr.h"
 #include "jtagmkII.h"
+#include "ftbb.h"
 
 #if defined(WIN32NATIVE)
 #define strtok_r( _s, _sep, _lasts ) \
@@ -117,6 +118,7 @@
 %token K_STK500V2
 %token K_AVR910
 %token K_BUTTERFLY
+%token K_FTBB
 %token K_TYPE
 %token K_VCC
 %token K_VFYLED
@@ -355,6 +357,12 @@
     }
   } |
 
+  K_TYPE TKN_EQUAL K_FTBB {
+    {
+      ftbb_initpgm(current_prog);
+    }
+  } |
+
   K_DESC TKN_EQUAL TKN_STRING {
     strncpy(current_prog->desc, $3->value.string, PGM_DESCLEN);
     current_prog->desc[PGM_DESCLEN-1] = 0;
diff -Naur avrdude/ftbb.c avrdude-ftbb/ftbb.c
--- avrdude/ftbb.c	1969-12-31 16:00:00.000000000 -0800
+++ avrdude-ftbb/ftbb.c	2005-08-18 11:57:42.820963200 -0700
@@ -0,0 +1,304 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003-2004  Theodore A. Roth  <troth@openavr.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * avrdude interface for serial programming via FTDI bit bang mode operation. 
+ */
+
+#define FTBB_DEBUG 0
+
+#include "ac_cfg.h"
+#include "avr.h"
+#include "pgm.h"
+#include "ftbb.h"
+#include <ftd2xx.h>
+
+#define RESET   (1<<(pgm->pinno[PIN_AVR_RESET]-1))
+#define SCK	(1<<(pgm->pinno[PIN_AVR_SCK]-1))
+#define MOSI	(1<<(pgm->pinno[PIN_AVR_MOSI]-1))
+#define MISO	(1<<(pgm->pinno[PIN_AVR_MISO]-1))
+#define FTDDR	(MOSI|SCK|RESET)
+
+static FT_STATUS status;
+static FT_HANDLE handle;
+static unsigned char txbits;
+
+/* Send 8 bits over SPI bus with per-bit read back (very slow :-( )
+ *
+ * Alternating FT_Read and FT_Write commands result in non-adjustable
+ * timeout delays on the order of 200ms.
+ *
+ */
+static unsigned char ftbb_txrx(PROGRAMMER *pgm, unsigned char val)
+{
+    int i;
+    unsigned char bits;
+    unsigned char res;    
+    DWORD written;
+
+    res = 0;
+    for (i = 0; i < 8; i++) {  // For each bit
+        // Set up data on low phase of SCK
+        txbits &= ~SCK;
+
+        // Set MOSI to high bit of transmit data
+        if (val & 0x80)
+            txbits |= MOSI;
+        else
+            txbits &= ~MOSI;
+
+        FT_Write(handle, &txbits, 1, &written);
+
+        // Clock just fell, read previous input bit and shift in
+        FT_GetBitMode(handle, &bits);
+        res = (res << 1) | (bits & MISO);
+
+        // Now raise SCK to latch data in AVR
+        txbits |= SCK;
+        FT_Write(handle, &txbits, 1, &written);
+
+        // Move on to next bit in transmit data
+        val = val << 1;
+    }
+
+    return res;
+}
+
+/* Generic programmer command function for pgm->cmd
+ *
+ * Sends four bytes of command in sequence and collects responses
+ *
+ */
+static int ftbb_cmd(PROGRAMMER *pgm, unsigned char cmd[4], unsigned char res[4])
+{
+    int i;
+    
+#if FTBB_DEBUG
+    printf("CMD: %02X%02X%02X%02X  ", cmd[0], cmd[1], cmd[2], cmd[3]);
+#endif
+
+    for (i = 0; i < 4; i++) {
+        res[i] = ftbb_txrx(pgm, cmd[i]);
+    }
+    
+#if FTBB_DEBUG
+    printf("RES: %02X%02X%02X%02X\n", res[0], res[1], res[2], res[3]);
+#endif
+
+    return 0;
+}
+
+/* Programmer initialization command for pgm->initialize
+ *
+ * Pulse RESET with SCK low, then send SPI start programming command
+ *
+ */
+static int ftbb_initialize(PROGRAMMER *pgm, AVRPART *p)
+{
+  DWORD written;
+
+  // Atmel documentation says to raise RESET for 2 cpu clocks while sclk is low
+  // then lower RESET and wait 20 ms.
+  txbits |= RESET;
+  FT_Write(handle, &txbits, 1, &written);
+  usleep(1000); // 2 AVR cpu clocks at any realistic clock rate
+  txbits &= ~RESET;
+  FT_Write(handle, &txbits, 1, &written);
+  usleep(20000);
+
+  pgm->program_enable(pgm, p);
+  return 0;
+}
+
+/* Programmer status display for pgm->display
+ *
+ * Not-implemented
+ *
+ */
+static void ftbb_display(PROGRAMMER *pgm, char *p)
+{
+#if FTBB_DEBUG
+  printf("ftbb: display called with: %s\n", p);
+#endif
+
+  printf("FTBB: RESET mapped to pinno %d\n", pgm->pinno[PIN_AVR_RESET]);
+  printf("FTBB: SCK   mapped to pinno %d\n", pgm->pinno[PIN_AVR_SCK]);
+  printf("FTBB: MOSI  mapped to pinno %d\n", pgm->pinno[PIN_AVR_MOSI]);
+  printf("FTBB: MISO  mapped to pinno %d\n", pgm->pinno[PIN_AVR_MISO]);
+}  
+
+/* Programmer enable command for pgm->enable
+ *
+ * Lowers SCK and RESET in preparation for serial programming
+ *
+ */
+static void ftbb_enable(PROGRAMMER *pgm)
+{
+  DWORD written;
+
+  // Lower SCK & RESET
+  txbits &= ~SCK;
+  txbits &= ~RESET;
+  FT_Write(handle, &txbits, 1, &written);
+}
+
+/* Programmer disable command for pgm->disable
+ *
+ * Raises RESET to return to normal chip operation
+ *
+ */
+static void ftbb_disable(PROGRAMMER *pgm)
+{
+  DWORD written;
+  
+  // Raise RESET to return to normal mode
+  txbits |= RESET;
+  FT_Write(handle, &txbits, 1, &written);
+}
+
+
+/* Programmer programming mode enable function for pgm->program_enable
+ *
+ * Starts SPI programming mode 
+ *
+ */
+static int ftbb_program_enable(PROGRAMMER *pgm, AVRPART *p)
+{
+  unsigned char cmd[4];
+  unsigned char res[4];
+  
+  if (p->op[AVR_OP_PGM_ENABLE] == NULL) {
+    fprintf(stderr, "program enable instruction not defined for part \"%s\"\n",
+            p->desc);
+    return -1;
+  }
+
+  memset(cmd, 0, sizeof(cmd));
+  avr_set_bits(p->op[AVR_OP_PGM_ENABLE], cmd);
+  pgm->cmd(pgm, cmd, res);
+
+  return 0;
+}
+
+/* Progammer erase function for pgm->erase
+ *
+ * Sends chip erase command and sleeps the chip erase delay
+ *
+ */ 
+static int ftbb_chip_erase(PROGRAMMER *pgm, AVRPART *p)
+{
+  unsigned char cmd[4];
+  unsigned char res[4];
+
+  if (p->op[AVR_OP_CHIP_ERASE] == NULL) {
+    fprintf(stderr, "chip erase instruction not defined for part \"%s\"\n",
+            p->desc);
+    return -1;
+  }
+
+  memset(cmd, 0, sizeof(cmd));
+  avr_set_bits(p->op[AVR_OP_CHIP_ERASE], cmd);
+  pgm->cmd(pgm, cmd, res);
+  usleep(p->chip_erase_delay);
+
+  return 0;
+}
+
+/* Programmer open command for pgm->open
+ *
+ * Opens FTD2XX device specified by 'name', performs a chip reset, then
+ * sets the baudrate and bit bang mode
+ *
+ */
+static int ftbb_open(PROGRAMMER *pgm, char *name)
+{
+  int devnum;
+
+  devnum = 0; // TODO: Use passed port name...
+  if (strcmp(name, "ft0")) {
+    fprintf(stderr, "ERROR: FTD2XX device selection not supported!\n");
+    return -1;
+  }
+
+  // Call FTD2XX library to open device
+  if ((status = FT_Open(devnum, &handle)) != FT_OK) {
+    fprintf(stderr, "Failed to open FTD2XX device #%d.\n", devnum);
+    return -1;        
+  }
+
+  // Reset chipset
+  if ((status = FT_ResetDevice(handle)) != FT_OK) {
+    fprintf(stderr, "Failed to reset chipset for FTD2XX device #%d.\n", devnum);
+    return -1;
+  }
+
+  // Set baud rate for bit bang interface
+  if ((status = FT_SetBaudRate(handle, pgm->baudrate)) != FT_OK) {
+    fprintf(stderr, "Failed to set baud rate for FTD2XX device #%d.\n", devnum);
+    return -1;
+  }
+
+  // Set bit bang direction and mode
+  if ((status = FT_SetBitMode(handle, FTDDR, 1)) != FT_OK) {
+    fprintf(stderr, "Failed to set bit bang mode for FTD2XX device #%d.\n", devnum);
+    return -1;
+  }
+
+  return 0;
+}
+
+/* Programmer close function for pgm->close
+ *
+ * Releases FTD2XX device
+ *
+ */
+static void ftbb_close(PROGRAMMER *pgm)
+{
+  FT_Close(handle);
+}
+
+/* Programmer initialization command for startup.
+ *
+ * Sets appropriate function pointers in structure
+ * Tests FTD2XX interface by enumerating number of devices
+ *
+ */
+void ftbb_initpgm (PROGRAMMER *pgm)
+{
+  DWORD num_devices;
+  
+  strcpy(pgm->type, "ftbb");
+
+  pgm->initialize = ftbb_initialize;
+  pgm->display = ftbb_display;
+  pgm->enable = ftbb_enable;
+  pgm->disable = ftbb_disable;
+  pgm->program_enable = ftbb_program_enable;
+  pgm->chip_erase = ftbb_chip_erase;  
+  pgm->cmd = ftbb_cmd;
+  pgm->open = ftbb_open;
+  pgm->close = ftbb_close;  
+
+  if ((status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY)) != FT_OK)
+    fprintf(stderr, "Failed to initialize FTD2XX interface.\n");
+  else
+    printf("%lu FTD2XX device(s) found.\n", num_devices);
+
+  txbits = RESET;
+}
diff -Naur avrdude/ftbb.h avrdude-ftbb/ftbb.h
--- avrdude/ftbb.h	1969-12-31 16:00:00.000000000 -0800
+++ avrdude-ftbb/ftbb.h	2005-08-18 11:28:38.232368000 -0700
@@ -0,0 +1,27 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2003-2004  Theodore A. Roth  <troth@openavr.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __ftbb_h__
+#define __ftbb_h__
+
+#include "avrpart.h"
+
+void ftbb_initpgm (PROGRAMMER *pgm);
+
+#endif /* __ftbb_h__ */
diff -Naur avrdude/lexer.l avrdude-ftbb/lexer.l
--- avrdude/lexer.l	2005-05-11 13:06:23.000000000 -0700
+++ avrdude-ftbb/lexer.l	2005-08-14 14:39:56.691843200 -0700
@@ -135,6 +135,7 @@
 enablepageprogramming { yylval=NULL; return K_ENABLEPAGEPROGRAMMING; }
 errled           { yylval=NULL; return K_ERRLED; }
 flash            { yylval=NULL; return K_FLASH; }
+ftbb		 { yylval=NULL; return K_FTBB; }
 has_jtag         { yylval=NULL; return K_HAS_JTAG; }
 id               { yylval=NULL; return K_ID; }
 idr              { yylval=NULL; return K_IDR; }
