diff --git a/src/config.c b/src/config.c
index 063f17e7..2bf1ce27 100644
--- a/src/config.c
+++ b/src/config.c
@@ -74,21 +74,77 @@ Component_t avr_comp[] = {
 
   // AVRPART
   part_comp_desc(desc, COMP_STRING),
+  part_comp_desc(family_id, COMP_STRING),
   part_comp_desc(prog_modes, COMP_INT),
   part_comp_desc(mcuid, COMP_INT),
   part_comp_desc(n_interrupts, COMP_INT),
   part_comp_desc(n_page_erase, COMP_INT),
   part_comp_desc(n_boot_sections, COMP_INT),
   part_comp_desc(boot_section_size, COMP_INT),
-  part_comp_desc(autobaud_sync, COMP_CHAR),
+  part_comp_desc(hvupdi_variant, COMP_INT),
+  part_comp_desc(stk500_devcode, COMP_INT),
+  part_comp_desc(avr910_devcode, COMP_INT),
+  part_comp_desc(chip_erase_delay, COMP_INT),
+  part_comp_desc(pagel, COMP_CHAR),
+  part_comp_desc(bs2, COMP_CHAR),
+
+  part_comp_desc(timeout, COMP_INT),
+  part_comp_desc(stabdelay, COMP_INT),
+  part_comp_desc(cmdexedelay, COMP_INT),
+  part_comp_desc(synchloops, COMP_INT),
+  part_comp_desc(bytedelay, COMP_INT),
+  part_comp_desc(pollindex, COMP_INT),
+  part_comp_desc(pollvalue, COMP_CHAR),
+  part_comp_desc(predelay, COMP_INT),
+  part_comp_desc(postdelay, COMP_INT),
+  part_comp_desc(pollmethod, COMP_INT),
+
+  part_comp_desc(hventerstabdelay, COMP_INT), // STK500 v2 hv mode parameters
+  part_comp_desc(progmodedelay, COMP_INT),
+  part_comp_desc(latchcycles, COMP_INT),
+  part_comp_desc(togglevtg, COMP_INT),
+  part_comp_desc(poweroffdelay, COMP_INT),
+  part_comp_desc(resetdelayms, COMP_INT),
+  part_comp_desc(resetdelayus, COMP_INT),
+  part_comp_desc(hvleavestabdelay, COMP_INT),
+  part_comp_desc(resetdelay, COMP_INT),
+  part_comp_desc(chiperasepulsewidth, COMP_INT),
+  part_comp_desc(chiperasepolltimeout, COMP_INT),
+  part_comp_desc(chiperasetime, COMP_INT),
+  part_comp_desc(programfusepulsewidth, COMP_INT),
+  part_comp_desc(programfusepolltimeout, COMP_INT),
+  part_comp_desc(programlockpulsewidth, COMP_INT),
+  part_comp_desc(programlockpolltimeout, COMP_INT),
+  part_comp_desc(synchcycles, COMP_INT),
+  part_comp_desc(hvspcmdexedelay, COMP_INT),
+
   part_comp_desc(idr, COMP_CHAR),
   part_comp_desc(rampz, COMP_CHAR),
   part_comp_desc(spmcr, COMP_CHAR),
   part_comp_desc(eecr, COMP_CHAR),
   part_comp_desc(eind, COMP_CHAR),
+  part_comp_desc(mcu_base, COMP_INT),
+  part_comp_desc(nvm_base, COMP_INT),
+  part_comp_desc(ocd_base, COMP_INT),
+  part_comp_desc(ocdrev, COMP_INT),
+  part_comp_desc(autobaud_sync, COMP_CHAR),
 
   // AVRMEM
+  mem_comp_desc(paged, COMP_BOOL),
+  mem_comp_desc(size, COMP_INT),
+  mem_comp_desc(num_pages, COMP_INT),
   mem_comp_desc(n_word_writes, COMP_INT),
+  mem_comp_desc(offset, COMP_INT),
+  mem_comp_desc(min_write_delay, COMP_INT),
+  mem_comp_desc(max_write_delay, COMP_INT),
+  mem_comp_desc(pwroff_after_write, COMP_INT),
+  {"readback_p1", COMP_AVRMEM, offsetof(AVRMEM, readback)+0, 1, COMP_CHAR },
+  {"readback_p2", COMP_AVRMEM, offsetof(AVRMEM, readback)+1, 1, COMP_CHAR },
+  mem_comp_desc(mode, COMP_INT),
+  mem_comp_desc(delay, COMP_INT),
+  mem_comp_desc(pollindex, COMP_INT),
+  mem_comp_desc(blocksize, COMP_INT),
+  mem_comp_desc(readsize, COMP_INT),
 };
 
 #define DEBUG 0
@@ -290,6 +346,9 @@ TOKEN *new_constant(const char *con) {
     !strcmp("PM_XMEGAJTAG", con)? PM_XMEGAJTAG:
     !strcmp("PM_AVR32JTAG", con)? PM_AVR32JTAG:
     !strcmp("PM_aWire", con)? PM_aWire:
+    !strcmp("pseudo", con)? 2:
+    !strcmp("yes", con) || !strcmp("true", con)? 1:
+    !strcmp("no", con) || !strcmp("false", con)? 0:
     (assigned = 0);
 
   if(!assigned) {
@@ -810,6 +869,7 @@ const char *cfg_comp_type(int type) {
   case COMP_INT: return "number";
   case COMP_SHORT: return "short";
   case COMP_CHAR: return "char";
+  case COMP_BOOL: return "bool";
   case COMP_STRING: return "string";
   case COMP_CHAR_ARRAY: return "byte array";
   case COMP_INT_LISTID: return "number list";
@@ -828,6 +888,7 @@ void cfg_assign(char *sp, int strct, Component_t *cp, VALUE *v) {
   int num;
 
   switch(cp->type) {
+  case COMP_BOOL:
   case COMP_CHAR:
   case COMP_SHORT:
   case COMP_INT:
diff --git a/src/config.h b/src/config.h
index 8bacda42..0f10f801 100644
--- a/src/config.h
+++ b/src/config.h
@@ -48,6 +48,7 @@ enum {                          // Component types in structure
   COMP_INT,
   COMP_SHORT,
   COMP_CHAR,
+  COMP_BOOL,
   COMP_STRING,
   COMP_CHAR_ARRAY,              // This and below are not yet implemented
   COMP_INT_LISTID,
diff --git a/src/config_gram.y b/src/config_gram.y
index 8d54acf3..bc4411cf 100644
--- a/src/config_gram.y
+++ b/src/config_gram.y
@@ -71,12 +71,9 @@ static int pin_name;
 %token K_MEMORY
 
 %token K_PAGE_SIZE
-%token K_PAGED
 
 %token K_ALIAS
-%token K_BS2
 %token K_BUFF
-%token K_CHIP_ERASE_DELAY
 %token K_CONNTYPE
 %token K_DEDICATED
 %token K_DEFAULT_BITCLOCK
@@ -84,40 +81,23 @@ static int pin_name;
 %token K_DEFAULT_PROGRAMMER
 %token K_DEFAULT_SERIAL
 %token K_DEFAULT_SPI
-%token K_FAMILY_ID
 %token K_HVUPDI_SUPPORT
-%token K_HVUPDI_VARIANT
 %token K_DEVICECODE
-%token K_STK500_DEVCODE
-%token K_AVR910_DEVCODE
 %token K_EEPROM
 %token K_ERRLED
 %token K_FLASH
 %token K_ID
 %token K_IO
 %token K_LOADPAGE
-%token K_MAX_WRITE_DELAY
-%token K_MCU_BASE
-%token K_MIN_WRITE_DELAY
 %token K_SDI
 %token K_SDO
-%token K_NUM_PAGES
-%token K_NVM_BASE
-%token K_OCD_BASE
-%token K_OCDREV
-%token K_OFFSET
-%token K_PAGEL
 %token K_PARALLEL
 %token K_PARENT
 %token K_PART
 %token K_PGMLED
 %token K_PROGRAMMER
-%token K_PSEUDO
-%token K_PWROFF_AFTER_WRITE
 %token K_RDYLED
 %token K_READBACK
-%token K_READBACK_P1
-%token K_READBACK_P2
 %token K_READMEM
 %token K_RESET
 %token K_RETRY_PULSE
@@ -132,46 +112,8 @@ static int pin_name;
 %token K_VCC
 %token K_VFYLED
 
-%token K_NO
-%token K_YES
-
 /* stk500 v2 xml file parameters */
 /* ISP */
-%token K_TIMEOUT
-%token K_STABDELAY
-%token K_CMDEXEDELAY
-%token K_HVSPCMDEXEDELAY
-%token K_SYNCHLOOPS
-%token K_BYTEDELAY
-%token K_POLLVALUE
-%token K_POLLINDEX
-%token K_PREDELAY
-%token K_POSTDELAY
-%token K_POLLMETHOD
-%token K_MODE
-%token K_DELAY
-%token K_BLOCKSIZE
-%token K_READSIZE
-/* HV mode */
-%token K_HVENTERSTABDELAY
-%token K_PROGMODEDELAY
-%token K_LATCHCYCLES
-%token K_TOGGLEVTG
-%token K_POWEROFFDELAY
-%token K_RESETDELAYMS
-%token K_RESETDELAYUS
-%token K_HVLEAVESTABDELAY
-%token K_RESETDELAY
-%token K_SYNCHCYCLES
-%token K_HVCMDEXEDELAY
-
-%token K_CHIPERASEPULSEWIDTH
-%token K_CHIPERASEPOLLTIMEOUT
-%token K_CHIPERASETIME
-%token K_PROGRAMFUSEPULSEWIDTH
-%token K_PROGRAMFUSEPOLLTIMEOUT
-%token K_PROGRAMLOCKPULSEWIDTH
-%token K_PROGRAMLOCKPOLLTIMEOUT
 
 %token K_PP_CONTROLSTACK
 %token K_HVSP_CONTROLSTACK
@@ -638,10 +580,6 @@ reset_disposition :
   K_DEDICATED | K_IO
 ;
 
-parallel_modes :
-  yesno | K_PSEUDO
-;
-
 retry_lines :
   K_RESET | K_SCK
 ;
@@ -657,40 +595,13 @@ part_parm :
       free_token($3);
     } |
 
-  K_FAMILY_ID TKN_EQUAL TKN_STRING
-    {
-      current_part->family_id = cache_string($3->value.string);
-      free_token($3);
-    } |
-
-  K_HVUPDI_VARIANT TKN_EQUAL numexpr
-    {
-      current_part->hvupdi_variant = $3->value.number;
-      free_token($3);
-    } |
-
   K_DEVICECODE TKN_EQUAL numexpr {
     {
-      yyerror("devicecode is deprecated, use "
-              "stk500_devcode instead");
+      yyerror("devicecode is deprecated, use stk500_devcode instead");
       YYABORT;
     }
   } |
 
-  K_STK500_DEVCODE TKN_EQUAL numexpr {
-    {
-      current_part->stk500_devcode = $3->value.number;
-      free_token($3);
-    }
-  } |
-
-  K_AVR910_DEVCODE TKN_EQUAL numexpr {
-    {
-      current_part->avr910_devcode = $3->value.number;
-      free_token($3);
-    }
-  } |
-
   K_SIGNATURE TKN_EQUAL TKN_NUMBER TKN_NUMBER TKN_NUMBER {
     {
       current_part->signature[0] = $3->value.number;
@@ -857,24 +768,6 @@ part_parm :
     }
   } |
 
-  K_CHIP_ERASE_DELAY TKN_EQUAL numexpr
-    {
-      current_part->chip_erase_delay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_PAGEL TKN_EQUAL numexpr
-    {
-      current_part->pagel = $3->value.number;
-      free_token($3);
-    } |
-
-  K_BS2 TKN_EQUAL numexpr
-    {
-      current_part->bs2 = $3->value.number;
-      free_token($3);
-    } |
-
   K_RESET TKN_EQUAL reset_disposition
     {
       if ($3->primary == K_DEDICATED)
@@ -885,306 +778,139 @@ part_parm :
       free_tokens(2, $1, $3);
     } |
 
-  K_TIMEOUT TKN_EQUAL numexpr
+  K_HAS_JTAG TKN_EQUAL numexpr
     {
-      current_part->timeout = $3->value.number;
-      free_token($3);
-    } |
-
-  K_STABDELAY TKN_EQUAL numexpr
-    {
-      current_part->stabdelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_CMDEXEDELAY TKN_EQUAL numexpr
-    {
-      current_part->cmdexedelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_HVSPCMDEXEDELAY TKN_EQUAL numexpr
-    {
-      current_part->hvspcmdexedelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_SYNCHLOOPS TKN_EQUAL numexpr
-    {
-      current_part->synchloops = $3->value.number;
-      free_token($3);
-    } |
-
-  K_BYTEDELAY TKN_EQUAL numexpr
-    {
-      current_part->bytedelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_POLLVALUE TKN_EQUAL numexpr
-    {
-      current_part->pollvalue = $3->value.number;
-      free_token($3);
-    } |
-
-  K_POLLINDEX TKN_EQUAL numexpr
-    {
-      current_part->pollindex = $3->value.number;
-      free_token($3);
-    } |
-
-  K_PREDELAY TKN_EQUAL numexpr
-    {
-      current_part->predelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_POSTDELAY TKN_EQUAL numexpr
-    {
-      current_part->postdelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_POLLMETHOD TKN_EQUAL numexpr
-    {
-      current_part->pollmethod = $3->value.number;
-      free_token($3);
-    } |
-
-  K_HVENTERSTABDELAY TKN_EQUAL numexpr
-    {
-      current_part->hventerstabdelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_PROGMODEDELAY TKN_EQUAL numexpr
-    {
-      current_part->progmodedelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_LATCHCYCLES TKN_EQUAL numexpr
-    {
-      current_part->latchcycles = $3->value.number;
-      free_token($3);
-    } |
-
-  K_TOGGLEVTG TKN_EQUAL numexpr
-    {
-      current_part->togglevtg = $3->value.number;
-      free_token($3);
-    } |
-
-  K_POWEROFFDELAY TKN_EQUAL numexpr
-    {
-      current_part->poweroffdelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_RESETDELAYMS TKN_EQUAL numexpr
-    {
-      current_part->resetdelayms = $3->value.number;
-      free_token($3);
-    } |
-
-  K_RESETDELAYUS TKN_EQUAL numexpr
-    {
-      current_part->resetdelayus = $3->value.number;
-      free_token($3);
-    } |
-
-  K_HVLEAVESTABDELAY TKN_EQUAL numexpr
-    {
-      current_part->hvleavestabdelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_RESETDELAY TKN_EQUAL numexpr
-    {
-      current_part->resetdelay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_CHIPERASEPULSEWIDTH TKN_EQUAL numexpr
-    {
-      current_part->chiperasepulsewidth = $3->value.number;
-      free_token($3);
-    } |
-
-  K_CHIPERASEPOLLTIMEOUT TKN_EQUAL numexpr
-    {
-      current_part->chiperasepolltimeout = $3->value.number;
-      free_token($3);
-    } |
-
-  K_CHIPERASETIME TKN_EQUAL numexpr
-    {
-      current_part->chiperasetime = $3->value.number;
-      free_token($3);
-    } |
-
-  K_PROGRAMFUSEPULSEWIDTH TKN_EQUAL numexpr
-    {
-      current_part->programfusepulsewidth = $3->value.number;
-      free_token($3);
-    } |
-
-  K_PROGRAMFUSEPOLLTIMEOUT TKN_EQUAL numexpr
-    {
-      current_part->programfusepolltimeout = $3->value.number;
-      free_token($3);
-    } |
-
-  K_PROGRAMLOCKPULSEWIDTH TKN_EQUAL numexpr
-    {
-      current_part->programlockpulsewidth = $3->value.number;
-      free_token($3);
-    } |
-
-  K_PROGRAMLOCKPOLLTIMEOUT TKN_EQUAL numexpr
-    {
-      current_part->programlockpolltimeout = $3->value.number;
-      free_token($3);
-    } |
-
-  K_SYNCHCYCLES TKN_EQUAL numexpr
-    {
-      current_part->synchcycles = $3->value.number;
-      free_token($3);
-    } |
-
-  K_HAS_JTAG TKN_EQUAL yesno
-    {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->prog_modes |= PM_JTAG;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->prog_modes &= ~(PM_JTAG | PM_JTAGmkI | PM_XMEGAJTAG | PM_AVR32JTAG);
       free_token($3);
     } |
 
-  K_HAS_DW TKN_EQUAL yesno
+  K_HAS_DW TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->prog_modes |= PM_debugWIRE;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->prog_modes &= ~PM_debugWIRE;
       free_token($3);
     } |
 
-  K_HAS_PDI TKN_EQUAL yesno
+  K_HAS_PDI TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->prog_modes |= PM_PDI;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->prog_modes &= ~PM_PDI;
       free_token($3);
     } |
 
-  K_HAS_UPDI TKN_EQUAL yesno
+  K_HAS_UPDI TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->prog_modes |= PM_UPDI;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->prog_modes &= ~PM_UPDI;
       free_token($3);
     } |
 
-  K_HAS_TPI TKN_EQUAL yesno
+  K_HAS_TPI TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->prog_modes |= PM_TPI;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->prog_modes &= ~PM_TPI;
       free_token($3);
     } |
 
-  K_IS_AT90S1200 TKN_EQUAL yesno
+  K_IS_AT90S1200 TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->flags |= AVRPART_IS_AT90S1200;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->flags &= ~AVRPART_IS_AT90S1200;
+      else {
+        yyerror("not a Boolean value");
+        free_token($3);
+        YYABORT;
+      }
 
       free_token($3);
     } |
 
-  K_IS_AVR32 TKN_EQUAL yesno
+  K_IS_AVR32 TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->prog_modes |= PM_aWire;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->prog_modes &= ~PM_aWire;
       free_token($3);
     } |
 
-  K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL yesno
+  K_ALLOWFULLPAGEBITSTREAM TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->flags |= AVRPART_ALLOWFULLPAGEBITSTREAM;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->flags &= ~AVRPART_ALLOWFULLPAGEBITSTREAM;
+      else {
+        yyerror("not a Boolean value");
+        free_token($3);
+        YYABORT;
+      }
 
       free_token($3);
     } |
 
-  K_ENABLEPAGEPROGRAMMING TKN_EQUAL yesno
+  K_ENABLEPAGEPROGRAMMING TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->flags |= AVRPART_ENABLEPAGEPROGRAMMING;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->flags &= ~AVRPART_ENABLEPAGEPROGRAMMING;
+      else {
+        yyerror("not a Boolean value");
+        free_token($3);
+        YYABORT;
+      }
 
       free_token($3);
     } |
 
-  K_MCU_BASE TKN_EQUAL numexpr
+  K_SERIAL TKN_EQUAL numexpr
     {
-      current_part->mcu_base = $3->value.number;
-      free_token($3);
-    } |
-
-  K_NVM_BASE TKN_EQUAL numexpr
-    {
-      current_part->nvm_base = $3->value.number;
-      free_token($3);
-    } |
-
- K_OCD_BASE TKN_EQUAL numexpr
-    {
-      current_part->ocd_base = $3->value.number;
-      free_token($3);
-    } |
-
-  K_OCDREV          TKN_EQUAL numexpr
-    {
-      current_part->ocdrev = $3->value.number;
-      free_token($3);
-    } |
-
-  K_SERIAL TKN_EQUAL yesno
-    {
-      if ($3->primary == K_YES)
+      if ($3->value.number == 1)
         current_part->flags |= AVRPART_SERIALOK;
-      else if ($3->primary == K_NO)
+      else if ($3->value.number == 0)
         current_part->flags &= ~AVRPART_SERIALOK;
+      else {
+        yyerror("not a Boolean value");
+        free_token($3);
+        YYABORT;
+      }
 
       free_token($3);
     } |
 
-  K_PARALLEL TKN_EQUAL parallel_modes
+  K_PARALLEL TKN_EQUAL numexpr
     {
-      if ($3->primary == K_YES) {
+      if ($3->value.number == 1) {
         current_part->flags |= AVRPART_PARALLELOK;
         current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
       }
-      else if ($3->primary == K_NO) {
+      else if ($3->value.number == 0) {
         current_part->flags &= ~AVRPART_PARALLELOK;
         current_part->flags &= ~AVRPART_PSEUDOPARALLEL;
       }
-      else if ($3->primary == K_PSEUDO) {
+      else if ($3->value.number == 2) {
         current_part->flags |= AVRPART_PARALLELOK;
         current_part->flags |= AVRPART_PSEUDOPARALLEL;
       }
+      else {
+        yyerror("outside [0, 2] (yes/no/pseudo)");
+        free_token($3);
+        YYABORT;
+      }
 
 
       free_token($3);
@@ -1286,11 +1012,6 @@ part_parm :
 ;
 
 
-yesno :
-  K_YES | K_NO
-;
-
-
 mem_specs :
   mem_spec TKN_SEMI |
   mem_alias TKN_SEMI |
@@ -1304,19 +1025,6 @@ mem_spec :
     free_token($1);
   } |
 
-  K_PAGED          TKN_EQUAL yesno
-    {
-      current_mem->paged = $3->primary == K_YES ? 1 : 0;
-      free_token($3);
-    } |
-
-  K_SIZE            TKN_EQUAL numexpr
-    {
-      current_mem->size = $3->value.number;
-      free_token($3);
-    } |
-
-
   K_PAGE_SIZE       TKN_EQUAL numexpr
     {
       int ps = $3->value.number;
@@ -1327,36 +1035,6 @@ mem_spec :
       free_token($3);
     } |
 
-  K_NUM_PAGES       TKN_EQUAL numexpr
-    {
-      current_mem->num_pages = $3->value.number;
-      free_token($3);
-    } |
-
-  K_OFFSET          TKN_EQUAL numexpr
-    {
-      current_mem->offset = $3->value.number;
-      free_token($3);
-    } |
-
-  K_MIN_WRITE_DELAY TKN_EQUAL numexpr
-    {
-      current_mem->min_write_delay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_MAX_WRITE_DELAY TKN_EQUAL numexpr
-    {
-      current_mem->max_write_delay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_PWROFF_AFTER_WRITE TKN_EQUAL yesno
-    {
-      current_mem->pwroff_after_write = $3->primary == K_YES ? 1 : 0;
-      free_token($3);
-    } |
-
   K_READBACK        TKN_EQUAL TKN_NUMBER TKN_NUMBER
     {
       current_mem->readback[0] = $3->value.number;
@@ -1365,50 +1043,6 @@ mem_spec :
       free_token($4);
     } |
 
-  K_READBACK_P1     TKN_EQUAL numexpr
-    {
-      current_mem->readback[0] = $3->value.number;
-      free_token($3);
-    } |
-
-  K_READBACK_P2     TKN_EQUAL numexpr
-    {
-      current_mem->readback[1] = $3->value.number;
-      free_token($3);
-    } |
-
-
-  K_MODE TKN_EQUAL numexpr
-    {
-      current_mem->mode = $3->value.number;
-      free_token($3);
-    } |
-
-  K_DELAY TKN_EQUAL numexpr
-    {
-      current_mem->delay = $3->value.number;
-      free_token($3);
-    } |
-
-  K_BLOCKSIZE TKN_EQUAL numexpr
-    {
-      current_mem->blocksize = $3->value.number;
-      free_token($3);
-    } |
-
-  K_READSIZE TKN_EQUAL numexpr
-    {
-      current_mem->readsize = $3->value.number;
-      free_token($3);
-    } |
-
-  K_POLLINDEX TKN_EQUAL numexpr
-    {
-      current_mem->pollindex = $3->value.number;
-      free_token($3);
-    } |
-
-
   opcode TKN_EQUAL string_list {
     { 
       int opnum;
diff --git a/src/developer_opts_private.h b/src/developer_opts_private.h
index a9910fe0..43950313 100644
--- a/src/developer_opts_private.h
+++ b/src/developer_opts_private.h
@@ -62,6 +62,11 @@ static int dev_message(int msglvl, const char *fmt, ...);
     dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf(fmt, pgm->component), pgm->comments); \
 } while(0)
 
+#define _if_pgmout_bool(component) do { \
+  if(!base || !!base->component != !!pgm->component) \
+    dev_part_strct_entry(tsv, ".prog", id, NULL, #component, dev_sprintf("%s", pgm->component? "true": "false"), pgm->comments); \
+} while(0)
+
 // Result must be a malloc'd string
 #define _if_pgmout_str(cmp, result, component) do { \
   if(!base || cmp(base->component, pgm->component)) \
@@ -77,6 +82,11 @@ static int dev_message(int msglvl, const char *fmt, ...);
     dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments); \
 } while(0)
 
+#define _if_partout_bool(component) do { \
+  if(!base || !!base->component != !!p->component) \
+    dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf("%s", p->component? "true": "false"), p->comments); \
+} while(0)
+
 #define _if_n_partout(cmp, n, fmt, component) do { \
   if(!base || cmp(base->component, p->component, n)) \
     dev_part_strct_entry(tsv, ".pt", p->desc, NULL, #component, dev_sprintf(fmt, p->component), p->comments); \
@@ -120,6 +130,11 @@ static int dev_message(int msglvl, const char *fmt, ...);
 #define _memout_yn(component) \
   dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_memout_yn()", m->component? "yes": "no"), m->comments)
 
+#define _if_memout_bool(component) do { \
+  if(!bm || !!bm->component != !!m->component) \
+    dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, dev_sprintf("%s", m->component? "true": "false"), m->comments); \
+} while(0)
+
 #define _if_memout_yn(component) do { \
   if(!bm || bm->component != m->component) \
     dev_part_strct_entry(tsv, ".ptmm", p->desc, m->desc, #component, cfg_strdup("_if_memout_yn()", m->component? "yes": "no"), m->comments); \
diff --git a/src/lexer.l b/src/lexer.l
index 7408d5f5..0e52ef78 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -122,9 +122,16 @@ SIGN     [+-]
 
 
 (?x: desc | prog_modes | baudrate | usbvid | usbdev | usbsn | usbvendor | usbproduct |
-  mcuid | n_interrupts | n_page_erase | n_word_writes | n_boot_sections |
-  boot_section_size | autobaud_sync | idr | rampz | spmcr | eecr | eind ) { /* struct components */
-
+  family_id | mcuid | n_interrupts | n_page_erase | n_boot_sections | boot_section_size |
+  hvupdi_variant | stk500_devcode | avr910_devcode | chip_erase_delay | pagel | bs2 |
+  timeout | stabdelay | cmdexedelay | synchloops | bytedelay | pollindex | pollvalue | predelay | postdelay | pollmethod |
+  hventerstabdelay | progmodedelay | latchcycles | togglevtg | poweroffdelay | resetdelayms | resetdelayus | resetdelay | hvleavestabdelay |
+  chiperasetime | (chiperase|program(fuse|lock))(polltimeout|pulsewidth) | synchcycles | hvspcmdexedelay |
+  mcu_base | nvm_base | ocd_base | ocdrev |
+  autobaud_sync | idr | rampz | spmcr | eecr | eind |
+  paged | size | num_pages | n_word_writes | offset | min_write_delay | max_write_delay | pwroff_after_write |
+  readback_p1 | readback_p2 | mode | delay | blocksize | readsize ) {
+  /* struct components for PROGRAMMER, AVRPART and AVRMEM */
   Component_t *cp = cfg_comp_search(yytext, current_strct);
   if(!cp) {
     yyerror("unknown component %s in %s", yytext, cfg_strct_name(current_strct));
@@ -136,26 +143,17 @@ SIGN     [+-]
   return TKN_COMPONENT;
 }
 
-PM_(SPM|TPI|ISP|PDI|UPDI|HVSP|HVPP|debugWIRE|JTAG|JTAGmkI|XMEGAJTAG|AVR32JTAG|aWire) { /* Constants */
+
+(?x: PM_(SPM|TPI|ISP|PDI|UPDI|HVSP|HVPP|debugWIRE|JTAG|JTAGmkI|XMEGAJTAG|AVR32JTAG|aWire) |
+ yes|no|pseudo | true|false ) { /* Constants */
   yylval = new_constant(yytext);
   return TKN_NUMBER;
 }
 
 alias            { yylval=NULL; return K_ALIAS; }
 allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; }
-avr910_devcode   { yylval=NULL; ccap(); return K_AVR910_DEVCODE; }
-bank_size        { yylval=NULL; return K_PAGE_SIZE; }
-banked           { yylval=NULL; return K_PAGED; }
-blocksize        { yylval=NULL; ccap(); return K_BLOCKSIZE; }
-bs2              { yylval=NULL; ccap(); return K_BS2; }
 buff             { yylval=NULL; ccap(); return K_BUFF; }
-bytedelay        { yylval=NULL; ccap(); return K_BYTEDELAY; }
 chip_erase       { yylval=new_token(K_CHIP_ERASE); ccap(); return K_CHIP_ERASE; }
-chip_erase_delay { yylval=NULL; ccap(); return K_CHIP_ERASE_DELAY; }
-chiperasepolltimeout { yylval=NULL; ccap(); return K_CHIPERASEPOLLTIMEOUT; }
-chiperasepulsewidth { yylval=NULL; ccap(); return K_CHIPERASEPULSEWIDTH; }
-chiperasetime    { yylval=NULL; ccap(); return K_CHIPERASETIME; }
-cmdexedelay      { yylval=NULL; ccap(); return K_CMDEXEDELAY; }
 connection_type  { yylval=NULL; ccap(); return K_CONNTYPE; }
 dedicated        { yylval=new_token(K_DEDICATED); return K_DEDICATED; }
 default_bitclock { yylval=NULL; return K_DEFAULT_BITCLOCK; }
@@ -163,13 +161,11 @@ default_parallel { yylval=NULL; return K_DEFAULT_PARALLEL; }
 default_programmer { yylval=NULL; return K_DEFAULT_PROGRAMMER; }
 default_serial   { yylval=NULL; return K_DEFAULT_SERIAL; }
 default_spi      { yylval=NULL; return K_DEFAULT_SPI; }
-delay            { yylval=NULL; ccap(); return K_DELAY; }
 devicecode       { yylval=NULL; ccap(); return K_DEVICECODE; }
 eeprom           { yylval=NULL; return K_EEPROM; }
 eeprom_instr     { yylval=NULL; ccap(); return K_EEPROM_INSTR; }
 enablepageprogramming { yylval=NULL; ccap(); return K_ENABLEPAGEPROGRAMMING; }
 errled           { yylval=NULL; ccap(); return K_ERRLED; }
-family_id        { yylval=NULL; ccap(); return K_FAMILY_ID; }
 flash            { yylval=NULL; return K_FLASH; }
 flash_instr      { yylval=NULL; ccap(); return K_FLASH_INSTR; }
 has_debugwire    { yylval=NULL; ccap(); return K_HAS_DW; }
@@ -177,84 +173,40 @@ has_jtag         { yylval=NULL; ccap(); return K_HAS_JTAG; }
 has_pdi          { yylval=NULL; ccap(); return K_HAS_PDI; }
 has_tpi          { yylval=NULL; ccap(); return K_HAS_TPI; }
 has_updi         { yylval=NULL; ccap(); return K_HAS_UPDI; }
-hventerstabdelay { yylval=NULL; ccap(); return K_HVENTERSTABDELAY; }
-hvleavestabdelay { yylval=NULL; ccap(); return K_HVLEAVESTABDELAY; }
 hvsp_controlstack  { yylval=NULL; ccap(); return K_HVSP_CONTROLSTACK; }
-hvspcmdexedelay  { yylval=NULL; ccap(); return K_HVSPCMDEXEDELAY; }
 hvupdi_support   { yylval=NULL; ccap(); return K_HVUPDI_SUPPORT; }
-hvupdi_variant   { yylval=NULL; ccap(); return K_HVUPDI_VARIANT; }
 id               { yylval=NULL; ccap(); return K_ID; }
 io               { yylval=new_token(K_IO); return K_IO; }
 is_at90s1200     { yylval=NULL; ccap(); return K_IS_AT90S1200; }
 is_avr32         { yylval=NULL; ccap(); return K_IS_AVR32; }
-latchcycles      { yylval=NULL; ccap(); return K_LATCHCYCLES; }
 load_ext_addr    { yylval=new_token(K_LOAD_EXT_ADDR); ccap(); return K_LOAD_EXT_ADDR; }
 loadpage_hi      { yylval=new_token(K_LOADPAGE_HI); ccap(); return K_LOADPAGE_HI; }
 loadpage_lo      { yylval=new_token(K_LOADPAGE_LO); ccap(); return K_LOADPAGE_LO; }
-max_write_delay  { yylval=NULL; ccap(); return K_MAX_WRITE_DELAY; }
-mcu_base         { yylval=NULL; ccap(); return K_MCU_BASE; }
 memory           { yylval=NULL; ccap(); current_strct = COMP_AVRMEM; return K_MEMORY; }
-min_write_delay  { yylval=NULL; ccap(); return K_MIN_WRITE_DELAY; }
 miso             { yylval=NULL; ccap(); return K_SDI; } // Deprecated
-mode             { yylval=NULL; ccap(); return K_MODE; }
 mosi             { yylval=NULL; ccap(); return K_SDO; } // Deprecated
-no               { yylval=new_token(K_NO); return K_NO; }
 NULL             { yylval=NULL; return K_NULL; }
-num_banks        { yylval=NULL; return K_NUM_PAGES; }
-num_pages        { yylval=NULL; ccap(); return K_NUM_PAGES; }
-nvm_base         { yylval=NULL; ccap(); return K_NVM_BASE; }
-ocd_base         { yylval=NULL; ccap(); return K_OCD_BASE; }
-ocdrev           { yylval=NULL; ccap(); return K_OCDREV; }
-offset           { yylval=NULL; ccap(); return K_OFFSET; }
-paged            { yylval=NULL; ccap(); return K_PAGED; }
-pagel            { yylval=NULL; ccap(); return K_PAGEL; }
 page_size        { yylval=NULL; ccap(); return K_PAGE_SIZE; }
 parallel         { yylval=NULL; ccap(); return K_PARALLEL; }
 parent           { yylval=NULL; return K_PARENT; }
 part             { yylval=NULL; ccap(); current_strct = COMP_AVRPART; return K_PART; }
 pgm_enable       { yylval=new_token(K_PGM_ENABLE); ccap(); return K_PGM_ENABLE; }
 pgmled           { yylval=NULL; ccap(); return K_PGMLED; }
-pollindex        { yylval=NULL; ccap(); return K_POLLINDEX; }
-pollmethod       { yylval=NULL; ccap(); return K_POLLMETHOD; }
-pollvalue        { yylval=NULL; ccap(); return K_POLLVALUE; }
-postdelay        { yylval=NULL; ccap(); return K_POSTDELAY; }
-poweroffdelay    { yylval=NULL; ccap(); return K_POWEROFFDELAY; }
 pp_controlstack  { yylval=NULL; ccap(); return K_PP_CONTROLSTACK; }
-predelay         { yylval=NULL; ccap(); return K_PREDELAY; }
-progmodedelay    { yylval=NULL; ccap(); return K_PROGMODEDELAY; }
-programfusepolltimeout { yylval=NULL; ccap(); return K_PROGRAMFUSEPOLLTIMEOUT; }
-programfusepulsewidth { yylval=NULL; ccap(); return K_PROGRAMFUSEPULSEWIDTH; }
-programlockpolltimeout { yylval=NULL; ccap(); return K_PROGRAMLOCKPOLLTIMEOUT; }
-programlockpulsewidth { yylval=NULL; ccap(); return K_PROGRAMLOCKPULSEWIDTH; }
 programmer       { yylval=NULL; ccap(); current_strct = COMP_PROGRAMMER; return K_PROGRAMMER; }
-pseudo           { yylval=new_token(K_PSEUDO); return K_PSEUDO; }
-pwroff_after_write { yylval=NULL; ccap(); return K_PWROFF_AFTER_WRITE; }
 rdyled           { yylval=NULL; ccap(); return K_RDYLED; }
 read             { yylval=new_token(K_READ); ccap(); return K_READ; }
 read_hi          { yylval=new_token(K_READ_HI); ccap(); return K_READ_HI; }
 read_lo          { yylval=new_token(K_READ_LO); ccap(); return K_READ_LO; }
 readback         { yylval=NULL; ccap(); return K_READBACK; }
-readback_p1      { yylval=NULL; ccap(); return K_READBACK_P1; }
-readback_p2      { yylval=NULL; ccap(); return K_READBACK_P2; }
-readsize        { yylval=NULL; ccap(); return K_READSIZE; }
 reset            { yylval=new_token(K_RESET); ccap(); return K_RESET; }
-resetdelay       { yylval=NULL; ccap(); return K_RESETDELAY; }
-resetdelayms     { yylval=NULL; ccap(); return K_RESETDELAYMS; }
-resetdelayus     { yylval=NULL; ccap(); return K_RESETDELAYUS; }
 retry_pulse      { yylval=NULL; ccap(); return K_RETRY_PULSE; }
 sck              { yylval=new_token(K_SCK); ccap(); return K_SCK; }
 sdi              { yylval=NULL; ccap(); return K_SDI; }
 sdo              { yylval=NULL; ccap(); return K_SDO; }
 serial           { yylval=NULL; ccap(); return K_SERIAL; }
 signature        { yylval=NULL; ccap(); return K_SIGNATURE; }
-size             { yylval=NULL; ccap(); return K_SIZE; }
 spi              { yylval=NULL; return K_SPI; }
-stabdelay        { yylval=NULL; ccap(); return K_STABDELAY; }
-stk500_devcode   { yylval=NULL; ccap(); return K_STK500_DEVCODE; }
-synchcycles      { yylval=NULL; ccap(); return K_SYNCHCYCLES; }
-synchloops       { yylval=NULL; ccap(); return K_SYNCHLOOPS; }
-timeout          { yylval=NULL; ccap(); return K_TIMEOUT; }
-togglevtg        { yylval=NULL; ccap(); return K_TOGGLEVTG; }
 type             { yylval=NULL; ccap(); return K_TYPE; }
 usb              { yylval=NULL; return K_USB; }
 usbpid           { yylval=NULL; ccap(); return K_USBPID; }
@@ -264,7 +216,6 @@ write            { yylval=new_token(K_WRITE); ccap(); return K_WRITE; }
 write_hi         { yylval=new_token(K_WRITE_HI); ccap(); return K_WRITE_HI; }
 write_lo         { yylval=new_token(K_WRITE_LO); ccap(); return K_WRITE_LO; }
 writepage        { yylval=new_token(K_WRITEPAGE); ccap(); return K_WRITEPAGE; }
-yes              { yylval=new_token(K_YES); return K_YES; }
 
 ","       { yylval = NULL; pyytext(); return TKN_COMMA; }
 "="       { yylval = NULL; pyytext(); return TKN_EQUAL; }