diff --git a/avr.c b/avr.c
index c9b6e880..5d322cff 100644
--- a/avr.c
+++ b/avr.c
@@ -58,6 +58,7 @@ AVRPART * avr_new_part(void)
   p->id[0]   = 0;
   p->desc[0] = 0;
   p->reset_disposition = RESET_DEDICATED;
+  p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK;
 
   p->mem = lcreat(NULL, 0);
 
@@ -1073,17 +1074,22 @@ void avr_display(FILE * f, AVRPART * p, char * prefix, int verbose)
   AVRMEM * m;
 
   fprintf(f, 
-          "%sAVR Part          : %s\n"
-          "%sChip Erase delay  : %d us\n"
-          "%sPAGEL             : P%02X\n"
-          "%sBS2               : P%02X\n"
-          "%sRESET disposition : %s\n"
-          "%sMemory Detail     :\n\n",
+          "%sAVR Part              : %s\n"
+          "%sChip Erase delay      : %d us\n"
+          "%sPAGEL                 : P%02X\n"
+          "%sBS2                   : P%02X\n"
+          "%sRESET disposition     : %s\n"
+          "%sserial program mode   : %s\n"
+          "%sparallel program mode : %s\n"
+          "%sMemory Detail         :\n\n",
           prefix, p->desc,
           prefix, p->chip_erase_delay,
           prefix, p->pagel,
           prefix, p->bs2,
           prefix, reset_disp_str(p->reset_disposition),
+          prefix, (p->flags & AVRPART_SERIALOK) ? "yes" : "no",
+          prefix, (p->flags & AVRPART_PARALLELOK) ? 
+            ((p->flags & AVRPART_PSEUDOPARALLEL) ? "psuedo" : "yes") : "no",
           prefix);
 
   px = prefix;
diff --git a/avrdude.conf.sample b/avrdude.conf.sample
index 210c7d79..6c2853e1 100644
--- a/avrdude.conf.sample
+++ b/avrdude.conf.sample
@@ -1085,6 +1085,8 @@ part
     pagel            = 0xD7;
     bs2              = 0xA0;
     reset            = dedicated;
+    serial           = yes;
+    parallel         = yes;
     pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1",
                        "x x x x  x x x x    x x x x  x x x x";
 
diff --git a/avrpart.h b/avrpart.h
index 6ad78618..c788af66 100644
--- a/avrpart.h
+++ b/avrpart.h
@@ -70,6 +70,10 @@ typedef struct opcode {
 } OPCODE;
 
 
+#define AVRPART_SERIALOK       0x0001  /* part supports serial programming */
+#define AVRPART_PARALLELOK     0x0002  /* part supports parallel programming */
+#define AVRPART_PSEUDOPARALLEL 0x0004  /* part has pseudo parallel support */
+
 #define AVR_DESCLEN 64
 #define AVR_IDLEN   32
 typedef struct avrpart {
@@ -80,6 +84,7 @@ typedef struct avrpart {
   unsigned char pagel;              /* for parallel programming */
   unsigned char bs2;                /* for parallel programming */
   int           reset_disposition;  /* see RESET_ enums */
+  unsigned      flags;              /* see AVRPART_ masks */
 
   OPCODE      * op[AVR_OP_MAX];     /* opcodes */
 
diff --git a/config_gram.y b/config_gram.y
index 0cea7aef..1685a5e3 100644
--- a/config_gram.y
+++ b/config_gram.y
@@ -82,15 +82,18 @@ static int parse_cmdbits(OPCODE * op);
 %token K_NUM_PAGES
 %token K_PAGEL
 %token K_PAR
+%token K_PARALLEL
 %token K_PART
 %token K_PGMLED
 %token K_PROGRAMMER
+%token K_PSEUDO
 %token K_PWROFF_AFTER_WRITE
 %token K_RDYLED
 %token K_READBACK_P1
 %token K_READBACK_P2
 %token K_READMEM
 %token K_RESET
+%token K_SERIAL
 %token K_SCK
 %token K_SIZE
 %token K_STK500
@@ -340,6 +343,10 @@ reset_disposition :
   K_DEDICATED | K_IO
 ;
 
+parallel_modes :
+  yesno | K_PSEUDO
+;
+
 part_parm :
   K_ID TKN_EQUAL TKN_STRING 
     {
@@ -390,6 +397,35 @@ part_parm :
       free_token($3);
     } |
 
+  K_SERIAL TKN_EQUAL yesno
+    {
+      if ($3->primary == K_YES)
+        current_part->flags |= AVRPART_SERIALOK;
+      else if ($3->primary == K_NO)
+        current_part->flags &= ~AVRPART_SERIALOK;
+
+      free_token($3);
+    } |
+
+  K_PARALLEL TKN_EQUAL parallel_modes
+    {
+      if ($3->primary == K_YES) {
+        current_part->flags |= AVRPART_PARALLELOK;
+        current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
+      }
+      else if ($3->primary == K_NO) {
+        current_part->flags &= ~AVRPART_PARALLELOK;
+        current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
+      }
+      else if ($3->primary == K_PSEUDO) {
+        current_part->flags |= AVRPART_PARALLELOK;
+        current_part->flags |= AVRPART_PSEUDOPARALLEL;
+      }
+
+
+      free_token($3);
+    } |
+
 /*
   K_EEPROM { current_mem = AVR_M_EEPROM; }
     mem_specs |
diff --git a/lexer.l b/lexer.l
index 7131c036..a093b9aa 100644
--- a/lexer.l
+++ b/lexer.l
@@ -137,16 +137,19 @@ num_pages        { yylval=NULL; return K_NUM_PAGES; }
 page_size        { yylval=NULL; return K_PAGE_SIZE; }
 paged            { yylval=NULL; return K_PAGED; }
 pagel            { yylval=NULL; return K_PAGEL; }
+par              { yylval=NULL; return K_PAR; }
+parallel         { yylval=NULL; return K_PARALLEL; }
 part             { yylval=NULL; return K_PART; }
 pgmled           { yylval=NULL; return K_PGMLED; }
-par              { yylval=NULL; return K_PAR; }
 programmer       { yylval=NULL; return K_PROGRAMMER; }
+pseudo           { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
 pwroff_after_write { yylval=NULL; return K_PWROFF_AFTER_WRITE; }
 rdyled           { yylval=NULL; return K_RDYLED; }
 readback_p1      { yylval=NULL; return K_READBACK_P1; }
 readback_p2      { yylval=NULL; return K_READBACK_P2; }
 reset            { yylval=NULL; return K_RESET; }
 sck              { yylval=NULL; return K_SCK; }
+serial           { yylval=NULL; return K_SERIAL; }
 size             { yylval=NULL; return K_SIZE; }
 stk500           { yylval=NULL; return K_STK500; }
 type             { yylval=NULL; return K_TYPE; }
diff --git a/stk500.c b/stk500.c
index c4dd00e2..f231abea 100644
--- a/stk500.c
+++ b/stk500.c
@@ -442,8 +442,17 @@ static int stk500_initialize(PROGRAMMER * pgm, AVRPART * p)
 
   buf[1] = p->devicecode;
   buf[2] = 0; /* device revision */
-  buf[3] = 0; /* parallel and serial programming */
-  buf[4] = 1; /* full parallel interface */
+
+  if ((p->flags & AVRPART_SERIALOK) && (p->flags & AVRPART_PARALLELOK))
+    buf[3] = 0; /* device supports parallel and serial programming */
+  else
+    buf[3] = 1; /* device supports parallel only */
+
+  if ((p->flags & AVRPART_PARALLELOK) && (p->flags & AVRPART_PSEUDOPARALLEL))
+    buf[4] = 1; /* full parallel interface */
+  else
+    buf[4] = 0; /* pseudo parallel interface */
+    
   buf[5] = 1; /* polling supported - XXX need this in config file */
   buf[6] = 1; /* programming is self-timed - XXX need in config file */