diff -Naur pp-0.1/src/debug.c pp-pch/src/debug.c
--- pp-0.1/src/debug.c	2005-01-27 10:17:00.000000000 -0800
+++ pp-pch/src/debug.c	2009-09-13 22:22:00.000000000 -0700
@@ -74,24 +74,16 @@
 }
 
 void debug_config_dump(char * fuseImage, deviceConfig_t devConfig) {
-	int ii;
+   int i;
 
-	printf("\nConfig Dump\n");
-	for (ii = 0; ii < devConfig.fuseCount * 2 + 8; ii++) {
-		printf("%02hhX",fuseImage[ii]);
+	puts( "\nConfig Dump");
 
-		if (ii < 8) {
-			if (ii < 7) {
-				printf(" ");
-			} else {
-				printf("\n");
-			}
-		} else {
-			if (((ii - 8) & 0xF) == 0xF || ii == devConfig.fuseCount*2 + 7) {
-				printf("\n");
-			} else if (((ii - 8) & 0x1) == 0x1) {
-				printf(" ");
-			}
-		}
-	}
+   printf("ID: 0x" );
+   for( i = 0; i < 8; i++ )
+      printf("%02hhx", fuseImage[ i ]);
+
+   printf( "\nFuses:" );
+   for( i = 0; i < devConfig.fuseCount; i++ )
+      printf( " 0x%02hhx%02hhx", fuseImage[ (i << 1) + 9 ], fuseImage[ (i << 1) + 8 ] );
+   printf( "\n" );
 }
diff -Naur pp-0.1/src/devConfig.c pp-pch/src/devConfig.c
--- pp-0.1/src/devConfig.c	2005-01-21 18:35:55.000000000 -0800
+++ pp-pch/src/devConfig.c	2009-09-13 22:22:00.000000000 -0700
@@ -55,7 +55,7 @@
 		}
 
 		// Parse the key and value
-		sscanf(buffer,"%[0-9a-zA-Z]=%s",key,value);
+		sscanf(buffer,"%[0-9a-zA-Z]=%[^\t\n]",key,value);
 
 		// Look for the CHIPname
 		// If we find the right CHIPname value, read everything else
diff -Naur pp-0.1/src/ihx32.c pp-pch/src/ihx32.c
--- pp-0.1/src/ihx32.c	2005-01-21 18:35:55.000000000 -0800
+++ pp-pch/src/ihx32.c	2009-09-18 20:52:25.000000000 -0700
@@ -21,11 +21,18 @@
 # include <config.h>
 #endif
 #include <stdio.h>
+#include "debug.h"
 #include "ihx32.h"
 
+char ascii2hexNybble( char ch )
+{
+   return( '9' < ch ? ('a' > ch ? ch - 'A' : ch - 'a') + 10 : ch - '0' );
+}
+
 int ihx32_read(FILE * hexFile, unsigned char * romImage, unsigned char *eepromImage, unsigned char *fuseImage, deviceConfig_t config ) {
 	int lba = 0;
 	char lineBuffer[256];
+	const char* cp;
 	char partBuffer[5];
 	char *destImage;
 	int numBytes;
@@ -34,72 +41,52 @@
 	int value;
 	int ii;
 	int done = 0;
-	// These are in words, convert to bytes
-	int eepromStart = config.eepromStart*2;
-	int configStart = config.configStart*2;
+
+	DEBUG_p("Preparing to read from hex file\n");
 
 	while (done == 0) {
 		fgets(lineBuffer,255,hexFile);
+      cp = lineBuffer;
 
 		// First character is always ':'
-		if (lineBuffer[0] != ':') {
-			return -1;
-		}
+      if( ':' != *cp++ )
+	continue;  // skip comment lines (anything not starting with ':')
 
 		// Next come the number of bytes
-		partBuffer[0] = lineBuffer[1];
-		partBuffer[1] = lineBuffer[2];
-		partBuffer[2] = '\0';
-		numBytes = strtol(partBuffer,NULL,16);
+      numBytes = (ascii2hexNybble( *cp++ ) << 4) + ascii2hexNybble( *cp++ );
 
 		// Then the lower 16-bits of the address
-		partBuffer[0] = lineBuffer[3];
-		partBuffer[1] = lineBuffer[4];
-		partBuffer[2] = lineBuffer[5];
-		partBuffer[3] = lineBuffer[6];
-		partBuffer[4] = '\0';
-		address = strtol(partBuffer,NULL,16);
+      for( ii = 0, address = 0; ii < 4; ii++ )
+      {
+         address <<= 4;
+         address += ascii2hexNybble( *cp++ );
+      }
 
 		// And then the record type
-		partBuffer[0] = lineBuffer[7];
-		partBuffer[1] = lineBuffer[8];
-		partBuffer[2] = '\0';
-		recType = strtol(partBuffer,NULL,16);
+      recType = (ascii2hexNybble( *cp++ ) << 4) + ascii2hexNybble( *cp++ );
 
 		switch(recType) {
 			case 0: // Data Record
 				address += lba;
-				if (address >= eepromStart) {
-					if (config.eepromSize > 0) {
-						destImage = eepromImage+(address-eepromStart);
-					} else {
-						destImage = NULL;
-					}
-				} else if (address >= configStart) {
-					destImage = fuseImage+8+(address-configStart);
-				} else {
-					destImage = romImage+address;
-				}
-
-				if (destImage != NULL) {
-					// Loop over each pair of bytes and
-					// put them in the destImage
-					for (ii = 0; ii < numBytes*2; ii+= 4) {
-						// Bytes are ordered low-byte, high-byte
-						// in the file, correct this
-						partBuffer[0] = lineBuffer[9+ii];
-						partBuffer[1] = lineBuffer[9+ii+1];
-						partBuffer[2] = '\0';
-						value = strtol(partBuffer,NULL,16);
-						destImage[ii/2+1] = value;
-
-						partBuffer[0] = lineBuffer[9+ii+2];
-						partBuffer[1] = lineBuffer[9+ii+3];
-						partBuffer[2] = '\0';
-						value = strtol(partBuffer,NULL,16);
-						destImage[ii/2] = value;
-					}
-				}
+            if( address >= config.configStart )
+            {
+               if( address >= config.eepromStart )
+                  destImage = eepromImage + address - config.eepromStart;
+               else
+                  destImage = fuseImage + 8 + address - config.configStart;
+
+               for( ii = 0; ii < numBytes; ii++ )
+                  *destImage++ = (ascii2hexNybble( *cp++ ) << 4) + ascii2hexNybble( *cp++ );
+            }
+            else
+            {
+               destImage = romImage + address;
+               for( ii = 0; ii < numBytes; ii += 2, destImage += 2 )
+               {
+                  destImage[1] = (ascii2hexNybble( *cp++ ) << 4) + ascii2hexNybble( *cp++ );
+                  destImage[0] = (ascii2hexNybble( *cp++ ) << 4) + ascii2hexNybble( *cp++ );
+               }
+            }
 				break;
 			case 1: // End of File record
 				done = 1;
@@ -107,16 +94,14 @@
 			case 2: // TODO : segment address
 				break;
 			case 4: // Upper 16-bits of address
-				partBuffer[1] = lineBuffer[9];
-				partBuffer[2] = lineBuffer[10];
-				partBuffer[3] = lineBuffer[11];
-				partBuffer[4] = lineBuffer[12];
-				partBuffer[5] = '\0';
-				lba = strtol(partBuffer, NULL, 16);
-				lba <<= 16;
+            for( ii = 0, lba = 0; ii < 4; ii++ )
+            {
+               lba <<= 4;
+               lba += ascii2hexNybble( *cp++ );
+            }
+            lba <<= 16;
 				break;
 		}
-		
 	}
 
 	return 0;
diff -Naur pp-0.1/src/pp.c pp-pch/src/pp.c
--- pp-0.1/src/pp.c	2005-01-27 10:19:27.000000000 -0800
+++ pp-pch/src/pp.c	2009-09-18 20:51:03.000000000 -0700
@@ -21,6 +21,7 @@
 # include <config.h>
 #endif
 #include <stdio.h>
+#include <string.h>
 #include <unistd.h>
 #include <sysexits.h>
 #include <termios.h>
@@ -159,8 +160,8 @@
 	//       (1 word = 2 bytes)
 	romImage = (unsigned char *)malloc(sizeof(unsigned char) * devConfig.romSize * 2);
 	for (ii = devConfig.romSize*2 - 2; ii >= 0; ii -= 2) {
-		romImage[ii] = 0x3F;
-		romImage[ii+1] = 0xFF;
+		romImage[ii] = devConfig.romPad >> 8;
+		romImage[ii+1] = devConfig.romPad & 0xFF;
 	}
 
 	if (devConfig.eepromSize > 0) {
@@ -180,22 +181,24 @@
 	fuseImage[8] = devConfig.fuse1Blank >> 8;
 	fuseImage[9] = devConfig.fuse1Blank & 0xFF;
 	if (devConfig.fuseCount == 2 || devConfig.fuseCount == 7) {
-		fuseImage[10] = devConfig.fuse2Blank >> 8;
-		fuseImage[11] = devConfig.fuse2Blank & 0xFF;
+		fuseImage[10] = devConfig.fuse2Blank & 0xFF;
+		fuseImage[11] = devConfig.fuse2Blank >> 8;
 	}
 	if (devConfig.fuseCount == 7) {
-		fuseImage[12] = devConfig.fuse3Blank >> 8;
-		fuseImage[13] = devConfig.fuse3Blank & 0xFF;
-		fuseImage[14] = devConfig.fuse4Blank >> 8;
-		fuseImage[15] = devConfig.fuse4Blank & 0xFF;
-		fuseImage[16] = devConfig.fuse5Blank >> 8;
-		fuseImage[17] = devConfig.fuse5Blank & 0xFF;
-		fuseImage[18] = devConfig.fuse6Blank >> 8;
-		fuseImage[19] = devConfig.fuse6Blank & 0xFF;
-		fuseImage[20] = devConfig.fuse7Blank >> 8;
-		fuseImage[21] = devConfig.fuse7Blank & 0xFF;
+		fuseImage[12] = devConfig.fuse3Blank & 0xFF;
+		fuseImage[13] = devConfig.fuse3Blank >> 8;
+		fuseImage[14] = devConfig.fuse4Blank & 0xFF;
+		fuseImage[15] = devConfig.fuse4Blank >> 8;
+		fuseImage[16] = devConfig.fuse5Blank & 0xFF;
+		fuseImage[17] = devConfig.fuse5Blank >> 8;
+		fuseImage[18] = devConfig.fuse6Blank & 0xFF;
+		fuseImage[19] = devConfig.fuse6Blank >> 8;
+		fuseImage[20] = devConfig.fuse7Blank & 0xFF;
+		fuseImage[21] = devConfig.fuse7Blank >> 8;
 	}
 
+	DEBUG_p("DEBUG: Attempting to open serial port %s\n",serialPort);
+
 	// Open the serial port
 	if ((serialFd = serial_open(serialPort,19200,8,PARITY_NONE,1)) < 0) {
 		switch(serialFd) {
@@ -304,11 +307,11 @@
 		programmer_read_config(serialFd, fuseImage, devConfig);
 		programmer_voltages_off(serialFd);
 
-#if defined(DEBUG)
+		//#if defined(DEBUG)
 		debug_rom_dump(romImage, devConfig);
 		debug_eeprom_dump(eepromImage, devConfig);
 		debug_config_dump(fuseImage, devConfig);
-#endif
+		//#endif
 
 		ihx32_write(hexFd,romImage,eepromImage,fuseImage,devConfig);
 
@@ -331,7 +334,6 @@
 			// Check for a blank ROM
 			programmer_voltages_on(serialFd);
 			ret = programmer_erase_rom_check(serialFd, devConfig);
-			programmer_voltages_off(serialFd);
 
 			if (ret < 0) {
 				printf("Error: failed to check for erased ROM\n");
@@ -341,10 +343,14 @@
 				return EX_SOFTWARE;
 			}
 
+         ret = programmer_echo(serialFd, 'V');
+         if( 0 > ret ) {
+            printf("Error: failed echo\n");
+            return EX_SOFTWARE;
+         }
+   
 			// Check for a blank EEPROM
-			programmer_voltages_on(serialFd);
 			ret = programmer_erase_eeprom_check(serialFd);
-			programmer_voltages_off(serialFd);
 
 			if (ret < 0) {
 				printf("Error: failed to check for erased EEPROM\n");
@@ -353,6 +359,18 @@
 				printf("Error: EEPROM is not erased, write will not be performed.  Override with -f.\n");
 				return EX_SOFTWARE;
 			}
+
+         ret = programmer_echo(serialFd, 'v');
+         if( 0 > ret ) {
+            printf("Error: failed echo\n");
+            return EX_SOFTWARE;
+         }
+         ret = programmer_echo(serialFd, 'V');
+         if( 0 > ret ) {
+            printf("Error: failed echo\n");
+            return EX_SOFTWARE;
+         }
+         programmer_voltages_off(serialFd);
 		}
 
 
@@ -380,26 +398,47 @@
 
 		programmer_voltages_on(serialFd);
 		ret = programmer_write_rom(serialFd,romImage,devConfig);
-		programmer_voltages_off(serialFd);
 		if (ret < 0) {
 			printf("Error: failed to write ROM\n");
 			return EX_SOFTWARE;
 		}
 
+      ret = programmer_echo(serialFd, 'V');
+      if( 0 > ret ) {
+         printf("Error: failed echo\n");
+         return EX_SOFTWARE;
+      }
+
 		if (devConfig.eepromSize > 0) {
-			programmer_voltages_on(serialFd);
 			ret = programmer_write_eeprom(serialFd,eepromImage,devConfig);
-			programmer_voltages_off(serialFd);
 			if (ret < 0) {
 				printf("Error: failed to write EEPROM\n");
 			}
 		}
 
-		programmer_voltages_on(serialFd);
+      ret = programmer_echo(serialFd, 'V');
+      if( 0 > ret ) {
+         printf("Error: failed echo\n");
+         return EX_SOFTWARE;
+      }
+
 		ret = programmer_write_fuses(serialFd,fuseImage,devConfig);
+		if (ret < 0) {
+			printf("Error: failed to write config\n");
+         return EX_SOFTWARE;
+		}
+      
+      ret = programmer_echo(serialFd, 'V');
+      if( 0 > ret ) {
+         printf("Error: failed echo\n");
+         return EX_SOFTWARE;
+      }
+      
+      ret = programmer_write_18Fxxxxx(serialFd,fuseImage,devConfig);
 		programmer_voltages_off(serialFd);
 		if (ret < 0) {
 			printf("Error: failed to write FUSEs\n");
+         return EX_SOFTWARE;
 		}
 
 	} else if (op_verify) {
diff -Naur pp-0.1/src/programmer.c pp-pch/src/programmer.c
--- pp-0.1/src/programmer.c	2005-01-27 10:13:00.000000000 -0800
+++ pp-pch/src/programmer.c	2009-09-18 21:07:31.000000000 -0700
@@ -64,15 +64,30 @@
 	return 0;
 }
 
+int programmer_echo(int port, char ch) {
+	unsigned char command;
+
+   command = 2;
+   write(port,&command,1);
+   write(port,&ch,1);
+   read(port,&command,1);
+   if( command != ch ) {
+      printf("DEBUG: Bad echo: %c != %c\n", command, ch);
+      return -1;
+   }
+   
+   return 0;
+}
+
 int programmer_proto_check(int port) {
 	unsigned char command;
-	unsigned char receive[4] = "XYZA";
+	unsigned char receive[5] = "XYZA\0";
 
 	command = 21;
 	write(port,&command,1);
 	read(port,receive,4);
 	if (strncasecmp(receive,PROTO_VERSION,4) != 0) {
-		printf("Version: %4c\n",receive);
+	  printf("Version: %4s\n", receive);
 		return -2;
 	}
 
@@ -239,15 +254,19 @@
 	unsigned char command;
 	int size;
 	int len;
-
+   
 	command = 11;
-	write(port,&command,1);
+	write(port,&command,1); 
 
 	len = 0;
 	size = devConfig.romSize * 2;
-	while ((len += read(port,romImage+len,256)) != size) {
-		DEBUG_p("DEBUG: rom read %d of %d bytes\n",len,size);
+   printf("0x%05x: ", len);
+	while ((len += read(port,romImage+len,1)) != size) {
+      printf(" %02hhx", romImage[len-1]);
+      if( 0 == (len % 16))
+         printf("\n0x%05x: ",len);
 	}
+   puts("");
 
 	return 0;
 }
@@ -262,8 +281,11 @@
 
 	len = 0;
 	size = devConfig.eepromSize;
-	while ((len += read(port,eepromImage+len,256)) != size) {
-		DEBUG_p("DEBUG: eeprom read %d of %d bytes\n",len,size);
+   printf("\n0x%05x: ",len+devConfig.eepromStart);
+	while ((len += read(port,eepromImage+len,1)) != size) {
+      printf(" %02hhx", eepromImage[len-1]);
+      if( 0 == (len % 16))
+         printf("\n0x%05x: ",len+devConfig.eepromStart);
 	}
 
 	return 0;
@@ -291,15 +313,8 @@
 	}
 
 	// IDs first
-	for (ii = 0; ii < 8; ii++) {
-		fuseImage[ii] = buffer[ii+2];
-	}
-
 	// Followed by Fuses in MSB
-	for (ii = 0; ii < devConfig.fuseCount*2; ii += 2) {
-		fuseImage[8+ii] = buffer[10+ii+1];
-		fuseImage[8+ii+1] = buffer[10+ii];
-	}
+   memcpy(fuseImage, buffer + 2, 22);
 
 	return 0;
 }
@@ -372,88 +387,70 @@
 
 }
 
-int programmer_write_rom(int port, char *romImage, deviceConfig_t devConfig) {
-	unsigned char command;
-	unsigned char buffer[32];
-	int ii, offset, endOffset, keepGoing = 1;
-
-	for (ii = devConfig.romSize*2 - 2; ii >= 0; ii -= 2) {
-		if (romImage[ii] != (devConfig.romPad >> 8) && romImage[ii+1] != (devConfig.romPad & 0xFF)) {
-			endOffset = ii;
-			break;
-		}
-	}
-	endOffset += 2;
-	endOffset /= 2;
-	DEBUG_p("DEBUG: Going to write from 0x0000 - 0x%04X\n",endOffset);
-
-	command = 7;
-	write(port,&command,1);
-
-	// Send romSize
-	buffer[0] = endOffset >> 8;
-	buffer[1] = endOffset & 0xFF;
-	write(port,buffer,2);
-
-	read(port,buffer,1);
-	if (buffer[0] != 'Y') {
-		DEBUG_p("DEBUG: write rom: bad response: %c\n",buffer[0]);
-		return -1;
-	}
-
-	// Fill Buffer A
-	for (ii = 0; ii < 32; ii++) {
-		buffer[ii] = romImage[ii];
-	}
-	offset = ii;
-	write(port,buffer,32);
-
-	read(port,buffer,1);
-	if (buffer[0] != 'Y') {
-		DEBUG_p("DEBUG: write rom: buffer_A bad response: %c\n",buffer[0]);
-		return -2;
-	}
-
-	// Fill Buffer B
-	for (ii = 0; ii < 32; ii++) {
-		buffer[ii] = romImage[offset+ii];
-	}
-	offset += ii;
-	write(port,buffer,32);
-
-	while (1) {
-		// Blank buffer
-		buffer[0] = '\0';
-		buffer[1] = '\0';
-		buffer[2] = '\0';
-
-		// Read completion codes
-		read(port,buffer,1);
-
-		// Possible results are
-		// 'N' = Programming error followed by current addres MSB first
-		// 'YP' = Programming finished
-		// 'Y' = Read for next 32 bytes
-		if (buffer[0] == 'N') {
-			read(port,buffer,2);
-			DEBUG_p("DEBUG: write rom: error writing %x\n",(unsigned int)(buffer[0] << 8) | buffer[1]);
-			return -3;
-		} else if (buffer[0] == 'Y') {
-			if (read(port,buffer,1) == 1 && buffer[0] == 'P') {
-				// All done
-				break;
-			}
-		}
-
-		// Write the next 32 bytes
-		for (ii = 0; ii < 32; ii++) {
-			buffer[ii] = romImage[offset+ii];
-		}
-		offset += ii;
-		write(port, buffer, 32);
-	}
-
-	return 0;
+int programmer_write_rom(int port, char *romImage, deviceConfig_t devConfig)
+{
+   unsigned short* sp = (unsigned short*)romImage;
+   unsigned short* ep = sp + devConfig.romSize;
+   unsigned short pad = (unsigned short)devConfig.romPad;
+
+   while( ep > sp && pad == *--ep )
+      /* loop to first non-pad word */;
+
+   int in, totalWords = ++ep - sp;
+   unsigned char buffer[ 5 ];
+
+   *buffer = 7;
+   write( port, buffer, 1 );
+
+   buffer[ 0 ] = totalWords >> 8;
+   buffer[ 1 ] = totalWords & 0xff;
+   write( port, buffer, 2 );
+
+   read( port, buffer, 1);
+   if( 'Y' != *buffer )
+   {
+      DEBUG_p( "DEBUG: write rom: bad response: %c\n", *buffer );
+      return -1;
+   }
+
+   while( 1 )
+   {
+      unsigned short address = sp - (unsigned short*)romImage;
+
+      write( port, sp, 32 );
+      /*
+      {
+	int a;
+	printf("0x%04x:", (unsigned int)(((char*)sp) - romImage));
+	for(a=0; a<32; a++) {
+	  printf(" %02x", ((unsigned char*)sp)[a]);
+	}
+	puts("");
+      }
+      */
+      printf( "Writing ROM: %d%%\r", 50 * ((char*)sp - romImage) / totalWords );
+      fflush(stdout);
+      sp += (32 / sizeof( *sp ));
+
+      in = read( port, buffer, 5 );
+      switch( *buffer )
+      {
+         case 'N':
+	    printf( "\nFailed to write ROM (current address 0x%0x)\n", (unsigned int)(((char*)sp) - romImage) );
+            return -3;
+
+         case 'P':
+	    puts("Writing ROM: complete");
+	    return 0;
+
+         case 'Y':
+            break;
+
+         default:
+	    printf( "\nBad write response, '%c' (current address 0x%0x)\n", *buffer, (unsigned int)(((char*)sp) - romImage) );
+            break;
+      }
+   }
 }
 
 int programmer_write_eeprom(int port, char *eepromImage, deviceConfig_t devConfig) {
@@ -463,9 +460,8 @@
 
 	command = 8;
 	write(port,&command,1);
-
 	// Send eepromSize
-	size = devConfig.eepromSize + 2;
+	size = devConfig.eepromSize;
 	buffer[0] = size >> 8;
 	buffer[1] = size & 0xFF;
 	write(port,buffer,2);
@@ -481,7 +477,10 @@
 	while (1) {
 		buffer[0] = eepromImage[offset];
 		buffer[1] = eepromImage[offset+1];
+
 		write(port,buffer,2);
+		printf( "Writing EEPROM: %d%%\r", 100 * offset / size );
+		fflush(stdout);
 
 		// Read completion codes
 		read(port,buffer,1);
@@ -496,7 +495,7 @@
 
 		offset += 2;
 	}
-
+	puts( "Writing EEPROM: complete" );
 	return 0;
 }
 
@@ -507,61 +506,25 @@
 	command = 9;
 	write(port,&command,1);
 
+	printf("Writing fuses... ");
+	fflush(stdout);
+
 	buffer[0] = '0';
 	buffer[1] = '0';
 
 	if (devConfig.bits == 14) {
-		buffer[2] = fuseImage[0];
-		buffer[3] = fuseImage[1];
-		buffer[4] = fuseImage[2];
-		buffer[5] = fuseImage[3];
-		buffer[6] = 'F';
-		buffer[7] = 'F';
-		buffer[8] = 'F';
-		buffer[9] = 'F';
-		buffer[10] = fuseImage[9];
-		buffer[11] = fuseImage[8];
-		buffer[12] = 0xFF;
-		buffer[13] = 0xFF;
-		buffer[14] = 0xFF;
-		buffer[15] = 0xFF;
-		buffer[16] = 0xFF;
-		buffer[17] = 0xFF;
-		buffer[18] = 0xFF;
-		buffer[19] = 0xFF;
-		buffer[20] = 0xFF;
-		buffer[21] = 0xFF;
-		buffer[22] = 0xFF;
-		buffer[23] = 0xFF;
+      memcpy(buffer + 2, fuseImage, 4);
+      memset(buffer + 6, 'F', 4);
+      memcpy(buffer + 10, fuseImage + 8, 2);
+      memset(buffer + 12, 0xff, 12);
 	} else if (devConfig.bits == 16) {
-		buffer[2] = fuseImage[0];
-		buffer[3] = fuseImage[1];
-		buffer[4] = fuseImage[2];
-		buffer[5] = fuseImage[3];
-		buffer[6] = fuseImage[4];
-		buffer[7] = fuseImage[5];
-		buffer[8] = fuseImage[6];
-		buffer[9] = fuseImage[7];
-		buffer[10] = fuseImage[9];
-		buffer[11] = fuseImage[8];
-		buffer[12] = fuseImage[11];
-		buffer[13] = fuseImage[10];
-		buffer[14] = fuseImage[13];
-		buffer[15] = fuseImage[12];
-		buffer[16] = fuseImage[15];
-		buffer[17] = fuseImage[14];
-		buffer[18] = fuseImage[17];
-		buffer[19] = fuseImage[16];
-		buffer[20] = fuseImage[19];
-		buffer[21] = fuseImage[18];
-		buffer[22] = fuseImage[21];
-		buffer[23] = fuseImage[20];
+      memcpy(buffer + 2, fuseImage, 22);
 	} else {
 		return -1;
 	}
 
 	write(port,buffer,24);
-
+	puts( "complete");
 	read(port,buffer,1);
 	if (buffer[0] != 'Y') {
 		DEBUG_p("DEBUG: write config: bad response %c\n",buffer[0]);
@@ -570,3 +533,27 @@
 
 	return 0;	
 }
+
+int programmer_write_18Fxxxxx(int port, char* fuseImage, deviceConfig_t devConfig)
+{
+   unsigned char command;
+   unsigned char buffer[24];
+
+   command = 17;
+   write(port,&command,1);
+   printf( "Writing 18Fxxxx fuses... " );   
+   fflush(stdout);
+
+   memset(buffer,0,2);
+   memcpy(buffer + 2, fuseImage, 22);
+
+   write(port,buffer,24);
+   puts("complete");
+	read(port,buffer,1);
+	if (buffer[0] != 'Y') {
+		DEBUG_p("DEBUG: write 18Fxxxxx: bad response %c\n",buffer[0]);
+		return -2;
+	}
+   
+	return 0;	
+}
diff -Naur pp-0.1/src/programmer.h pp-pch/src/programmer.h
--- pp-0.1/src/programmer.h	2005-01-21 18:35:55.000000000 -0800
+++ pp-pch/src/programmer.h	2009-09-13 22:01:48.000000000 -0700
@@ -24,6 +24,7 @@
 
 int programmer_reset(int port);
 int programmer_program_mode(int port);
+int programmer_echo(int port, char ch);
 int programmer_proto_check(int port);
 int programmer_chip_in_socket(int port);
 int programmer_init(int port, deviceConfig_t devConfig);
@@ -41,4 +42,5 @@
 int programmer_write_rom(int port, char *romImage, deviceConfig_t devConfig);
 int programmer_write_eeprom(int port, char *eepromImage, deviceConfig_t devConfig);
 int programmer_write_fuses(int port, char * fuseImage, deviceConfig_t devConfig);
+int programmer_write_18Fxxxxx(int port, char * fuseImage, deviceConfig_t devConfig);
 #endif
diff -Naur pp-0.1/src/serial.c pp-pch/src/serial.c
--- pp-0.1/src/serial.c	2005-01-21 18:35:55.000000000 -0800
+++ pp-pch/src/serial.c	2009-09-13 22:22:00.000000000 -0700
@@ -128,21 +128,27 @@
 	}
 
 	// Open the device file
-	fd = open(port, O_RDWR | O_NOCTTY);
+	fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
 	if (fd < 0)
 	{
 		// Can't open the device
 		return -4;
 	}
 
-	// Retrieve the current terminal IO settings
-	tcgetattr(fd, &oldtio);
+	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
 
-	oldtio.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
-	oldtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
-	oldtio.c_cflag &= ~(CSIZE | PARENB);
+	// Retrieve the current terminal IO settings
+	if(-1 == tcgetattr(fd, &oldtio))
+	  {
+	    close(fd);
+	    return -4;
+	  }
+
+	oldtio.c_oflag = 0;
+	oldtio.c_lflag = 0;
+	oldtio.c_iflag &= (IXON | IXOFF | IXANY);
+	oldtio.c_cflag &= ~HUPCL;
 	oldtio.c_cflag |= termdatabits | termstopbits | termparity | CREAD | CLOCAL;
-	oldtio.c_oflag &= ~(OPOST);
 
 	// Reads complete if 2 characters are read or
 	// .5 seconds elapses
