diff --git a/avrprog.c b/avrprog.c
index b1a8964e..4066c5b3 100644
--- a/avrprog.c
+++ b/avrprog.c
@@ -64,6 +64,7 @@
 #include <sys/stat.h>
 #include </sys/dev/ppbus/ppi.h>
 #include <limits.h>
+#include <ctype.h>
 
 #define DEFAULT_PARALLEL "/dev/ppi0"
 
@@ -102,12 +103,12 @@ typedef enum {
   AVR_FLASH_HI
 } AVRMEM;
 
-enum {
+typedef enum {
   FMT_AUTO,
   FMT_SREC,
   FMT_IHEX,
   FMT_RBIN
-};
+} FILEFMT;
 
 struct avrpart {
   char          * partdesc;         /* long part name */
@@ -800,6 +801,18 @@ void usage ( void )
 }
 
 
+char * fmtstr ( FILEFMT format )
+{
+  switch (format) {
+    case FMT_AUTO : return "auto-detect"; break;
+    case FMT_SREC : return "Motorola S-Record"; break;
+    case FMT_IHEX : return "Intel Hex"; break;
+    case FMT_RBIN : return "raw binary"; break;
+    default       : return "invalid format"; break;
+  };
+}
+
+
 
 int b2ihex ( unsigned char * inbuf, int bufsize, 
              int recsize, int startaddr,
@@ -971,7 +984,7 @@ int fileio_rbin ( struct fioparms * fio,
             "%s: %s error %s %s: %s; %s %d of the expected %d bytes\n", 
             progname, fio->iodesc, fio->dir, filename, strerror(errno),
             fio->rw, rc, size);
-    return -5;
+    return -1;
   }
 
   return rc;
@@ -987,20 +1000,20 @@ int fileio_ihex ( struct fioparms * fio,
     case FIO_WRITE:
       rc = b2ihex(buf, size, 32, 0, filename, f);
       if (rc) {
-        return -5;
+        return -1;
       }
       break;
 
     case FIO_READ:
       rc = ihex2b(filename, f, buf, size);
       if (rc)
-        return -5;
+        return -1;
       break;
 
     default:
       fprintf(stderr, "%s: invalid Intex Hex file I/O operation=%d\n",
               progname, fio->op);
-      return -5;
+      return -1;
       break;
   }
 
@@ -1013,7 +1026,7 @@ int fileio_srec ( struct fioparms * fio,
 {
   fprintf(stderr, "%s: Motorola S-Record %s format not yet supported\n",
           progname, fio->iodesc);
-  return -5;
+  return -1;
 }
 
 
@@ -1047,7 +1060,72 @@ int fileio_setparms ( int op, struct fioparms * fp )
 }
 
 
-int fileio ( int op, char * filename, int format, 
+
+int fmt_autodetect ( char * fname )
+{
+  FILE * f;
+  unsigned char buf[MAX_LINE_LEN];
+  int i;
+  int len;
+  int found;
+
+  f = fopen(fname, "r");
+  if (f == NULL) {
+    fprintf(stderr, "%s: error opening %s: %s\n",
+            progname, fname, strerror(errno));
+    return -1;
+  }
+
+  while (fgets((char *)buf, MAX_LINE_LEN, f)!=NULL) {
+    buf[MAX_LINE_LEN-1] = 0;
+    len = strlen((char *)buf);
+    if (buf[len-1] == '\n')
+      buf[--len] = 0;
+
+    /* check for binary data */
+    found = 0;
+    for (i=0; i<len; i++) {
+      if (buf[i] > 127) {
+        found = 1;
+        break;
+      }
+    }
+    if (found)
+      return FMT_RBIN;
+
+    /* check for lines that look like intel hex */
+    if ((buf[0] == ':') && (len >= 11)) {
+      found = 1;
+      for (i=1; i<len; i++) {
+        if (!isxdigit(buf[1])) {
+          found = 0;
+          break;
+        }
+      }
+      if (found)
+        return FMT_IHEX;
+    }
+
+    /* check for lines that look like motorola s-record */
+    if ((buf[0] == 'S') && (len >= 10) && isdigit(buf[1])) {
+      found = 1;
+      for (i=1; i<len; i++) {
+        if (!isxdigit(buf[1])) {
+          found = 0;
+          break;
+        }
+      }
+      if (found)
+        return FMT_SREC;
+    }
+  }
+
+  return -1;
+}
+
+
+
+int fileio ( int op, char * filename, FILEFMT format, 
              struct avrpart * p, AVRMEM memtype )
 {
   int rc;
@@ -1078,7 +1156,7 @@ int fileio ( int op, char * filename, int format,
     if (f == NULL) {
       fprintf(stderr, "%s: can't open %s file %s: %s\n",
               progname, fio.iodesc, fname, strerror(errno));
-      return -2;
+      return -1;
     }
   }
 
@@ -1096,7 +1174,7 @@ int fileio ( int op, char * filename, int format,
     default:
       fprintf(stderr, "%s: invalid memory type for %s: %d\n",
               progname, fio.iodesc, memtype);
-      return -3;
+      return -1;
   }
 
   if (fio.op == FIO_READ) {
@@ -1106,6 +1184,19 @@ int fileio ( int op, char * filename, int format,
     }
   }
 
+  if (format == FMT_AUTO) {
+    format = fmt_autodetect(fname);
+    if (format < 0) {
+      fprintf(stderr, 
+              "%s: can't determine file format for %s, specify explicitly\n",
+              progname, fname);
+      return -1;
+    }
+
+    fprintf(stderr, "%s: %s file %s auto detected as %s\n\n", 
+            progname, fio.iodesc, fname, fmtstr(format));
+  }
+
   switch (format) {
     case FMT_IHEX:
       rc = fileio_ihex(&fio, fname, f, buf, size);
@@ -1122,7 +1213,7 @@ int fileio ( int op, char * filename, int format,
     default:
       fprintf(stderr, "%s: invalid %s file format: %d\n",
               progname, fio.iodesc, format);
-      return -4;
+      return -1;
   }
 
   return rc;
@@ -1160,15 +1251,15 @@ int main ( int argc, char * argv [] )
   int              readorwrite; /* true if a chip read/write op was selected */
 
   /* options / operating mode variables */
-  int    memtype;     /* AVR_FLASH or AVR_EEPROM */
-  int    doread;      /* 0=reading, 1=writing */
-  int    erase;       /* 1=erase chip, 0=don't */
-  char * outputf;     /* output file name */
-  char * inputf;      /* input file name */
-  int    ovsigck;     /* 1=override sig check, 0=don't */
-  char * parallel;    /* parallel port device */
-  int    interactive; /* 1=enter interactive command mode, 0=don't */
-  int    filefmt;     /* FMT_AUTO, FMT_IHEX, FMT_SREC, FMT_RBIN */
+  int     memtype;     /* AVR_FLASH or AVR_EEPROM */
+  int     doread;      /* 0=reading, 1=writing */
+  int     erase;       /* 1=erase chip, 0=don't */
+  char  * outputf;     /* output file name */
+  char  * inputf;      /* input file name */
+  int     ovsigck;     /* 1=override sig check, 0=don't */
+  char  * parallel;    /* parallel port device */
+  int     interactive; /* 1=enter interactive command mode, 0=don't */
+  FILEFMT filefmt;     /* FMT_AUTO, FMT_IHEX, FMT_SREC, FMT_RBIN */
 
   readorwrite = 0;
   parallel    = DEFAULT_PARALLEL;
@@ -1517,7 +1608,7 @@ int main ( int argc, char * argv [] )
      * test mode, don't actually write to the chip, output the buffer
      * to stdout in intel hex instead 
      */
-    fileio(FIO_WRITE, "-", FMT_IHEX, p, memtype);
+    rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, memtype);
 #endif
     if (rc) {
       fprintf ( stderr, "%s: failed to write flash memory, rc=%d\n",