diff --git a/src/avrdude.conf.in b/src/avrdude.conf.in
index 56ecc8ab..43dbe767 100644
--- a/src/avrdude.conf.in
+++ b/src/avrdude.conf.in
@@ -403,6 +403,7 @@ default_spi        = "@DEFAULT_SPI_PORT@";
 # default_bitclock = 2.5;
 
 @HAVE_PARPORT_BEGIN@
+
 # Parallel port programmers
 
 #------------------------------------------------------------
@@ -845,7 +846,7 @@ programmer parent "ft2232h"
 
 programmer parent "ft2232h"
     id                     = "2232hio";
-    desc                   = "FT2232H based generic programmer";
+    desc                   = "2232hio based on FT2232H with buffer and LEDs";
     buff                   = ~4;
 # LED SIGNALs
     errled                 = ~11;
@@ -858,18 +859,15 @@ programmer parent "ft2232h"
 # tigard
 #------------------------------------------------------------
 
-# Tigard - FT2232H based multi-protocol tool for hardware hacking.
+# Tigard - FT2232H based multi-protocol tool for hardware hacking
 # https://github.com/tigard-tools/tigard
 
 programmer parent "ft2232h"
     id                     = "tigard";
     desc                   = "Tigard interface board";
     usbdev                 = "B";
-# ISP-signals
+# Reset is different to the FT2232H; sck, sdo, sdi remain at 0, 1, 2
     reset                  = 5; # BD5 (GPIOL1)
-    sck                    = 0; # BD0 (TCK)
-    sdo                    = 1; # BD1 (TDI)
-    sdi                    = 2; # BD2 (TDO)
 ;
 
 #------------------------------------------------------------
@@ -891,7 +889,6 @@ programmer parent "ft2232h"
 
 programmer parent "ft4232h"
     id                     = "4232h";
-    desc                   = "FT4232H based generic programmer";
 ;
 
 #------------------------------------------------------------
@@ -954,7 +951,6 @@ programmer
 programmer parent "ft232h"
     id                     = "um232h";
     desc                   = "UM232H module from FTDI";
-    usbpid                 = 0x6014;
 ;
 
 #------------------------------------------------------------
@@ -972,7 +968,6 @@ programmer parent "ft232h"
 programmer parent "ft232h"
     id                     = "c232hm";
     desc                   = "C232HM cable from FTDI";
-    usbpid                 = 0x6014;
 ;
 
 #------------------------------------------------------------
@@ -8695,6 +8690,7 @@ part
     mcuid                  = 167;
     n_interrupts           = 32;
     n_boot_sections        = 4;
+    boot_section_size      = 256;
     stk500_devcode         = 0x65;
     chip_erase_delay       = 9000;
     pagel                  = 0xd8;
@@ -8823,7 +8819,6 @@ part parent "pwm2"
     desc                   = "AT90PWM3";
     id                     = "pwm3";
     mcuid                  = 169;
-    boot_section_size      = 256;
 ;
 
 #------------------------------------------------------------
@@ -8835,7 +8830,6 @@ part parent "pwm2"
     desc                   = "AT90PWM2B";
     id                     = "pwm2b";
     mcuid                  = 168;
-    boot_section_size      = 256;
     signature              = 0x1e 0x93 0x83;
     ocdrev                 = 1;
 ;
@@ -13641,11 +13635,7 @@ part parent ".reduced_core_tiny"
     ;
 
     memory "fuse"
-        size               = 1;
-        page_size          = 16;
         n_word_writes      = 2;
-        offset             = 0x3f40;
-        blocksize          = 4;
     ;
 ;
 
@@ -13669,11 +13659,7 @@ part parent ".reduced_core_tiny"
     ;
 
     memory "fuse"
-        size               = 1;
-        page_size          = 16;
         n_word_writes      = 4;
-        offset             = 0x3f40;
-        blocksize          = 4;
     ;
 ;
 
@@ -13784,10 +13770,6 @@ part
         size               = 1;
     ;
 
-    memory "lockbits"
-        size               = 1;
-    ;
-
     memory "signature"
         size               = 3;
     ;
diff --git a/src/avrintel.c b/src/avrintel.c
index f0033cce..f24c4d91 100644
--- a/src/avrintel.c
+++ b/src/avrintel.c
@@ -9,7 +9,7 @@
  * meta-author Stefan Rueger <stefan.rueger@urclocks.com>
  *
  * v 1.1
- * 24.11.2022
+ * 02.01.2023
  *
  */
 
@@ -42,7 +42,7 @@ const uPcore_t uP_table[] = {   // Value of -1 typically means unknown
   {"ATtiny13",          10,  F_AVR8, {0x1E, 0x90, 0x07},       0, 0x00400, 0x020,  0,      0,       0, 0x0040,  4, 0x0060, 0x0040,  2,  1,  10,  vtab_attiny13a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny13A",         11,  F_AVR8, {0x1E, 0x90, 0x07},       0, 0x00400, 0x020,  0,      0,       0, 0x0040,  4, 0x0060, 0x0040,  2,  1,  10,  vtab_attiny13a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny15",          12,  F_AVR8, {0x1E, 0x90, 0x06},       0, 0x00400, 0x001,  0,      0,       0, 0x0040,  2, 0x0060, 0x0020,  1,  1,   9,   vtab_attiny15}, // atdf, avr-gcc 12.2.0, avrdude
-  {"ATtiny22",          13,  F_AVR8, {0x1E, 0x91, 0x06},       0, 0x00800,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0080,  1,  1,   3,   vtab_attiny22}, // avr-gcc 12.2.0
+  {"ATtiny22",          13,  F_AVR8, {0x1E, 0x91, 0x06},       0, 0x00800,    -1,  0,      0,      -1,     -1, -1, 0x0060, 0x0080,  1,  1,   3,   vtab_attiny22}, // avr-gcc 12.2.0, boot size (manual)
   {"ATtiny24",          14,  F_AVR8, {0x1E, 0x91, 0x0B},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  17,  vtab_attiny84a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny24A",         15,  F_AVR8, {0x1E, 0x91, 0x0B},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  17,  vtab_attiny84a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny25",          16,  F_AVR8, {0x1E, 0x91, 0x08},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  15,   vtab_attiny85}, // atdf, avr-gcc 12.2.0, avrdude
@@ -65,12 +65,12 @@ const uPcore_t uP_table[] = {   // Value of -1 typically means unknown
   {"ATtiny461",         33,  F_AVR8, {0x1E, 0x92, 0x08},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  19, vtab_attiny861a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny461A",        34,  F_AVR8, {0x1E, 0x92, 0x08},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  19, vtab_attiny861a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny828",         35,  F_AVR8, {0x1E, 0x93, 0x14},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  26,  vtab_attiny828}, // atdf, avr-gcc 12.2.0, avrdude
-  {"ATtiny828R",        36,  F_AVR8, {0x1E, 0x93, 0x14},       0, 0x02000, 0x040, -1,     -1,       0, 0x0100,  4,     -1,     -1, -1, -1,   0,            NULL}, // avrdude
+  {"ATtiny828R",        36,  F_AVR8, {0x1E, 0x93, 0x14},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0100,  4, 0x0100, 0x0200,  3,  1,  26,  vtab_attiny828}, // avrdude, from ATtiny828
   {"ATtiny841",         37,  F_AVR8, {0x1E, 0x93, 0x15},       0, 0x02000, 0x010,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  30,  vtab_attiny841}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny861",         38,  F_AVR8, {0x1E, 0x93, 0x0D},       0, 0x02000, 0x040,  0,      0,       0, 0x0200,  4, 0x0060, 0x0200,  3,  1,  19, vtab_attiny861a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny861A",        39,  F_AVR8, {0x1E, 0x93, 0x0D},       0, 0x02000, 0x040,  0,      0,       0, 0x0200,  4, 0x0060, 0x0200,  3,  1,  19, vtab_attiny861a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny1634",        40,  F_AVR8, {0x1E, 0x94, 0x12},       0, 0x04000, 0x020,  0,      0,       0, 0x0100,  4, 0x0100, 0x0400,  3,  1,  28, vtab_attiny1634}, // atdf, avr-gcc 12.2.0, avrdude
-  {"ATtiny1634R",       41,  F_AVR8, {0x1E, 0x94, 0x12},       0, 0x04000, 0x020, -1,     -1,       0, 0x0100,  4,     -1,     -1, -1, -1,   0,            NULL}, // avrdude
+  {"ATtiny1634R",       41,  F_AVR8, {0x1E, 0x94, 0x12},       0, 0x04000, 0x020,  0,      0,       0, 0x0100,  4, 0x0100, 0x0400,  3,  1,  28, vtab_attiny1634}, // avrdude, from ATtiny1634
   {"ATtiny2313",        42,  F_AVR8, {0x1E, 0x91, 0x0A},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  19, vtab_attiny2313}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny2313A",       43,  F_AVR8, {0x1E, 0x91, 0x0A},       0, 0x00800, 0x020,  0,      0,       0, 0x0080,  4, 0x0060, 0x0080,  3,  1,  21, vtab_attiny4313}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATtiny4313",        44,  F_AVR8, {0x1E, 0x92, 0x0D},       0, 0x01000, 0x040,  0,      0,       0, 0x0100,  4, 0x0060, 0x0100,  3,  1,  21, vtab_attiny4313}, // atdf, avr-gcc 12.2.0, avrdude
@@ -113,7 +113,7 @@ const uPcore_t uP_table[] = {   // Value of -1 typically means unknown
   {"ATmega88P",         81,  F_AVR8, {0x1E, 0x93, 0x0F},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26, vtab_atmega328p}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATmega88PA",        82,  F_AVR8, {0x1E, 0x93, 0x0F},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  26, vtab_atmega328p}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATmega88PB",        83,  F_AVR8, {0x1E, 0x93, 0x16},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  27, vtab_atmega168pb}, // atdf, avr-gcc 12.2.0, avrdude
-  {"ATmega103",         84,  F_AVR8, {0x1E, 0x97, 0x01},       0, 0x20000, 0x100, -1,     -1,       0, 0x1000,  1, 0x0060, 0x0fa0,  1,  1,  24,  vtab_atmega103}, // avr-gcc 12.2.0, avrdude
+  {"ATmega103",         84,  F_AVR8, {0x1E, 0x97, 0x01},       0, 0x20000, 0x100,  0,      0,       0, 0x1000,  1, 0x0060, 0x0fa0,  1,  1,  24,  vtab_atmega103}, // avr-gcc 12.2.0, avrdude, boot size (manual)
   {"ATmega128",         85,  F_AVR8, {0x1E, 0x97, 0x02},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x1000,  3,  1,  35, vtab_atmega128a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATmega128A",        86,  F_AVR8, {0x1E, 0x97, 0x02},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x1000,  3,  1,  35, vtab_atmega128a}, // atdf, avr-gcc 12.2.0, avrdude
   {"ATmega128RFA1",     87,  F_AVR8, {0x1E, 0xA7, 0x01},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0200, 0x4000,  3,  1,  72, vtab_atmega128rfa1}, // atdf, avr-gcc 12.2.0, avrdude
@@ -196,7 +196,7 @@ const uPcore_t uP_table[] = {   // Value of -1 typically means unknown
   {"AT76C711",         164,  F_AVR8, {0xff,   -1,   -1},       0, 0x04000,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x07a0, -1, -1,   0,            NULL}, // avr-gcc 12.2.0
   {"AT86RF401",        165,  F_AVR8, {0x1E, 0x91, 0x81},       0, 0x00800,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0080,  0,  1,   3,  vtab_at86rf401}, // avr-gcc 12.2.0
   {"AT90PWM1",         166,  F_AVR8, {0x1E, 0x93, 0x83},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32, vtab_at90pwm316}, // atdf, avr-gcc 12.2.0
-  {"AT90PWM2",         167,  F_AVR8, {0x1E, 0x93, 0x81},       0, 0x02000, 0x040,  4,     -1,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32,   vtab_at90pwm2}, // avr-gcc 12.2.0, avrdude
+  {"AT90PWM2",         167,  F_AVR8, {0x1E, 0x93, 0x81},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32,   vtab_at90pwm2}, // avr-gcc 12.2.0, avrdude, boot size (manual)
   {"AT90PWM2B",        168,  F_AVR8, {0x1E, 0x93, 0x83},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32,  vtab_at90pwm3b}, // atdf, avr-gcc 12.2.0, avrdude
   {"AT90PWM3",         169,  F_AVR8, {0x1E, 0x93, 0x81},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32,  vtab_at90pwm3b}, // atdf, avr-gcc 12.2.0, avrdude
   {"AT90PWM3B",        170,  F_AVR8, {0x1E, 0x93, 0x83},       0, 0x02000, 0x040,  4, 0x0100,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  32,  vtab_at90pwm3b}, // atdf, avr-gcc 12.2.0, avrdude
@@ -212,19 +212,19 @@ const uPcore_t uP_table[] = {   // Value of -1 typically means unknown
   {"AT90PWM316",       180,  F_AVR8, {0x1E, 0x94, 0x83},       0, 0x04000, 0x080,  4, 0x0200,       0, 0x0200,  4, 0x0100, 0x0400,  3,  1,  32, vtab_at90pwm316}, // atdf, avr-gcc 12.2.0, avrdude
   {"AT90USB646",       181,  F_AVR8, {0x1E, 0x96, 0x82},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  38, vtab_atmega32u6}, // atdf, avr-gcc 12.2.0, avrdude
   {"AT90USB647",       182,  F_AVR8, {0x1E, 0x96, 0x82},       0, 0x10000, 0x100,  4, 0x0400,       0, 0x0800,  8, 0x0100, 0x1000,  3,  1,  38, vtab_atmega32u6}, // atdf, avr-gcc 12.2.0, avrdude
-  {"AT90S1200",        183,  F_AVR8, {0x1E, 0x90, 0x01},       0, 0x00400, 0x001, -1,     -1,       0, 0x0040,  1, 0x0060, 0x0020,  1,  1,   4,  vtab_at90s1200}, // avr-gcc 12.2.0, avrdude
+  {"AT90S1200",        183,  F_AVR8, {0x1E, 0x90, 0x01},       0, 0x00400, 0x001,  0,      0,       0, 0x0040,  1, 0x0060, 0x0020,  1,  1,   4,  vtab_at90s1200}, // avr-gcc 12.2.0, avrdude, boot size (manual)
   {"AT90USB1286",      184,  F_AVR8, {0x1E, 0x97, 0x82},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x2000,  3,  1,  38, vtab_atmega32u6}, // atdf, avr-gcc 12.2.0, avrdude
   {"AT90USB1287",      185,  F_AVR8, {0x1E, 0x97, 0x82},       0, 0x20000, 0x100,  4, 0x0400,       0, 0x1000,  8, 0x0100, 0x2000,  3,  1,  38, vtab_atmega32u6}, // atdf, avr-gcc 12.2.0, avrdude
-  {"AT90S2313",        186,  F_AVR8, {0x1E, 0x91, 0x01},       0, 0x00800, 0x001, -1,     -1,       0, 0x0080,  1, 0x0060, 0x0080,  1,  1,  11,  vtab_at90s2313}, // avr-gcc 12.2.0, avrdude
-  {"AT90S2323",        187,  F_AVR8, {0x1E, 0x91, 0x02},       0, 0x00800,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0080,  1,  1,   3,   vtab_attiny22}, // avr-gcc 12.2.0
-  {"AT90S2333",        188,  F_AVR8, {0x1E, 0x91, 0x05},       0, 0x00800, 0x001, -1,     -1,       0, 0x0080,  1, 0x0060, 0x0080, -1, -1,  14,  vtab_at90s4433}, // avr-gcc 12.2.0, avrdude
-  {"AT90S2343",        189,  F_AVR8, {0x1E, 0x91, 0x03},       0, 0x00800, 0x001, -1,     -1,       0, 0x0080,  1, 0x0060, 0x0080,  1,  1,   3,   vtab_attiny22}, // avr-gcc 12.2.0, avrdude
-  {"AT90S4414",        190,  F_AVR8, {0x1E, 0x92, 0x01},       0, 0x01000, 0x001, -1,     -1,       0, 0x0100,  1, 0x0060, 0x0100,  1,  1,  13,  vtab_at90s8515}, // avr-gcc 12.2.0, avrdude
-  {"AT90S4433",        191,  F_AVR8, {0x1E, 0x92, 0x03},       0, 0x01000, 0x001, -1,     -1,       0, 0x0100,  1, 0x0060, 0x0080,  1,  1,  14,  vtab_at90s4433}, // avr-gcc 12.2.0, avrdude
-  {"AT90S4434",        192,  F_AVR8, {0x1E, 0x92, 0x02},       0, 0x01000, 0x001, -1,     -1,       0, 0x0100,  1, 0x0060, 0x0100,  1,  1,  17,  vtab_at90s8535}, // avr-gcc 12.2.0, avrdude
-  {"AT90S8515",        193,  F_AVR8, {0x1E, 0x93, 0x01},       0, 0x02000, 0x001, -1,     -1,       0, 0x0200,  1, 0x0060, 0x0200,  1,  1,  13,  vtab_at90s8515}, // avr-gcc 12.2.0, avrdude
+  {"AT90S2313",        186,  F_AVR8, {0x1E, 0x91, 0x01},       0, 0x00800, 0x001,  0,      0,       0, 0x0080,  1, 0x0060, 0x0080,  1,  1,  11,  vtab_at90s2313}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S2323",        187,  F_AVR8, {0x1E, 0x91, 0x02},       0, 0x00800,    -1,  0,      0,      -1,     -1, -1, 0x0060, 0x0080,  1,  1,   3,   vtab_attiny22}, // avr-gcc 12.2.0, boot size (manual)
+  {"AT90S2333",        188,  F_AVR8, {0x1E, 0x91, 0x05},       0, 0x00800, 0x001,  0,      0,       0, 0x0080,  1, 0x0060, 0x0080, -1, -1,  14,  vtab_at90s4433}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S2343",        189,  F_AVR8, {0x1E, 0x91, 0x03},       0, 0x00800, 0x001,  0,      0,       0, 0x0080,  1, 0x0060, 0x0080,  1,  1,   3,   vtab_attiny22}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S4414",        190,  F_AVR8, {0x1E, 0x92, 0x01},       0, 0x01000, 0x001,  0,      0,       0, 0x0100,  1, 0x0060, 0x0100,  1,  1,  13,  vtab_at90s8515}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S4433",        191,  F_AVR8, {0x1E, 0x92, 0x03},       0, 0x01000, 0x001,  0,      0,       0, 0x0100,  1, 0x0060, 0x0080,  1,  1,  14,  vtab_at90s4433}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S4434",        192,  F_AVR8, {0x1E, 0x92, 0x02},       0, 0x01000, 0x001,  0,      0,       0, 0x0100,  1, 0x0060, 0x0100,  1,  1,  17,  vtab_at90s8535}, // avr-gcc 12.2.0, avrdude, boot size (manual)
+  {"AT90S8515",        193,  F_AVR8, {0x1E, 0x93, 0x01},       0, 0x02000, 0x001,  0,      0,       0, 0x0200,  1, 0x0060, 0x0200,  1,  1,  13,  vtab_at90s8515}, // avr-gcc 12.2.0, avrdude, boot size (manual)
   {"AT90C8534",        194,  F_AVR8, {0xff,   -1,   -1},       0, 0x02000,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0100, -1, -1,   0,            NULL}, // avr-gcc 12.2.0
-  {"AT90S8535",        195,  F_AVR8, {0x1E, 0x93, 0x03},       0, 0x02000, 0x001, -1,     -1,       0, 0x0200,  1, 0x0060, 0x0200,  1,  1,  17,  vtab_at90s8535}, // avr-gcc 12.2.0, avrdude
+  {"AT90S8535",        195,  F_AVR8, {0x1E, 0x93, 0x03},       0, 0x02000, 0x001,  0,      0,       0, 0x0200,  1, 0x0060, 0x0200,  1,  1,  17,  vtab_at90s8535}, // avr-gcc 12.2.0, avrdude, boot size (manual)
   {"AT94K",            196,  F_AVR8, {0xff,   -1,   -1},       0, 0x08000,    -1, -1,     -1,      -1,     -1, -1, 0x0060, 0x0fa0, -1, -1,   0,            NULL}, // avr-gcc 12.2.0
   {"ATA5272",          197,  F_AVR8, {0x1E, 0x93, 0x87},       0, 0x02000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  37,    vtab_ata5272}, // atdf, avr-gcc 12.2.0
   {"ATA5505",          198,  F_AVR8, {0x1E, 0x94, 0x87},       0, 0x04000, 0x080,  0,      0,       0, 0x0200,  4, 0x0100, 0x0200,  3,  1,  20,  vtab_attiny167}, // atdf, avr-gcc 12.2.0
diff --git a/src/avrintel.h b/src/avrintel.h
index 9da54fba..63aca3bf 100644
--- a/src/avrintel.h
+++ b/src/avrintel.h
@@ -9,7 +9,7 @@
  * meta-author Stefan Rueger <stefan.rueger@urclocks.com>
  *
  * v 1.1
- * 24.11.2022
+ * 02.01.2023
  *
  */
 
diff --git a/src/config_gram.y b/src/config_gram.y
index 257abf61..9df42478 100644
--- a/src/config_gram.y
+++ b/src/config_gram.y
@@ -44,6 +44,7 @@ int yylex(void);
 int yyerror(char * errmsg, ...);
 int yywarning(char * errmsg, ...);
 
+static int clear_pin(int pinfunc);
 static int assign_pin(int pinfunc, TOKEN *v, int invert);
 static int assign_pin_list(int invert);
 static int which_opcode(TOKEN * opcode);
@@ -334,7 +335,6 @@ prog_def :
 prog_decl :
   K_PROGRAMMER
     { current_prog = pgm_new();
-      current_strct = COMP_PROGRAMMER;
       current_prog->config_file = cache_string(cfg_infile);
       current_prog->lineno = cfg_lineno;
     }
@@ -348,7 +348,6 @@ prog_decl :
         YYABORT;
       }
       current_prog = pgm_dup(pgm);
-      current_strct = COMP_PROGRAMMER;
       current_prog->parent_id = cache_string($3->value.string);
       current_prog->comments = NULL;
       current_prog->config_file = cache_string(cfg_infile);
@@ -426,7 +425,6 @@ part_decl :
   K_PART
     {
       current_part = avr_new_part();
-      current_strct = COMP_AVRPART;
       current_part->config_file = cache_string(cfg_infile);
       current_part->lineno = cfg_lineno;
     } |
@@ -440,7 +438,6 @@ part_decl :
       }
 
       current_part = avr_dup_part(parent_part);
-      current_strct = COMP_AVRPART;
       current_part->parent_id = cache_string($3->value.string);
       current_part->comments = NULL;
       current_part->config_file = cache_string(cfg_infile);
@@ -654,16 +651,16 @@ pin_list:
 ;
 
 prog_parm_pins:
-  K_VCC    TKN_EQUAL {pin_name = PPI_AVR_VCC;  } pin_list |
-  K_BUFF   TKN_EQUAL {pin_name = PPI_AVR_BUFF; } pin_list |
-  K_RESET  TKN_EQUAL {pin_name = PIN_AVR_RESET;} pin_number { free_token($1); } |
-  K_SCK    TKN_EQUAL {pin_name = PIN_AVR_SCK;  } pin_number { free_token($1); } |
-  K_SDO    TKN_EQUAL {pin_name = PIN_AVR_SDO;  } pin_number |
-  K_SDI    TKN_EQUAL {pin_name = PIN_AVR_SDI;  } pin_number |
-  K_ERRLED TKN_EQUAL {pin_name = PIN_LED_ERR;  } pin_number |
-  K_RDYLED TKN_EQUAL {pin_name = PIN_LED_RDY;  } pin_number |
-  K_PGMLED TKN_EQUAL {pin_name = PIN_LED_PGM;  } pin_number |
-  K_VFYLED TKN_EQUAL {pin_name = PIN_LED_VFY;  } pin_number
+  K_VCC    TKN_EQUAL {pin_name = PPI_AVR_VCC; clear_pin(pin_name);  } pin_list |
+  K_BUFF   TKN_EQUAL {pin_name = PPI_AVR_BUFF; clear_pin(pin_name); } pin_list |
+  K_RESET  TKN_EQUAL {pin_name = PIN_AVR_RESET; clear_pin(pin_name);} pin_number { free_token($1); } |
+  K_SCK    TKN_EQUAL {pin_name = PIN_AVR_SCK; clear_pin(pin_name);  } pin_number { free_token($1); } |
+  K_SDO    TKN_EQUAL {pin_name = PIN_AVR_SDO; clear_pin(pin_name);  } pin_number |
+  K_SDI    TKN_EQUAL {pin_name = PIN_AVR_SDI; clear_pin(pin_name);  } pin_number |
+  K_ERRLED TKN_EQUAL {pin_name = PIN_LED_ERR; clear_pin(pin_name);  } pin_number |
+  K_RDYLED TKN_EQUAL {pin_name = PIN_LED_RDY; clear_pin(pin_name);  } pin_number |
+  K_PGMLED TKN_EQUAL {pin_name = PIN_LED_PGM; clear_pin(pin_name);  } pin_number |
+  K_VFYLED TKN_EQUAL {pin_name = PIN_LED_VFY; clear_pin(pin_name);  } pin_number
 ;
 
 opcode :
@@ -1275,7 +1272,6 @@ part_parm :
       }
       avr_add_mem_order($2->value.string);
       current_mem = mem;
-      current_strct = COMP_AVRMEM;
       free_token($2);
     }
     mem_specs 
@@ -1550,6 +1546,17 @@ static char * vtypestr(int type)
 #endif
 
 
+static int clear_pin(int pinfunc) {
+  if(pinfunc < 0 || pinfunc >= N_PINS) {
+    yyerror("pin function must be in the range [0, %d]", N_PINS-1);
+    return -1;
+  }
+
+  pin_clear_all(&(current_prog->pin[pinfunc]));
+
+  return 0;
+}
+
 static int assign_pin(int pinfunc, TOKEN *v, int invert) {
   if(pinfunc < 0 || pinfunc >= N_PINS) {
     yyerror("pin function must be in the range [0, %d]", N_PINS-1);
diff --git a/src/developer_opts.c b/src/developer_opts.c
index cb42e30e..4606fc00 100644
--- a/src/developer_opts.c
+++ b/src/developer_opts.c
@@ -486,6 +486,13 @@ typedef struct {
   AVRMEMdeep mems[40];
 } AVRPARTdeep;
 
+
+// Return memory iff its desc matches str exactly
+static AVRMEM *dev_locate_mem(const AVRPART *p, const char *str) {
+  AVRMEM *m = p->mem? avr_locate_mem_noalias(p, str): NULL;
+  return m && strcmp(m->desc, str) == 0? m: NULL;
+}
+
 static int avrpart_deep_copy(AVRPARTdeep *d, const AVRPART *p) {
   AVRMEM *m;
   size_t di;
@@ -525,7 +532,7 @@ static int avrpart_deep_copy(AVRPARTdeep *d, const AVRPART *p) {
   // Fill in all memories we got in defined order
   di = 0;
   for(size_t mi=0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi]; mi++) {
-    m = p->mem? avr_locate_mem_noalias(p, avr_mem_order[mi]): NULL;
+    m = dev_locate_mem(p, avr_mem_order[mi]);
     if(m) {
       if(di >= sizeof d->mems/sizeof *d->mems) {
         pmsg_error("ran out of mems[] space, increase size in AVRMEMdeep of developer_opts.c and recompile\n");
@@ -726,8 +733,8 @@ static void dev_part_strct(const AVRPART *p, bool tsv, const AVRPART *base, bool
   for(size_t mi=0; mi < sizeof avr_mem_order/sizeof *avr_mem_order && avr_mem_order[mi]; mi++) {
     AVRMEM *m, *bm;
 
-    m = p->mem? avr_locate_mem_noalias(p, avr_mem_order[mi]): NULL;
-    bm = base && base->mem? avr_locate_mem_noalias(base, avr_mem_order[mi]): NULL;
+    m = dev_locate_mem(p, avr_mem_order[mi]);
+    bm = base? dev_locate_mem(base, avr_mem_order[mi]): NULL;
 
     if(!m && bm && !tsv)
       dev_info("\n    memory \"%s\" = NULL;\n", bm->desc);
@@ -1189,6 +1196,42 @@ static const char *connstr(conntype_t conntype) {
   }
 }
 
+
+static char *dev_usbpid_liststr(const PROGRAMMER *pgm) {
+  char spc[1024];  int firstid = 1;
+
+  spc[0] = 0;
+  if(pgm->usbpid)
+    for(LNODEID ln=lfirst(pgm->usbpid); ln; ln=lnext(ln)) {
+      if(strlen(spc) > sizeof spc - 20)
+        break;
+      if(!firstid)
+        strcat(spc, ", ");
+      firstid = 0;
+      sprintf(spc + strlen(spc), "0x%04x", *(unsigned int *) ldata(ln));
+    }
+
+  return cfg_strdup(__func__, *spc? spc: "NULL");
+}
+
+static char *dev_hvupdi_support_liststr(const PROGRAMMER *pgm) {
+  char spc[1024];  int firstid = 1;
+
+  spc[0] = 0;
+  if(pgm->hvupdi_support)
+    for(LNODEID ln=lfirst(pgm->hvupdi_support); ln; ln=lnext(ln)) {
+      if(strlen(spc) > sizeof spc - 20)
+        break;
+      if(!firstid)
+        strcat(spc, ", ");
+      firstid = 0;
+      sprintf(spc + strlen(spc), "%d", *(unsigned int *) ldata(ln));
+    }
+
+  return cfg_strdup(__func__, *spc? spc: "NULL");
+}
+
+
 static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *base, bool injct) {
   char *id = ldata(lfirst(pgm->id));
   LNODEID ln;
@@ -1249,26 +1292,18 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
 
   _if_pgmout(intcmp, "0x%04x", usbvid);
 
-  if(pgm->usbpid && lfirst(pgm->usbpid)) {
-    if(tsv)
-      dev_info(".prog\t%s\tusbpid\t", id);
-    else {
-      dev_cout(pgm->comments, "usbpid", 0, 0);
-      dev_info("    %-22s = ", "usbpid");
-    }
-    for(firstid=1, ln=lfirst(pgm->usbpid); ln; ln=lnext(ln)) {
-      if(!firstid)
-        dev_info(", ");
-      firstid = 0;
-      dev_info("0x%04x", *(unsigned int *) ldata(ln));
-    }
-    if(tsv)
-      dev_info("\n");
-    else {
-      dev_info(";");
-      dev_cout(pgm->comments, "usbpid", 1, 1);
-    }
+  char *pgmstr = dev_usbpid_liststr(pgm);
+  int show = !base;
+
+  if(base) {
+    char *basestr = dev_usbpid_liststr(base);
+    show = strcmp(basestr, pgmstr) != 0;
+    free(basestr);
   }
+  if(show)
+    dev_part_strct_entry(tsv, ".prog", id, NULL, "usbpid", pgmstr, pgm->comments);
+  else                          // dev_part_strct_entry() frees pgmstr
+    free(pgmstr);
 
   _if_pgmout_str(strcmp, cfg_escape(pgm->usbdev), usbdev);
   _if_pgmout_str(strcmp, cfg_escape(pgm->usbsn), usbsn);
@@ -1286,26 +1321,18 @@ static void dev_pgm_strct(const PROGRAMMER *pgm, bool tsv, const PROGRAMMER *bas
       free(bstr);
   }
 
-  if(pgm->hvupdi_support && lfirst(pgm->hvupdi_support)) {
-    if(tsv)
-      dev_info(".prog\t%s\thvupdu_support\t", id);
-    else {
-      dev_cout(pgm->comments, "hvupdi_support", 0, 0);
-      dev_info("    %-22s = ", "hvupdi_support");
-    }
-    for(firstid=1, ln=lfirst(pgm->hvupdi_support); ln; ln=lnext(ln)) {
-      if(!firstid)
-        dev_info(", ");
-      firstid = 0;
-      dev_info("%d", *(unsigned int *) ldata(ln));
-    }
-    if(tsv)
-      dev_info("\n");
-    else {
-      dev_info(";");
-      dev_cout(pgm->comments, "hvupdi_support", 1, 1);
-    }
+  pgmstr = dev_hvupdi_support_liststr(pgm);
+  show = !base;
+
+  if(base) {
+    char *basestr = dev_hvupdi_support_liststr(base);
+    show = strcmp(basestr, pgmstr) != 0;
+    free(basestr);
   }
+  if(show)
+    dev_part_strct_entry(tsv, ".prog", id, NULL, "hvupdi_support", pgmstr, pgm->comments);
+  else                          // dev_part_strct_entry() frees pgmstr
+    free(pgmstr);
 
   if(injct)
     for(size_t i=0; i<sizeof pgminj/sizeof*pgminj; i++)
diff --git a/src/lexer.l b/src/lexer.l
index 88413a72..ea5e2cd0 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -126,7 +126,7 @@ SIGN     [+-]
 
   Component_t *cp = cfg_comp_search(yytext, current_strct);
   if(!cp) {
-    yyerror("Unknown component %s in %s", yytext, cfg_strct_name(current_strct));
+    yyerror("unknown component %s in %s", yytext, cfg_strct_name(current_strct));
     return YYERRCODE;
   }
   yylval = new_token(TKN_COMPONENT);
@@ -194,7 +194,7 @@ 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(); return K_MEMORY; }
+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; }
@@ -212,7 +212,7 @@ 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(); return K_PART; }
+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; }
@@ -227,7 +227,7 @@ 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(); return K_PROGRAMMER; }
+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; }