Parcourir la source

Now version 6.2
https://code.google.com/p/optiboot/issues/detail?id=110
Make the "length" variable types be dependent on SPM_PAGESIZE.
Having it be uint8_t on smaller chips saves significant code
space, but it really should be uint16_t on bigger chips.

(Also, fix the luminet makefile target. Not that the code works.)

westfw il y a 10 ans
Parent
commit
c0c10a8798

+ 2 - 2
optiboot/bootloaders/optiboot/Makefile.extras

@@ -62,8 +62,8 @@ attiny84: TARGET = attiny84
 attiny84: MCU_TARGET = attiny84
 attiny84: CFLAGS += $(COMMON_OPTIONS) -DSOFT_UART -DVIRTUAL_BOOT_PARTITION
 attiny84: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1ffe
-attiny84: $(PROGRAM)_attiny84p.hex
-attiny84: $(PROGRAM)_attiny84p.lst
+attiny84: $(PROGRAM)_attiny84.hex
+attiny84: $(PROGRAM)_attiny84.lst
 
 
 

+ 28 - 13
optiboot/bootloaders/optiboot/optiboot.c

@@ -16,7 +16,6 @@
 /*                                                        */
 /* Enhancements:                                          */
 /*   Fits in 512 bytes, saving 1.5K of code space         */
-/*   Background page erasing speeds up programming        */
 /*   Higher baud rate speeds up programming               */
 /*   Written almost entirely in C                         */
 /*   Customisable timeout with accurate timeconstant      */
@@ -151,6 +150,9 @@
 /* Edit History:					  */
 /*							  */
 /* Aug 2014						  */
+/* 6.2 WestfW: make size of length variables dependent    */
+/*              on the SPM_PAGESIZE.  This saves space    */
+/*              on the chips where it's most important.   */
 /* 6.1 WestfW: Fix OPTIBOOT_CUSTOMVER (send it!)	  */
 /*             Make no-wait mod less picky about	  */
 /*               skipping the bootloader.		  */
@@ -218,7 +220,7 @@
 /**********************************************************/
 
 #define OPTIBOOT_MAJVER 6
-#define OPTIBOOT_MINVER 1
+#define OPTIBOOT_MINVER 2
 
 /*
  * OPTIBOOT_CUSTOMVER should be defined (by the makefile) for custom edits
@@ -320,6 +322,20 @@ optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER;
 #define WATCHDOG_8S     (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
 #endif
 
+
+/*
+ * We can never load flash with more than 1 page at a time, so we can save
+ * some code space on parts with smaller pagesize by using a smaller int.
+ */
+#if SPM_PAGESIZE > 255
+typedef uint16_t pagelen_t ;
+#define GETLENGTH(len) len = getch()<<8; len |= getch()
+#else
+typedef uint8_t pagelen_t;
+#define GETLENGTH(len) (void) getch() /* skip high byte */; len = getch()
+#endif
+
+
 /* Function Prototypes
  * The main() function is in init9, which removes the interrupt vector table
  * we don't need. It is also 'OS_main', which means the compiler does not
@@ -338,9 +354,9 @@ static inline void getNch(uint8_t);
 static inline void flash_led(uint8_t);
 static inline void watchdogReset();
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len);
+			       uint16_t address, pagelen_t len);
 static inline void read_mem(uint8_t memtype,
-			    uint16_t address, uint16_t len);
+			    uint16_t address, pagelen_t len);
 
 #ifdef SOFT_UART
 void uartDelay() __attribute__ ((naked));
@@ -350,7 +366,7 @@ void appStart(uint8_t rstFlags) __attribute__ ((naked));
 /*
  * RAMSTART should be self-explanatory.  It's bigger on parts with a
  * lot of peripheral registers.  Let 0x100 be the default
- * Note that RAMSTART need not be exactly at the start of RAM.
+ * Note that RAMSTART (for optiboot) need not be exactly at the start of RAM.
  */
 #if !defined(RAMSTART)  // newer versions of gcc avr-libc define RAMSTART
 #define RAMSTART 0x100
@@ -385,7 +401,7 @@ int main(void) {
    *  necessary, and uses 4 bytes of flash.)
    */
   register uint16_t address = 0;
-  register uint16_t  length;
+  register pagelen_t  length;
 
   // After the zero init loop, this is the first code to run.
   //
@@ -504,10 +520,9 @@ int main(void) {
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
-      length |= getch();
+      GETLENGTH(length);
       savelength = length;
       desttype = getch();
 
@@ -545,8 +560,8 @@ int main(void) {
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
-      length |= getch();
+      GETLENGTH(length);
+
       desttype = getch();
 
       verifySpace();
@@ -755,7 +770,7 @@ void appStart(uint8_t rstFlags) {
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
     case 'E': // EEPROM
@@ -818,7 +833,7 @@ static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
     } // switch
 }
 
-static inline void read_mem(uint8_t memtype, uint16_t address, uint16_t length)
+static inline void read_mem(uint8_t memtype, uint16_t address, pagelen_t length)
 {
     uint8_t ch;
 

+ 2 - 2
optiboot/bootloaders/optiboot/optiboot_atmega1280.hex

@@ -6,7 +6,7 @@
 :10FC40002093840096BBB09BFECF1F9AA89581504D
 :10FC5000A9F7CC24DD248824839425E0A22E91E109
 :10FC6000992EC2D0813471F4BFD0182FCFD0123862
-:10FC700011F481E005C0113811F486E001C083E081
+:10FC700011F482E005C0113811F486E001C083E080
 :10FC8000ABD0A7C0823411F484E103C0853419F4E9
 :10FC900085E0C4D09EC08535A1F4A6D0082F10E021
 :10FCA000A3D0E82EFF24FE2CEE24E02AF12A8F2D8B
@@ -38,6 +38,6 @@
 :10FE4000F89A992780B50895262FF999FECF1FBA01
 :10FE500092BD81BD20BD0FB6F894FA9AF99A0FBEF3
 :04FE6000019608956A
-:02FFFE000106FA
+:02FFFE000206F9
 :040000031000FC00ED
 :00000001FF

+ 15 - 16
optiboot/bootloaders/optiboot/optiboot_atmega1280.lst

@@ -15,19 +15,19 @@ Idx Name          Size      VMA       LMA       File off  Algn
                   CONTENTS, READONLY, DEBUGGING
   5 .debug_pubnames 00000074  00000000  00000000  0000053f  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_info   000003e4  00000000  00000000  000005b3  2**0
+  6 .debug_info   000003f0  00000000  00000000  000005b3  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_abbrev 000001f1  00000000  00000000  00000997  2**0
+  7 .debug_abbrev 000001fe  00000000  00000000  000009a3  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_line   0000045b  00000000  00000000  00000b88  2**0
+  8 .debug_line   0000044b  00000000  00000000  00000ba1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_frame  00000080  00000000  00000000  00000fe4  2**2
+  9 .debug_frame  00000080  00000000  00000000  00000fec  2**2
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_str    00000172  00000000  00000000  00001064  2**0
+ 10 .debug_str    0000017c  00000000  00000000  0000106c  2**0
                   CONTENTS, READONLY, DEBUGGING
- 11 .debug_loc    000003b3  00000000  00000000  000011d6  2**0
+ 11 .debug_loc    000003b3  00000000  00000000  000011e8  2**0
                   CONTENTS, READONLY, DEBUGGING
- 12 .debug_ranges 000000d0  00000000  00000000  00001589  2**0
+ 12 .debug_ranges 000000d0  00000000  00000000  0000159b  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -183,7 +183,7 @@ void watchdogReset() {
    1fc6e:	12 38       	cpi	r17, 0x82	; 130
    1fc70:	11 f4       	brne	.+4      	; 0x1fc76 <main+0x76>
 	  putch(optiboot_version & 0xFF);
-   1fc72:	81 e0       	ldi	r24, 0x01	; 1
+   1fc72:	82 e0       	ldi	r24, 0x02	; 2
    1fc74:	05 c0       	rjmp	.+10     	; 0x1fc80 <main+0x80>
       } else if (which == 0x81) {
    1fc76:	11 38       	cpi	r17, 0x81	; 129
@@ -273,14 +273,13 @@ void watchdogReset() {
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
+      GETLENGTH(length);
    1fcd4:	89 d0       	rcall	.+274    	; 0x1fde8 <getch>
    1fcd6:	90 e0       	ldi	r25, 0x00	; 0
    1fcd8:	18 2f       	mov	r17, r24
    1fcda:	00 27       	eor	r16, r16
-      length |= getch();
    1fcdc:	85 d0       	rcall	.+266    	; 0x1fde8 <getch>
    1fcde:	90 e0       	ldi	r25, 0x00	; 0
    1fce0:	08 2b       	or	r16, r24
@@ -311,7 +310,7 @@ void watchdogReset() {
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
    1fcfe:	f5 e4       	ldi	r31, 0x45	; 69
@@ -334,7 +333,7 @@ static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
    1fd18:	97 d0       	rcall	.+302    	; 0x1fe48 <__eewr_byte_m1280>
    1fd1a:	01 50       	subi	r16, 0x01	; 1
    1fd1c:	10 40       	sbci	r17, 0x00	; 0
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
     case 'E': // EEPROM
@@ -431,16 +430,16 @@ int main(void) {
    1fd78:	84 37       	cpi	r24, 0x74	; 116
    1fd7a:	f1 f4       	brne	.+60     	; 0x1fdb8 <main+0x1b8>
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
+      GETLENGTH(length);
    1fd7c:	35 d0       	rcall	.+106    	; 0x1fde8 <getch>
    1fd7e:	90 e0       	ldi	r25, 0x00	; 0
    1fd80:	d8 2f       	mov	r29, r24
    1fd82:	cc 27       	eor	r28, r28
-      length |= getch();
    1fd84:	31 d0       	rcall	.+98     	; 0x1fde8 <getch>
    1fd86:	90 e0       	ldi	r25, 0x00	; 0
    1fd88:	c8 2b       	or	r28, r24
    1fd8a:	d9 2b       	or	r29, r25
+
       desttype = getch();
    1fd8c:	2d d0       	rcall	.+90     	; 0x1fde8 <getch>
    1fd8e:	18 2f       	mov	r17, r24
@@ -448,7 +447,7 @@ int main(void) {
       verifySpace();
    1fd90:	3d d0       	rcall	.+122    	; 0x1fe0c <verifySpace>
 
-static inline void read_mem(uint8_t memtype, uint16_t address, uint16_t length)
+static inline void read_mem(uint8_t memtype, uint16_t address, pagelen_t length)
 {
     uint8_t ch;
 

+ 28 - 30
optiboot/bootloaders/optiboot/optiboot_atmega328.hex

@@ -1,35 +1,33 @@
-:107E0000112494B714BE892F8D7011F0892FEFD0F3
+:107E0000112494B714BE892F8D7011F0892FDED004
 :107E100085E08093810082E08093C00088E18093B8
 :107E2000C10086E08093C20080E18093C4008EE0B0
-:107E3000C8D0259A86E020E33CEF91E0309385009E
+:107E3000B7D0259A86E020E33CEF91E030938500AF
 :107E40002093840096BBB09BFECF1D9AA8958150CD
-:107E5000A9F7AA24BB2433E0832E7724739425E06A
-:107E6000922E91E1C92EA1D0813471F49ED0182FA9
-:107E7000AED0123811F481E005C0113811F486E05B
-:107E800001C083E08AD086C0823411F484E103C04B
-:107E9000853419F485E0A3D07DC0853579F485D08B
-:107EA000E82EFF2482D0082F10E0102F00270E2983
-:107EB0001F29000F111F8BD058016CC0863521F48B
-:107EC00084E08DD080E0DECF843609F041C06DD0F3
-:107ED00090E0182F002769D090E0082B192B65D06F
-:107EE000D82EE801E12CF1E0FF2E5FD0F70181935D
-:107EF0007F012197D1F76BD0F5E4DF1609F4FFCFAE
-:107F0000F50187BEE89507B600FCFDCFB501A801D5
-:107F1000A0E0B1E02C9130E011968C91119790E0A7
-:107F2000982F8827822B932B1296FB010C0177BE8A
-:107F3000E89511246E5F7F4F4250504059F7F5018C
-:107F400097BEE89507B600FCFDCFC7BEE89522C0F6
-:107F5000843791F42AD090E0D82FCC2726D090E017
-:107F6000C82BD92B22D033D08501F80185918F0100
-:107F700014D02197D1F70EC0853739F428D08EE17F
-:107F80000CD085E90AD08FE07DCF813511F488E0EF
-:107F900018D01DD080E101D066CF982F8091C0000D
-:107FA00085FFFCCF9093C60008958091C00087FFA5
-:107FB000FCCF8091C00084FD01C0A8958091C600CF
-:107FC0000895E0E6F0E098E1908380830895EDDF86
-:107FD000803219F088E0F5DFFFCF84E1DECF1F9318
-:107FE000182FE3DF1150E9F7F2DF1F910895282ED3
-:0A7FF00080E0E7DFEE27FF27099489
-:027FFE0001067A
+:107E5000A9F7EE24FF24B3E0AB2EBB24B394A5E036
+:107E6000DA2EF1E1CF2E90D0813471F48DD0082F2D
+:107E70009DD0023811F482E005C0013811F486E08B
+:107E800001C083E079D075C0823411F484E103C06D
+:107E9000853419F485E092D06CC0853579F474D0BE
+:107EA000E82EFF2471D0082F10E0102F00270E2994
+:107EB0001F29000F111F7AD078015BC0863521F48D
+:107EC00084E07CD080E0DECF843609F035C05CD021
+:107ED0005BD0182F59D0082FC0E0D1E055D089933E
+:107EE0001C17E1F763D0053409F4FFCFF701A7BEF3
+:107EF000E89507B600FCFDCFA701A0E0B1E02C910A
+:107F000030E011968C91119790E0982F8827822B62
+:107F1000932B1296FA010C01B7BEE89511244E5F1F
+:107F20005F4F1A1761F7F701D7BEE89507B600FC57
+:107F3000FDCFC7BEE8951DC0843769F425D024D095
+:107F4000082F22D033D0E701FE018591EF0114D034
+:107F50000150D1F70EC0853739F428D08EE10CD00E
+:107F600085E90AD08FE08ECF813511F488E018D0F2
+:107F70001DD080E101D077CF982F8091C00085FF80
+:107F8000FCCF9093C60008958091C00087FFFCCF7E
+:107F90008091C00084FD01C0A8958091C60008951D
+:107FA000E0E6F0E098E1908380830895EDDF803291
+:107FB00019F088E0F5DFFFCF84E1DECF1F93182FA3
+:107FC000E3DF1150E9F7F2DF1F910895282E80E0DA
+:087FD000E7DFEE27FF2709940B
+:027FFE00020679
 :0400000300007E007B
 :00000001FF

+ 179 - 197
optiboot/bootloaders/optiboot/optiboot_atmega328.lst

@@ -3,27 +3,27 @@ optiboot_atmega328.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001fa  00007e00  00007e00  00000074  2**1
+  0 .text         000001d8  00007e00  00007e00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00007ffe  00007ffe  0000026e  2**0
+  1 .version      00000002  00007ffe  00007ffe  0000024c  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  00000270  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000298  2**0
+  3 .debug_pubnames 00000074  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003e0  00000000  00000000  0000030c  2**0
+  4 .debug_info   000003ea  00000000  00000000  000002ea  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001f1  00000000  00000000  000006ec  2**0
+  5 .debug_abbrev 000001ef  00000000  00000000  000006d4  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000043b  00000000  00000000  000008dd  2**0
+  6 .debug_line   0000042b  00000000  00000000  000008c3  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000d18  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000cf0  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000172  00000000  00000000  00000d98  2**0
+  8 .debug_str    0000017c  00000000  00000000  00000d70  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d7  00000000  00000000  00000f0a  2**0
+  9 .debug_loc    00000300  00000000  00000000  00000eec  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011e1  2**0
+ 10 .debug_ranges 000000b8  00000000  00000000  000011ec  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -51,7 +51,7 @@ int main(void) {
     7e0a:	11 f0       	breq	.+4      	; 0x7e10 <main+0x10>
       appStart(ch);
     7e0c:	89 2f       	mov	r24, r25
-    7e0e:	ef d0       	rcall	.+478    	; 0x7fee <appStart>
+    7e0e:	de d0       	rcall	.+444    	; 0x7fcc <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -81,7 +81,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     7e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    7e30:	c8 d0       	rcall	.+400    	; 0x7fc2 <watchdogConfig>
+    7e30:	b7 d0       	rcall	.+366    	; 0x7fa0 <watchdogConfig>
 
 #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
   /* Set LED pin as output */
@@ -131,66 +131,66 @@ void watchdogReset() {
   } while (--count);
     7e4e:	81 50       	subi	r24, 0x01	; 1
     7e50:	a9 f7       	brne	.-22     	; 0x7e3c <main+0x3c>
-    7e52:	aa 24       	eor	r10, r10
-    7e54:	bb 24       	eor	r11, r11
+    7e52:	ee 24       	eor	r14, r14
+    7e54:	ff 24       	eor	r15, r15
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    7e56:	33 e0       	ldi	r19, 0x03	; 3
-    7e58:	83 2e       	mov	r8, r19
+    7e56:	b3 e0       	ldi	r27, 0x03	; 3
+    7e58:	ab 2e       	mov	r10, r27
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7e5a:	77 24       	eor	r7, r7
-    7e5c:	73 94       	inc	r7
+    7e5a:	bb 24       	eor	r11, r11
+    7e5c:	b3 94       	inc	r11
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    7e5e:	25 e0       	ldi	r18, 0x05	; 5
-    7e60:	92 2e       	mov	r9, r18
+    7e5e:	a5 e0       	ldi	r26, 0x05	; 5
+    7e60:	da 2e       	mov	r13, r26
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    7e62:	91 e1       	ldi	r25, 0x11	; 17
-    7e64:	c9 2e       	mov	r12, r25
+    7e62:	f1 e1       	ldi	r31, 0x11	; 17
+    7e64:	cf 2e       	mov	r12, r31
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    7e66:	a1 d0       	rcall	.+322    	; 0x7faa <getch>
+    7e66:	90 d0       	rcall	.+288    	; 0x7f88 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     7e68:	81 34       	cpi	r24, 0x41	; 65
     7e6a:	71 f4       	brne	.+28     	; 0x7e88 <main+0x88>
       unsigned char which = getch();
-    7e6c:	9e d0       	rcall	.+316    	; 0x7faa <getch>
-    7e6e:	18 2f       	mov	r17, r24
+    7e6c:	8d d0       	rcall	.+282    	; 0x7f88 <getch>
+    7e6e:	08 2f       	mov	r16, r24
       verifySpace();
-    7e70:	ae d0       	rcall	.+348    	; 0x7fce <verifySpace>
+    7e70:	9d d0       	rcall	.+314    	; 0x7fac <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
       if (which == 0x82) {
-    7e72:	12 38       	cpi	r17, 0x82	; 130
+    7e72:	02 38       	cpi	r16, 0x82	; 130
     7e74:	11 f4       	brne	.+4      	; 0x7e7a <main+0x7a>
 	  putch(optiboot_version & 0xFF);
-    7e76:	81 e0       	ldi	r24, 0x01	; 1
+    7e76:	82 e0       	ldi	r24, 0x02	; 2
     7e78:	05 c0       	rjmp	.+10     	; 0x7e84 <main+0x84>
       } else if (which == 0x81) {
-    7e7a:	11 38       	cpi	r17, 0x81	; 129
+    7e7a:	01 38       	cpi	r16, 0x81	; 129
     7e7c:	11 f4       	brne	.+4      	; 0x7e82 <main+0x82>
 	  putch(optiboot_version >> 8);
     7e7e:	86 e0       	ldi	r24, 0x06	; 6
@@ -202,8 +202,8 @@ void watchdogReset() {
 	 */
 	putch(0x03);
     7e82:	83 e0       	ldi	r24, 0x03	; 3
-    7e84:	8a d0       	rcall	.+276    	; 0x7f9a <putch>
-    7e86:	86 c0       	rjmp	.+268    	; 0x7f94 <main+0x194>
+    7e84:	79 d0       	rcall	.+242    	; 0x7f78 <putch>
+    7e86:	75 c0       	rjmp	.+234    	; 0x7f72 <main+0x172>
       }
     }
     else if(ch == STK_SET_DEVICE) {
@@ -220,8 +220,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     7e94:	85 e0       	ldi	r24, 0x05	; 5
-    7e96:	a3 d0       	rcall	.+326    	; 0x7fde <getNch>
-    7e98:	7d c0       	rjmp	.+250    	; 0x7f94 <main+0x194>
+    7e96:	92 d0       	rcall	.+292    	; 0x7fbc <getNch>
+    7e98:	6c c0       	rjmp	.+216    	; 0x7f72 <main+0x172>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     7e9a:	85 35       	cpi	r24, 0x55	; 85
@@ -229,11 +229,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    7e9e:	85 d0       	rcall	.+266    	; 0x7faa <getch>
+    7e9e:	74 d0       	rcall	.+232    	; 0x7f88 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     7ea0:	e8 2e       	mov	r14, r24
     7ea2:	ff 24       	eor	r15, r15
-    7ea4:	82 d0       	rcall	.+260    	; 0x7faa <getch>
+    7ea4:	71 d0       	rcall	.+226    	; 0x7f88 <getch>
     7ea6:	08 2f       	mov	r16, r24
     7ea8:	10 e0       	ldi	r17, 0x00	; 0
     7eaa:	10 2f       	mov	r17, r16
@@ -249,9 +249,9 @@ void watchdogReset() {
     7eb4:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    7eb6:	8b d0       	rcall	.+278    	; 0x7fce <verifySpace>
-    7eb8:	58 01       	movw	r10, r16
-    7eba:	6c c0       	rjmp	.+216    	; 0x7f94 <main+0x194>
+    7eb6:	7a d0       	rcall	.+244    	; 0x7fac <verifySpace>
+    7eb8:	78 01       	movw	r14, r16
+    7eba:	5b c0       	rjmp	.+182    	; 0x7f72 <main+0x172>
     }
     else if(ch == STK_UNIVERSAL) {
     7ebc:	86 35       	cpi	r24, 0x56	; 86
@@ -259,7 +259,7 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     7ec0:	84 e0       	ldi	r24, 0x04	; 4
-    7ec2:	8d d0       	rcall	.+282    	; 0x7fde <getNch>
+    7ec2:	7c d0       	rcall	.+248    	; 0x7fbc <getNch>
       putch(0x00);
     7ec4:	80 e0       	ldi	r24, 0x00	; 0
     7ec6:	de cf       	rjmp	.-68     	; 0x7e84 <main+0x84>
@@ -268,339 +268,321 @@ void watchdogReset() {
     else if(ch == STK_PROG_PAGE) {
     7ec8:	84 36       	cpi	r24, 0x64	; 100
     7eca:	09 f0       	breq	.+2      	; 0x7ece <main+0xce>
-    7ecc:	41 c0       	rjmp	.+130    	; 0x7f50 <main+0x150>
+    7ecc:	35 c0       	rjmp	.+106    	; 0x7f38 <main+0x138>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
-    7ece:	6d d0       	rcall	.+218    	; 0x7faa <getch>
-    7ed0:	90 e0       	ldi	r25, 0x00	; 0
+      GETLENGTH(length);
+    7ece:	5c d0       	rcall	.+184    	; 0x7f88 <getch>
+    7ed0:	5b d0       	rcall	.+182    	; 0x7f88 <getch>
     7ed2:	18 2f       	mov	r17, r24
-    7ed4:	00 27       	eor	r16, r16
-      length |= getch();
-    7ed6:	69 d0       	rcall	.+210    	; 0x7faa <getch>
-    7ed8:	90 e0       	ldi	r25, 0x00	; 0
-    7eda:	08 2b       	or	r16, r24
-    7edc:	19 2b       	or	r17, r25
       savelength = length;
       desttype = getch();
-    7ede:	65 d0       	rcall	.+202    	; 0x7faa <getch>
-    7ee0:	d8 2e       	mov	r13, r24
-    7ee2:	e8 01       	movw	r28, r16
-    7ee4:	e1 2c       	mov	r14, r1
-    7ee6:	f1 e0       	ldi	r31, 0x01	; 1
-    7ee8:	ff 2e       	mov	r15, r31
+    7ed4:	59 d0       	rcall	.+178    	; 0x7f88 <getch>
+    7ed6:	08 2f       	mov	r16, r24
+    7ed8:	c0 e0       	ldi	r28, 0x00	; 0
+    7eda:	d1 e0       	ldi	r29, 0x01	; 1
 
       // read a page worth of contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    7eea:	5f d0       	rcall	.+190    	; 0x7faa <getch>
-    7eec:	f7 01       	movw	r30, r14
-    7eee:	81 93       	st	Z+, r24
-    7ef0:	7f 01       	movw	r14, r30
+    7edc:	55 d0       	rcall	.+170    	; 0x7f88 <getch>
+    7ede:	89 93       	st	Y+, r24
       while (--length);
-    7ef2:	21 97       	sbiw	r28, 0x01	; 1
-    7ef4:	d1 f7       	brne	.-12     	; 0x7eea <main+0xea>
+    7ee0:	1c 17       	cp	r17, r28
+    7ee2:	e1 f7       	brne	.-8      	; 0x7edc <main+0xdc>
 
       // Read command terminator, start reply
       verifySpace();
-    7ef6:	6b d0       	rcall	.+214    	; 0x7fce <verifySpace>
+    7ee4:	63 d0       	rcall	.+198    	; 0x7fac <verifySpace>
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
-    7ef8:	f5 e4       	ldi	r31, 0x45	; 69
-    7efa:	df 16       	cp	r13, r31
-    7efc:	09 f4       	brne	.+2      	; 0x7f00 <main+0x100>
-    7efe:	ff cf       	rjmp	.-2      	; 0x7efe <main+0xfe>
+    7ee6:	05 34       	cpi	r16, 0x45	; 69
+    7ee8:	09 f4       	brne	.+2      	; 0x7eec <main+0xec>
+    7eea:	ff cf       	rjmp	.-2      	; 0x7eea <main+0xea>
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    7f00:	f5 01       	movw	r30, r10
-    7f02:	87 be       	out	0x37, r8	; 55
-    7f04:	e8 95       	spm
+    7eec:	f7 01       	movw	r30, r14
+    7eee:	a7 be       	out	0x37, r10	; 55
+    7ef0:	e8 95       	spm
 	    boot_spm_busy_wait();
-    7f06:	07 b6       	in	r0, 0x37	; 55
-    7f08:	00 fc       	sbrc	r0, 0
-    7f0a:	fd cf       	rjmp	.-6      	; 0x7f06 <main+0x106>
-    7f0c:	b5 01       	movw	r22, r10
-    7f0e:	a8 01       	movw	r20, r16
-    7f10:	a0 e0       	ldi	r26, 0x00	; 0
-    7f12:	b1 e0       	ldi	r27, 0x01	; 1
+    7ef2:	07 b6       	in	r0, 0x37	; 55
+    7ef4:	00 fc       	sbrc	r0, 0
+    7ef6:	fd cf       	rjmp	.-6      	; 0x7ef2 <main+0xf2>
+    7ef8:	a7 01       	movw	r20, r14
+    7efa:	a0 e0       	ldi	r26, 0x00	; 0
+    7efc:	b1 e0       	ldi	r27, 0x01	; 1
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
-    7f14:	2c 91       	ld	r18, X
-    7f16:	30 e0       	ldi	r19, 0x00	; 0
+    7efe:	2c 91       	ld	r18, X
+    7f00:	30 e0       	ldi	r19, 0x00	; 0
 		a |= (*bufPtr++) << 8;
-    7f18:	11 96       	adiw	r26, 0x01	; 1
-    7f1a:	8c 91       	ld	r24, X
-    7f1c:	11 97       	sbiw	r26, 0x01	; 1
-    7f1e:	90 e0       	ldi	r25, 0x00	; 0
-    7f20:	98 2f       	mov	r25, r24
-    7f22:	88 27       	eor	r24, r24
-    7f24:	82 2b       	or	r24, r18
-    7f26:	93 2b       	or	r25, r19
+    7f02:	11 96       	adiw	r26, 0x01	; 1
+    7f04:	8c 91       	ld	r24, X
+    7f06:	11 97       	sbiw	r26, 0x01	; 1
+    7f08:	90 e0       	ldi	r25, 0x00	; 0
+    7f0a:	98 2f       	mov	r25, r24
+    7f0c:	88 27       	eor	r24, r24
+    7f0e:	82 2b       	or	r24, r18
+    7f10:	93 2b       	or	r25, r19
 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
 
 /* main program starts here */
 int main(void) {
-    7f28:	12 96       	adiw	r26, 0x02	; 2
+    7f12:	12 96       	adiw	r26, 0x02	; 2
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7f2a:	fb 01       	movw	r30, r22
-    7f2c:	0c 01       	movw	r0, r24
-    7f2e:	77 be       	out	0x37, r7	; 55
-    7f30:	e8 95       	spm
-    7f32:	11 24       	eor	r1, r1
+    7f14:	fa 01       	movw	r30, r20
+    7f16:	0c 01       	movw	r0, r24
+    7f18:	b7 be       	out	0x37, r11	; 55
+    7f1a:	e8 95       	spm
+    7f1c:	11 24       	eor	r1, r1
 		addrPtr += 2;
-    7f34:	6e 5f       	subi	r22, 0xFE	; 254
-    7f36:	7f 4f       	sbci	r23, 0xFF	; 255
+    7f1e:	4e 5f       	subi	r20, 0xFE	; 254
+    7f20:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    7f38:	42 50       	subi	r20, 0x02	; 2
-    7f3a:	50 40       	sbci	r21, 0x00	; 0
-    7f3c:	59 f7       	brne	.-42     	; 0x7f14 <main+0x114>
+    7f22:	1a 17       	cp	r17, r26
+    7f24:	61 f7       	brne	.-40     	; 0x7efe <main+0xfe>
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    7f3e:	f5 01       	movw	r30, r10
-    7f40:	97 be       	out	0x37, r9	; 55
-    7f42:	e8 95       	spm
+    7f26:	f7 01       	movw	r30, r14
+    7f28:	d7 be       	out	0x37, r13	; 55
+    7f2a:	e8 95       	spm
 	    boot_spm_busy_wait();
-    7f44:	07 b6       	in	r0, 0x37	; 55
-    7f46:	00 fc       	sbrc	r0, 0
-    7f48:	fd cf       	rjmp	.-6      	; 0x7f44 <main+0x144>
+    7f2c:	07 b6       	in	r0, 0x37	; 55
+    7f2e:	00 fc       	sbrc	r0, 0
+    7f30:	fd cf       	rjmp	.-6      	; 0x7f2c <main+0x12c>
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    7f4a:	c7 be       	out	0x37, r12	; 55
-    7f4c:	e8 95       	spm
-    7f4e:	22 c0       	rjmp	.+68     	; 0x7f94 <main+0x194>
+    7f32:	c7 be       	out	0x37, r12	; 55
+    7f34:	e8 95       	spm
+    7f36:	1d c0       	rjmp	.+58     	; 0x7f72 <main+0x172>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    7f50:	84 37       	cpi	r24, 0x74	; 116
-    7f52:	91 f4       	brne	.+36     	; 0x7f78 <main+0x178>
+    7f38:	84 37       	cpi	r24, 0x74	; 116
+    7f3a:	69 f4       	brne	.+26     	; 0x7f56 <main+0x156>
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
-    7f54:	2a d0       	rcall	.+84     	; 0x7faa <getch>
-    7f56:	90 e0       	ldi	r25, 0x00	; 0
-    7f58:	d8 2f       	mov	r29, r24
-    7f5a:	cc 27       	eor	r28, r28
-      length |= getch();
-    7f5c:	26 d0       	rcall	.+76     	; 0x7faa <getch>
-    7f5e:	90 e0       	ldi	r25, 0x00	; 0
-    7f60:	c8 2b       	or	r28, r24
-    7f62:	d9 2b       	or	r29, r25
+      GETLENGTH(length);
+    7f3c:	25 d0       	rcall	.+74     	; 0x7f88 <getch>
+    7f3e:	24 d0       	rcall	.+72     	; 0x7f88 <getch>
+    7f40:	08 2f       	mov	r16, r24
+
       desttype = getch();
-    7f64:	22 d0       	rcall	.+68     	; 0x7faa <getch>
+    7f42:	22 d0       	rcall	.+68     	; 0x7f88 <getch>
 
       verifySpace();
-    7f66:	33 d0       	rcall	.+102    	; 0x7fce <verifySpace>
-    7f68:	85 01       	movw	r16, r10
+    7f44:	33 d0       	rcall	.+102    	; 0x7fac <verifySpace>
+    7f46:	e7 01       	movw	r28, r14
 	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
 	    // read a Flash byte and increment the address
 	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
 	    putch(ch);
-    7f6a:	f8 01       	movw	r30, r16
-    7f6c:	85 91       	lpm	r24, Z+
-    7f6e:	8f 01       	movw	r16, r30
-    7f70:	14 d0       	rcall	.+40     	; 0x7f9a <putch>
+    7f48:	fe 01       	movw	r30, r28
+    7f4a:	85 91       	lpm	r24, Z+
+    7f4c:	ef 01       	movw	r28, r30
+    7f4e:	14 d0       	rcall	.+40     	; 0x7f78 <putch>
 	} while (--length);
-    7f72:	21 97       	sbiw	r28, 0x01	; 1
-    7f74:	d1 f7       	brne	.-12     	; 0x7f6a <main+0x16a>
-    7f76:	0e c0       	rjmp	.+28     	; 0x7f94 <main+0x194>
+    7f50:	01 50       	subi	r16, 0x01	; 1
+    7f52:	d1 f7       	brne	.-12     	; 0x7f48 <main+0x148>
+    7f54:	0e c0       	rjmp	.+28     	; 0x7f72 <main+0x172>
 	  
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    7f78:	85 37       	cpi	r24, 0x75	; 117
-    7f7a:	39 f4       	brne	.+14     	; 0x7f8a <main+0x18a>
+    7f56:	85 37       	cpi	r24, 0x75	; 117
+    7f58:	39 f4       	brne	.+14     	; 0x7f68 <main+0x168>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    7f7c:	28 d0       	rcall	.+80     	; 0x7fce <verifySpace>
+    7f5a:	28 d0       	rcall	.+80     	; 0x7fac <verifySpace>
       putch(SIGNATURE_0);
-    7f7e:	8e e1       	ldi	r24, 0x1E	; 30
-    7f80:	0c d0       	rcall	.+24     	; 0x7f9a <putch>
+    7f5c:	8e e1       	ldi	r24, 0x1E	; 30
+    7f5e:	0c d0       	rcall	.+24     	; 0x7f78 <putch>
       putch(SIGNATURE_1);
-    7f82:	85 e9       	ldi	r24, 0x95	; 149
-    7f84:	0a d0       	rcall	.+20     	; 0x7f9a <putch>
+    7f60:	85 e9       	ldi	r24, 0x95	; 149
+    7f62:	0a d0       	rcall	.+20     	; 0x7f78 <putch>
       putch(SIGNATURE_2);
-    7f86:	8f e0       	ldi	r24, 0x0F	; 15
-    7f88:	7d cf       	rjmp	.-262    	; 0x7e84 <main+0x84>
+    7f64:	8f e0       	ldi	r24, 0x0F	; 15
+    7f66:	8e cf       	rjmp	.-228    	; 0x7e84 <main+0x84>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    7f8a:	81 35       	cpi	r24, 0x51	; 81
-    7f8c:	11 f4       	brne	.+4      	; 0x7f92 <main+0x192>
+    7f68:	81 35       	cpi	r24, 0x51	; 81
+    7f6a:	11 f4       	brne	.+4      	; 0x7f70 <main+0x170>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    7f8e:	88 e0       	ldi	r24, 0x08	; 8
-    7f90:	18 d0       	rcall	.+48     	; 0x7fc2 <watchdogConfig>
+    7f6c:	88 e0       	ldi	r24, 0x08	; 8
+    7f6e:	18 d0       	rcall	.+48     	; 0x7fa0 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    7f92:	1d d0       	rcall	.+58     	; 0x7fce <verifySpace>
+    7f70:	1d d0       	rcall	.+58     	; 0x7fac <verifySpace>
     }
     putch(STK_OK);
-    7f94:	80 e1       	ldi	r24, 0x10	; 16
-    7f96:	01 d0       	rcall	.+2      	; 0x7f9a <putch>
-    7f98:	66 cf       	rjmp	.-308    	; 0x7e66 <main+0x66>
+    7f72:	80 e1       	ldi	r24, 0x10	; 16
+    7f74:	01 d0       	rcall	.+2      	; 0x7f78 <putch>
+    7f76:	77 cf       	rjmp	.-274    	; 0x7e66 <main+0x66>
 
-00007f9a <putch>:
+00007f78 <putch>:
   }
 }
 
 void putch(char ch) {
-    7f9a:	98 2f       	mov	r25, r24
+    7f78:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    7f9c:	80 91 c0 00 	lds	r24, 0x00C0
-    7fa0:	85 ff       	sbrs	r24, 5
-    7fa2:	fc cf       	rjmp	.-8      	; 0x7f9c <putch+0x2>
+    7f7a:	80 91 c0 00 	lds	r24, 0x00C0
+    7f7e:	85 ff       	sbrs	r24, 5
+    7f80:	fc cf       	rjmp	.-8      	; 0x7f7a <putch+0x2>
   UART_UDR = ch;
-    7fa4:	90 93 c6 00 	sts	0x00C6, r25
+    7f82:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    7fa8:	08 95       	ret
+    7f86:	08 95       	ret
 
-00007faa <getch>:
+00007f88 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    7faa:	80 91 c0 00 	lds	r24, 0x00C0
-    7fae:	87 ff       	sbrs	r24, 7
-    7fb0:	fc cf       	rjmp	.-8      	; 0x7faa <getch>
+    7f88:	80 91 c0 00 	lds	r24, 0x00C0
+    7f8c:	87 ff       	sbrs	r24, 7
+    7f8e:	fc cf       	rjmp	.-8      	; 0x7f88 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    7fb2:	80 91 c0 00 	lds	r24, 0x00C0
-    7fb6:	84 fd       	sbrc	r24, 4
-    7fb8:	01 c0       	rjmp	.+2      	; 0x7fbc <getch+0x12>
+    7f90:	80 91 c0 00 	lds	r24, 0x00C0
+    7f94:	84 fd       	sbrc	r24, 4
+    7f96:	01 c0       	rjmp	.+2      	; 0x7f9a <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    7fba:	a8 95       	wdr
+    7f98:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
   ch = UART_UDR;
-    7fbc:	80 91 c6 00 	lds	r24, 0x00C6
+    7f9a:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    7fc0:	08 95       	ret
+    7f9e:	08 95       	ret
 
-00007fc2 <watchdogConfig>:
+00007fa0 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7fc2:	e0 e6       	ldi	r30, 0x60	; 96
-    7fc4:	f0 e0       	ldi	r31, 0x00	; 0
-    7fc6:	98 e1       	ldi	r25, 0x18	; 24
-    7fc8:	90 83       	st	Z, r25
+    7fa0:	e0 e6       	ldi	r30, 0x60	; 96
+    7fa2:	f0 e0       	ldi	r31, 0x00	; 0
+    7fa4:	98 e1       	ldi	r25, 0x18	; 24
+    7fa6:	90 83       	st	Z, r25
   WDTCSR = x;
-    7fca:	80 83       	st	Z, r24
+    7fa8:	80 83       	st	Z, r24
 }
-    7fcc:	08 95       	ret
+    7faa:	08 95       	ret
 
-00007fce <verifySpace>:
+00007fac <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    7fce:	ed df       	rcall	.-38     	; 0x7faa <getch>
-    7fd0:	80 32       	cpi	r24, 0x20	; 32
-    7fd2:	19 f0       	breq	.+6      	; 0x7fda <verifySpace+0xc>
+    7fac:	ed df       	rcall	.-38     	; 0x7f88 <getch>
+    7fae:	80 32       	cpi	r24, 0x20	; 32
+    7fb0:	19 f0       	breq	.+6      	; 0x7fb8 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    7fd4:	88 e0       	ldi	r24, 0x08	; 8
-    7fd6:	f5 df       	rcall	.-22     	; 0x7fc2 <watchdogConfig>
-    7fd8:	ff cf       	rjmp	.-2      	; 0x7fd8 <verifySpace+0xa>
+    7fb2:	88 e0       	ldi	r24, 0x08	; 8
+    7fb4:	f5 df       	rcall	.-22     	; 0x7fa0 <watchdogConfig>
+    7fb6:	ff cf       	rjmp	.-2      	; 0x7fb6 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    7fda:	84 e1       	ldi	r24, 0x14	; 20
+    7fb8:	84 e1       	ldi	r24, 0x14	; 20
 }
-    7fdc:	de cf       	rjmp	.-68     	; 0x7f9a <putch>
+    7fba:	de cf       	rjmp	.-68     	; 0x7f78 <putch>
 
-00007fde <getNch>:
+00007fbc <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    7fde:	1f 93       	push	r17
-    7fe0:	18 2f       	mov	r17, r24
+    7fbc:	1f 93       	push	r17
+    7fbe:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    7fe2:	e3 df       	rcall	.-58     	; 0x7faa <getch>
-    7fe4:	11 50       	subi	r17, 0x01	; 1
-    7fe6:	e9 f7       	brne	.-6      	; 0x7fe2 <getNch+0x4>
+    7fc0:	e3 df       	rcall	.-58     	; 0x7f88 <getch>
+    7fc2:	11 50       	subi	r17, 0x01	; 1
+    7fc4:	e9 f7       	brne	.-6      	; 0x7fc0 <getNch+0x4>
   verifySpace();
-    7fe8:	f2 df       	rcall	.-28     	; 0x7fce <verifySpace>
+    7fc6:	f2 df       	rcall	.-28     	; 0x7fac <verifySpace>
 }
-    7fea:	1f 91       	pop	r17
-    7fec:	08 95       	ret
+    7fc8:	1f 91       	pop	r17
+    7fca:	08 95       	ret
 
-00007fee <appStart>:
+00007fcc <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    7fee:	28 2e       	mov	r2, r24
+    7fcc:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    7ff0:	80 e0       	ldi	r24, 0x00	; 0
-    7ff2:	e7 df       	rcall	.-50     	; 0x7fc2 <watchdogConfig>
+    7fce:	80 e0       	ldi	r24, 0x00	; 0
+    7fd0:	e7 df       	rcall	.-50     	; 0x7fa0 <watchdogConfig>
   __asm__ __volatile__ (
-    7ff4:	ee 27       	eor	r30, r30
-    7ff6:	ff 27       	eor	r31, r31
-    7ff8:	09 94       	ijmp
+    7fd2:	ee 27       	eor	r30, r30
+    7fd4:	ff 27       	eor	r31, r31
+    7fd6:	09 94       	ijmp

+ 28 - 30
optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex

@@ -1,35 +1,33 @@
-:107E0000112494B714BE892F8D7011F0892FEFD0F3
+:107E0000112494B714BE892F8D7011F0892FDED004
 :107E100085E08093810082E08093C00088E18093B8
 :107E2000C10086E08093C20088E08093C4008EE0A9
-:107E3000C8D0259A86E028E13EEF91E03093850096
+:107E3000B7D0259A86E028E13EEF91E030938500A7
 :107E40002093840096BBB09BFECF1D9AA8958150CD
-:107E5000A9F7AA24BB2433E0832E7724739425E06A
-:107E6000922E91E1C92EA1D0813471F49ED0182FA9
-:107E7000AED0123811F481E005C0113811F486E05B
-:107E800001C083E08AD086C0823411F484E103C04B
-:107E9000853419F485E0A3D07DC0853579F485D08B
-:107EA000E82EFF2482D0082F10E0102F00270E2983
-:107EB0001F29000F111F8BD058016CC0863521F48B
-:107EC00084E08DD080E0DECF843609F041C06DD0F3
-:107ED00090E0182F002769D090E0082B192B65D06F
-:107EE000D82EE801E12CF1E0FF2E5FD0F70181935D
-:107EF0007F012197D1F76BD0F5E4DF1609F4FFCFAE
-:107F0000F50187BEE89507B600FCFDCFB501A801D5
-:107F1000A0E0B1E02C9130E011968C91119790E0A7
-:107F2000982F8827822B932B1296FB010C0177BE8A
-:107F3000E89511246E5F7F4F4250504059F7F5018C
-:107F400097BEE89507B600FCFDCFC7BEE89522C0F6
-:107F5000843791F42AD090E0D82FCC2726D090E017
-:107F6000C82BD92B22D033D08501F80185918F0100
-:107F700014D02197D1F70EC0853739F428D08EE17F
-:107F80000CD085E90AD08FE07DCF813511F488E0EF
-:107F900018D01DD080E101D066CF982F8091C0000D
-:107FA00085FFFCCF9093C60008958091C00087FFA5
-:107FB000FCCF8091C00084FD01C0A8958091C600CF
-:107FC0000895E0E6F0E098E1908380830895EDDF86
-:107FD000803219F088E0F5DFFFCF84E1DECF1F9318
-:107FE000182FE3DF1150E9F7F2DF1F910895282ED3
-:0A7FF00080E0E7DFEE27FF27099489
-:027FFE0001067A
+:107E5000A9F7EE24FF24B3E0AB2EBB24B394A5E036
+:107E6000DA2EF1E1CF2E90D0813471F48DD0082F2D
+:107E70009DD0023811F482E005C0013811F486E08B
+:107E800001C083E079D075C0823411F484E103C06D
+:107E9000853419F485E092D06CC0853579F474D0BE
+:107EA000E82EFF2471D0082F10E0102F00270E2994
+:107EB0001F29000F111F7AD078015BC0863521F48D
+:107EC00084E07CD080E0DECF843609F035C05CD021
+:107ED0005BD0182F59D0082FC0E0D1E055D089933E
+:107EE0001C17E1F763D0053409F4FFCFF701A7BEF3
+:107EF000E89507B600FCFDCFA701A0E0B1E02C910A
+:107F000030E011968C91119790E0982F8827822B62
+:107F1000932B1296FA010C01B7BEE89511244E5F1F
+:107F20005F4F1A1761F7F701D7BEE89507B600FC57
+:107F3000FDCFC7BEE8951DC0843769F425D024D095
+:107F4000082F22D033D0E701FE018591EF0114D034
+:107F50000150D1F70EC0853739F428D08EE10CD00E
+:107F600085E90AD08FE08ECF813511F488E018D0F2
+:107F70001DD080E101D077CF982F8091C00085FF80
+:107F8000FCCF9093C60008958091C00087FFFCCF7E
+:107F90008091C00084FD01C0A8958091C60008951D
+:107FA000E0E6F0E098E1908380830895EDDF803291
+:107FB00019F088E0F5DFFFCF84E1DECF1F93182FA3
+:107FC000E3DF1150E9F7F2DF1F910895282E80E0DA
+:087FD000E7DFEE27FF2709940B
+:027FFE00020679
 :0400000300007E007B
 :00000001FF

+ 179 - 197
optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst

@@ -3,27 +3,27 @@ optiboot_atmega328.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001fa  00007e00  00007e00  00000074  2**1
+  0 .text         000001d8  00007e00  00007e00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00007ffe  00007ffe  0000026e  2**0
+  1 .version      00000002  00007ffe  00007ffe  0000024c  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  00000270  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000298  2**0
+  3 .debug_pubnames 00000074  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003e0  00000000  00000000  0000030c  2**0
+  4 .debug_info   000003ea  00000000  00000000  000002ea  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001f1  00000000  00000000  000006ec  2**0
+  5 .debug_abbrev 000001ef  00000000  00000000  000006d4  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000043b  00000000  00000000  000008dd  2**0
+  6 .debug_line   0000042b  00000000  00000000  000008c3  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000d18  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000cf0  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000172  00000000  00000000  00000d98  2**0
+  8 .debug_str    0000017c  00000000  00000000  00000d70  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d7  00000000  00000000  00000f0a  2**0
+  9 .debug_loc    00000300  00000000  00000000  00000eec  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011e1  2**0
+ 10 .debug_ranges 000000b8  00000000  00000000  000011ec  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -51,7 +51,7 @@ int main(void) {
     7e0a:	11 f0       	breq	.+4      	; 0x7e10 <main+0x10>
       appStart(ch);
     7e0c:	89 2f       	mov	r24, r25
-    7e0e:	ef d0       	rcall	.+478    	; 0x7fee <appStart>
+    7e0e:	de d0       	rcall	.+444    	; 0x7fcc <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -81,7 +81,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     7e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    7e30:	c8 d0       	rcall	.+400    	; 0x7fc2 <watchdogConfig>
+    7e30:	b7 d0       	rcall	.+366    	; 0x7fa0 <watchdogConfig>
 
 #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
   /* Set LED pin as output */
@@ -131,66 +131,66 @@ void watchdogReset() {
   } while (--count);
     7e4e:	81 50       	subi	r24, 0x01	; 1
     7e50:	a9 f7       	brne	.-22     	; 0x7e3c <main+0x3c>
-    7e52:	aa 24       	eor	r10, r10
-    7e54:	bb 24       	eor	r11, r11
+    7e52:	ee 24       	eor	r14, r14
+    7e54:	ff 24       	eor	r15, r15
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    7e56:	33 e0       	ldi	r19, 0x03	; 3
-    7e58:	83 2e       	mov	r8, r19
+    7e56:	b3 e0       	ldi	r27, 0x03	; 3
+    7e58:	ab 2e       	mov	r10, r27
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7e5a:	77 24       	eor	r7, r7
-    7e5c:	73 94       	inc	r7
+    7e5a:	bb 24       	eor	r11, r11
+    7e5c:	b3 94       	inc	r11
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    7e5e:	25 e0       	ldi	r18, 0x05	; 5
-    7e60:	92 2e       	mov	r9, r18
+    7e5e:	a5 e0       	ldi	r26, 0x05	; 5
+    7e60:	da 2e       	mov	r13, r26
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    7e62:	91 e1       	ldi	r25, 0x11	; 17
-    7e64:	c9 2e       	mov	r12, r25
+    7e62:	f1 e1       	ldi	r31, 0x11	; 17
+    7e64:	cf 2e       	mov	r12, r31
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    7e66:	a1 d0       	rcall	.+322    	; 0x7faa <getch>
+    7e66:	90 d0       	rcall	.+288    	; 0x7f88 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     7e68:	81 34       	cpi	r24, 0x41	; 65
     7e6a:	71 f4       	brne	.+28     	; 0x7e88 <main+0x88>
       unsigned char which = getch();
-    7e6c:	9e d0       	rcall	.+316    	; 0x7faa <getch>
-    7e6e:	18 2f       	mov	r17, r24
+    7e6c:	8d d0       	rcall	.+282    	; 0x7f88 <getch>
+    7e6e:	08 2f       	mov	r16, r24
       verifySpace();
-    7e70:	ae d0       	rcall	.+348    	; 0x7fce <verifySpace>
+    7e70:	9d d0       	rcall	.+314    	; 0x7fac <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
       if (which == 0x82) {
-    7e72:	12 38       	cpi	r17, 0x82	; 130
+    7e72:	02 38       	cpi	r16, 0x82	; 130
     7e74:	11 f4       	brne	.+4      	; 0x7e7a <main+0x7a>
 	  putch(optiboot_version & 0xFF);
-    7e76:	81 e0       	ldi	r24, 0x01	; 1
+    7e76:	82 e0       	ldi	r24, 0x02	; 2
     7e78:	05 c0       	rjmp	.+10     	; 0x7e84 <main+0x84>
       } else if (which == 0x81) {
-    7e7a:	11 38       	cpi	r17, 0x81	; 129
+    7e7a:	01 38       	cpi	r16, 0x81	; 129
     7e7c:	11 f4       	brne	.+4      	; 0x7e82 <main+0x82>
 	  putch(optiboot_version >> 8);
     7e7e:	86 e0       	ldi	r24, 0x06	; 6
@@ -202,8 +202,8 @@ void watchdogReset() {
 	 */
 	putch(0x03);
     7e82:	83 e0       	ldi	r24, 0x03	; 3
-    7e84:	8a d0       	rcall	.+276    	; 0x7f9a <putch>
-    7e86:	86 c0       	rjmp	.+268    	; 0x7f94 <main+0x194>
+    7e84:	79 d0       	rcall	.+242    	; 0x7f78 <putch>
+    7e86:	75 c0       	rjmp	.+234    	; 0x7f72 <main+0x172>
       }
     }
     else if(ch == STK_SET_DEVICE) {
@@ -220,8 +220,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     7e94:	85 e0       	ldi	r24, 0x05	; 5
-    7e96:	a3 d0       	rcall	.+326    	; 0x7fde <getNch>
-    7e98:	7d c0       	rjmp	.+250    	; 0x7f94 <main+0x194>
+    7e96:	92 d0       	rcall	.+292    	; 0x7fbc <getNch>
+    7e98:	6c c0       	rjmp	.+216    	; 0x7f72 <main+0x172>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     7e9a:	85 35       	cpi	r24, 0x55	; 85
@@ -229,11 +229,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    7e9e:	85 d0       	rcall	.+266    	; 0x7faa <getch>
+    7e9e:	74 d0       	rcall	.+232    	; 0x7f88 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     7ea0:	e8 2e       	mov	r14, r24
     7ea2:	ff 24       	eor	r15, r15
-    7ea4:	82 d0       	rcall	.+260    	; 0x7faa <getch>
+    7ea4:	71 d0       	rcall	.+226    	; 0x7f88 <getch>
     7ea6:	08 2f       	mov	r16, r24
     7ea8:	10 e0       	ldi	r17, 0x00	; 0
     7eaa:	10 2f       	mov	r17, r16
@@ -249,9 +249,9 @@ void watchdogReset() {
     7eb4:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    7eb6:	8b d0       	rcall	.+278    	; 0x7fce <verifySpace>
-    7eb8:	58 01       	movw	r10, r16
-    7eba:	6c c0       	rjmp	.+216    	; 0x7f94 <main+0x194>
+    7eb6:	7a d0       	rcall	.+244    	; 0x7fac <verifySpace>
+    7eb8:	78 01       	movw	r14, r16
+    7eba:	5b c0       	rjmp	.+182    	; 0x7f72 <main+0x172>
     }
     else if(ch == STK_UNIVERSAL) {
     7ebc:	86 35       	cpi	r24, 0x56	; 86
@@ -259,7 +259,7 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     7ec0:	84 e0       	ldi	r24, 0x04	; 4
-    7ec2:	8d d0       	rcall	.+282    	; 0x7fde <getNch>
+    7ec2:	7c d0       	rcall	.+248    	; 0x7fbc <getNch>
       putch(0x00);
     7ec4:	80 e0       	ldi	r24, 0x00	; 0
     7ec6:	de cf       	rjmp	.-68     	; 0x7e84 <main+0x84>
@@ -268,339 +268,321 @@ void watchdogReset() {
     else if(ch == STK_PROG_PAGE) {
     7ec8:	84 36       	cpi	r24, 0x64	; 100
     7eca:	09 f0       	breq	.+2      	; 0x7ece <main+0xce>
-    7ecc:	41 c0       	rjmp	.+130    	; 0x7f50 <main+0x150>
+    7ecc:	35 c0       	rjmp	.+106    	; 0x7f38 <main+0x138>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
-    7ece:	6d d0       	rcall	.+218    	; 0x7faa <getch>
-    7ed0:	90 e0       	ldi	r25, 0x00	; 0
+      GETLENGTH(length);
+    7ece:	5c d0       	rcall	.+184    	; 0x7f88 <getch>
+    7ed0:	5b d0       	rcall	.+182    	; 0x7f88 <getch>
     7ed2:	18 2f       	mov	r17, r24
-    7ed4:	00 27       	eor	r16, r16
-      length |= getch();
-    7ed6:	69 d0       	rcall	.+210    	; 0x7faa <getch>
-    7ed8:	90 e0       	ldi	r25, 0x00	; 0
-    7eda:	08 2b       	or	r16, r24
-    7edc:	19 2b       	or	r17, r25
       savelength = length;
       desttype = getch();
-    7ede:	65 d0       	rcall	.+202    	; 0x7faa <getch>
-    7ee0:	d8 2e       	mov	r13, r24
-    7ee2:	e8 01       	movw	r28, r16
-    7ee4:	e1 2c       	mov	r14, r1
-    7ee6:	f1 e0       	ldi	r31, 0x01	; 1
-    7ee8:	ff 2e       	mov	r15, r31
+    7ed4:	59 d0       	rcall	.+178    	; 0x7f88 <getch>
+    7ed6:	08 2f       	mov	r16, r24
+    7ed8:	c0 e0       	ldi	r28, 0x00	; 0
+    7eda:	d1 e0       	ldi	r29, 0x01	; 1
 
       // read a page worth of contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    7eea:	5f d0       	rcall	.+190    	; 0x7faa <getch>
-    7eec:	f7 01       	movw	r30, r14
-    7eee:	81 93       	st	Z+, r24
-    7ef0:	7f 01       	movw	r14, r30
+    7edc:	55 d0       	rcall	.+170    	; 0x7f88 <getch>
+    7ede:	89 93       	st	Y+, r24
       while (--length);
-    7ef2:	21 97       	sbiw	r28, 0x01	; 1
-    7ef4:	d1 f7       	brne	.-12     	; 0x7eea <main+0xea>
+    7ee0:	1c 17       	cp	r17, r28
+    7ee2:	e1 f7       	brne	.-8      	; 0x7edc <main+0xdc>
 
       // Read command terminator, start reply
       verifySpace();
-    7ef6:	6b d0       	rcall	.+214    	; 0x7fce <verifySpace>
+    7ee4:	63 d0       	rcall	.+198    	; 0x7fac <verifySpace>
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
-    7ef8:	f5 e4       	ldi	r31, 0x45	; 69
-    7efa:	df 16       	cp	r13, r31
-    7efc:	09 f4       	brne	.+2      	; 0x7f00 <main+0x100>
-    7efe:	ff cf       	rjmp	.-2      	; 0x7efe <main+0xfe>
+    7ee6:	05 34       	cpi	r16, 0x45	; 69
+    7ee8:	09 f4       	brne	.+2      	; 0x7eec <main+0xec>
+    7eea:	ff cf       	rjmp	.-2      	; 0x7eea <main+0xea>
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    7f00:	f5 01       	movw	r30, r10
-    7f02:	87 be       	out	0x37, r8	; 55
-    7f04:	e8 95       	spm
+    7eec:	f7 01       	movw	r30, r14
+    7eee:	a7 be       	out	0x37, r10	; 55
+    7ef0:	e8 95       	spm
 	    boot_spm_busy_wait();
-    7f06:	07 b6       	in	r0, 0x37	; 55
-    7f08:	00 fc       	sbrc	r0, 0
-    7f0a:	fd cf       	rjmp	.-6      	; 0x7f06 <main+0x106>
-    7f0c:	b5 01       	movw	r22, r10
-    7f0e:	a8 01       	movw	r20, r16
-    7f10:	a0 e0       	ldi	r26, 0x00	; 0
-    7f12:	b1 e0       	ldi	r27, 0x01	; 1
+    7ef2:	07 b6       	in	r0, 0x37	; 55
+    7ef4:	00 fc       	sbrc	r0, 0
+    7ef6:	fd cf       	rjmp	.-6      	; 0x7ef2 <main+0xf2>
+    7ef8:	a7 01       	movw	r20, r14
+    7efa:	a0 e0       	ldi	r26, 0x00	; 0
+    7efc:	b1 e0       	ldi	r27, 0x01	; 1
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
-    7f14:	2c 91       	ld	r18, X
-    7f16:	30 e0       	ldi	r19, 0x00	; 0
+    7efe:	2c 91       	ld	r18, X
+    7f00:	30 e0       	ldi	r19, 0x00	; 0
 		a |= (*bufPtr++) << 8;
-    7f18:	11 96       	adiw	r26, 0x01	; 1
-    7f1a:	8c 91       	ld	r24, X
-    7f1c:	11 97       	sbiw	r26, 0x01	; 1
-    7f1e:	90 e0       	ldi	r25, 0x00	; 0
-    7f20:	98 2f       	mov	r25, r24
-    7f22:	88 27       	eor	r24, r24
-    7f24:	82 2b       	or	r24, r18
-    7f26:	93 2b       	or	r25, r19
+    7f02:	11 96       	adiw	r26, 0x01	; 1
+    7f04:	8c 91       	ld	r24, X
+    7f06:	11 97       	sbiw	r26, 0x01	; 1
+    7f08:	90 e0       	ldi	r25, 0x00	; 0
+    7f0a:	98 2f       	mov	r25, r24
+    7f0c:	88 27       	eor	r24, r24
+    7f0e:	82 2b       	or	r24, r18
+    7f10:	93 2b       	or	r25, r19
 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
 
 /* main program starts here */
 int main(void) {
-    7f28:	12 96       	adiw	r26, 0x02	; 2
+    7f12:	12 96       	adiw	r26, 0x02	; 2
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7f2a:	fb 01       	movw	r30, r22
-    7f2c:	0c 01       	movw	r0, r24
-    7f2e:	77 be       	out	0x37, r7	; 55
-    7f30:	e8 95       	spm
-    7f32:	11 24       	eor	r1, r1
+    7f14:	fa 01       	movw	r30, r20
+    7f16:	0c 01       	movw	r0, r24
+    7f18:	b7 be       	out	0x37, r11	; 55
+    7f1a:	e8 95       	spm
+    7f1c:	11 24       	eor	r1, r1
 		addrPtr += 2;
-    7f34:	6e 5f       	subi	r22, 0xFE	; 254
-    7f36:	7f 4f       	sbci	r23, 0xFF	; 255
+    7f1e:	4e 5f       	subi	r20, 0xFE	; 254
+    7f20:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    7f38:	42 50       	subi	r20, 0x02	; 2
-    7f3a:	50 40       	sbci	r21, 0x00	; 0
-    7f3c:	59 f7       	brne	.-42     	; 0x7f14 <main+0x114>
+    7f22:	1a 17       	cp	r17, r26
+    7f24:	61 f7       	brne	.-40     	; 0x7efe <main+0xfe>
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    7f3e:	f5 01       	movw	r30, r10
-    7f40:	97 be       	out	0x37, r9	; 55
-    7f42:	e8 95       	spm
+    7f26:	f7 01       	movw	r30, r14
+    7f28:	d7 be       	out	0x37, r13	; 55
+    7f2a:	e8 95       	spm
 	    boot_spm_busy_wait();
-    7f44:	07 b6       	in	r0, 0x37	; 55
-    7f46:	00 fc       	sbrc	r0, 0
-    7f48:	fd cf       	rjmp	.-6      	; 0x7f44 <main+0x144>
+    7f2c:	07 b6       	in	r0, 0x37	; 55
+    7f2e:	00 fc       	sbrc	r0, 0
+    7f30:	fd cf       	rjmp	.-6      	; 0x7f2c <main+0x12c>
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    7f4a:	c7 be       	out	0x37, r12	; 55
-    7f4c:	e8 95       	spm
-    7f4e:	22 c0       	rjmp	.+68     	; 0x7f94 <main+0x194>
+    7f32:	c7 be       	out	0x37, r12	; 55
+    7f34:	e8 95       	spm
+    7f36:	1d c0       	rjmp	.+58     	; 0x7f72 <main+0x172>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    7f50:	84 37       	cpi	r24, 0x74	; 116
-    7f52:	91 f4       	brne	.+36     	; 0x7f78 <main+0x178>
+    7f38:	84 37       	cpi	r24, 0x74	; 116
+    7f3a:	69 f4       	brne	.+26     	; 0x7f56 <main+0x156>
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
-    7f54:	2a d0       	rcall	.+84     	; 0x7faa <getch>
-    7f56:	90 e0       	ldi	r25, 0x00	; 0
-    7f58:	d8 2f       	mov	r29, r24
-    7f5a:	cc 27       	eor	r28, r28
-      length |= getch();
-    7f5c:	26 d0       	rcall	.+76     	; 0x7faa <getch>
-    7f5e:	90 e0       	ldi	r25, 0x00	; 0
-    7f60:	c8 2b       	or	r28, r24
-    7f62:	d9 2b       	or	r29, r25
+      GETLENGTH(length);
+    7f3c:	25 d0       	rcall	.+74     	; 0x7f88 <getch>
+    7f3e:	24 d0       	rcall	.+72     	; 0x7f88 <getch>
+    7f40:	08 2f       	mov	r16, r24
+
       desttype = getch();
-    7f64:	22 d0       	rcall	.+68     	; 0x7faa <getch>
+    7f42:	22 d0       	rcall	.+68     	; 0x7f88 <getch>
 
       verifySpace();
-    7f66:	33 d0       	rcall	.+102    	; 0x7fce <verifySpace>
-    7f68:	85 01       	movw	r16, r10
+    7f44:	33 d0       	rcall	.+102    	; 0x7fac <verifySpace>
+    7f46:	e7 01       	movw	r28, r14
 	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
 	    // read a Flash byte and increment the address
 	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
 	    putch(ch);
-    7f6a:	f8 01       	movw	r30, r16
-    7f6c:	85 91       	lpm	r24, Z+
-    7f6e:	8f 01       	movw	r16, r30
-    7f70:	14 d0       	rcall	.+40     	; 0x7f9a <putch>
+    7f48:	fe 01       	movw	r30, r28
+    7f4a:	85 91       	lpm	r24, Z+
+    7f4c:	ef 01       	movw	r28, r30
+    7f4e:	14 d0       	rcall	.+40     	; 0x7f78 <putch>
 	} while (--length);
-    7f72:	21 97       	sbiw	r28, 0x01	; 1
-    7f74:	d1 f7       	brne	.-12     	; 0x7f6a <main+0x16a>
-    7f76:	0e c0       	rjmp	.+28     	; 0x7f94 <main+0x194>
+    7f50:	01 50       	subi	r16, 0x01	; 1
+    7f52:	d1 f7       	brne	.-12     	; 0x7f48 <main+0x148>
+    7f54:	0e c0       	rjmp	.+28     	; 0x7f72 <main+0x172>
 	  
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    7f78:	85 37       	cpi	r24, 0x75	; 117
-    7f7a:	39 f4       	brne	.+14     	; 0x7f8a <main+0x18a>
+    7f56:	85 37       	cpi	r24, 0x75	; 117
+    7f58:	39 f4       	brne	.+14     	; 0x7f68 <main+0x168>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    7f7c:	28 d0       	rcall	.+80     	; 0x7fce <verifySpace>
+    7f5a:	28 d0       	rcall	.+80     	; 0x7fac <verifySpace>
       putch(SIGNATURE_0);
-    7f7e:	8e e1       	ldi	r24, 0x1E	; 30
-    7f80:	0c d0       	rcall	.+24     	; 0x7f9a <putch>
+    7f5c:	8e e1       	ldi	r24, 0x1E	; 30
+    7f5e:	0c d0       	rcall	.+24     	; 0x7f78 <putch>
       putch(SIGNATURE_1);
-    7f82:	85 e9       	ldi	r24, 0x95	; 149
-    7f84:	0a d0       	rcall	.+20     	; 0x7f9a <putch>
+    7f60:	85 e9       	ldi	r24, 0x95	; 149
+    7f62:	0a d0       	rcall	.+20     	; 0x7f78 <putch>
       putch(SIGNATURE_2);
-    7f86:	8f e0       	ldi	r24, 0x0F	; 15
-    7f88:	7d cf       	rjmp	.-262    	; 0x7e84 <main+0x84>
+    7f64:	8f e0       	ldi	r24, 0x0F	; 15
+    7f66:	8e cf       	rjmp	.-228    	; 0x7e84 <main+0x84>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    7f8a:	81 35       	cpi	r24, 0x51	; 81
-    7f8c:	11 f4       	brne	.+4      	; 0x7f92 <main+0x192>
+    7f68:	81 35       	cpi	r24, 0x51	; 81
+    7f6a:	11 f4       	brne	.+4      	; 0x7f70 <main+0x170>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    7f8e:	88 e0       	ldi	r24, 0x08	; 8
-    7f90:	18 d0       	rcall	.+48     	; 0x7fc2 <watchdogConfig>
+    7f6c:	88 e0       	ldi	r24, 0x08	; 8
+    7f6e:	18 d0       	rcall	.+48     	; 0x7fa0 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    7f92:	1d d0       	rcall	.+58     	; 0x7fce <verifySpace>
+    7f70:	1d d0       	rcall	.+58     	; 0x7fac <verifySpace>
     }
     putch(STK_OK);
-    7f94:	80 e1       	ldi	r24, 0x10	; 16
-    7f96:	01 d0       	rcall	.+2      	; 0x7f9a <putch>
-    7f98:	66 cf       	rjmp	.-308    	; 0x7e66 <main+0x66>
+    7f72:	80 e1       	ldi	r24, 0x10	; 16
+    7f74:	01 d0       	rcall	.+2      	; 0x7f78 <putch>
+    7f76:	77 cf       	rjmp	.-274    	; 0x7e66 <main+0x66>
 
-00007f9a <putch>:
+00007f78 <putch>:
   }
 }
 
 void putch(char ch) {
-    7f9a:	98 2f       	mov	r25, r24
+    7f78:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    7f9c:	80 91 c0 00 	lds	r24, 0x00C0
-    7fa0:	85 ff       	sbrs	r24, 5
-    7fa2:	fc cf       	rjmp	.-8      	; 0x7f9c <putch+0x2>
+    7f7a:	80 91 c0 00 	lds	r24, 0x00C0
+    7f7e:	85 ff       	sbrs	r24, 5
+    7f80:	fc cf       	rjmp	.-8      	; 0x7f7a <putch+0x2>
   UART_UDR = ch;
-    7fa4:	90 93 c6 00 	sts	0x00C6, r25
+    7f82:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    7fa8:	08 95       	ret
+    7f86:	08 95       	ret
 
-00007faa <getch>:
+00007f88 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    7faa:	80 91 c0 00 	lds	r24, 0x00C0
-    7fae:	87 ff       	sbrs	r24, 7
-    7fb0:	fc cf       	rjmp	.-8      	; 0x7faa <getch>
+    7f88:	80 91 c0 00 	lds	r24, 0x00C0
+    7f8c:	87 ff       	sbrs	r24, 7
+    7f8e:	fc cf       	rjmp	.-8      	; 0x7f88 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    7fb2:	80 91 c0 00 	lds	r24, 0x00C0
-    7fb6:	84 fd       	sbrc	r24, 4
-    7fb8:	01 c0       	rjmp	.+2      	; 0x7fbc <getch+0x12>
+    7f90:	80 91 c0 00 	lds	r24, 0x00C0
+    7f94:	84 fd       	sbrc	r24, 4
+    7f96:	01 c0       	rjmp	.+2      	; 0x7f9a <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    7fba:	a8 95       	wdr
+    7f98:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
   ch = UART_UDR;
-    7fbc:	80 91 c6 00 	lds	r24, 0x00C6
+    7f9a:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    7fc0:	08 95       	ret
+    7f9e:	08 95       	ret
 
-00007fc2 <watchdogConfig>:
+00007fa0 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7fc2:	e0 e6       	ldi	r30, 0x60	; 96
-    7fc4:	f0 e0       	ldi	r31, 0x00	; 0
-    7fc6:	98 e1       	ldi	r25, 0x18	; 24
-    7fc8:	90 83       	st	Z, r25
+    7fa0:	e0 e6       	ldi	r30, 0x60	; 96
+    7fa2:	f0 e0       	ldi	r31, 0x00	; 0
+    7fa4:	98 e1       	ldi	r25, 0x18	; 24
+    7fa6:	90 83       	st	Z, r25
   WDTCSR = x;
-    7fca:	80 83       	st	Z, r24
+    7fa8:	80 83       	st	Z, r24
 }
-    7fcc:	08 95       	ret
+    7faa:	08 95       	ret
 
-00007fce <verifySpace>:
+00007fac <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    7fce:	ed df       	rcall	.-38     	; 0x7faa <getch>
-    7fd0:	80 32       	cpi	r24, 0x20	; 32
-    7fd2:	19 f0       	breq	.+6      	; 0x7fda <verifySpace+0xc>
+    7fac:	ed df       	rcall	.-38     	; 0x7f88 <getch>
+    7fae:	80 32       	cpi	r24, 0x20	; 32
+    7fb0:	19 f0       	breq	.+6      	; 0x7fb8 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    7fd4:	88 e0       	ldi	r24, 0x08	; 8
-    7fd6:	f5 df       	rcall	.-22     	; 0x7fc2 <watchdogConfig>
-    7fd8:	ff cf       	rjmp	.-2      	; 0x7fd8 <verifySpace+0xa>
+    7fb2:	88 e0       	ldi	r24, 0x08	; 8
+    7fb4:	f5 df       	rcall	.-22     	; 0x7fa0 <watchdogConfig>
+    7fb6:	ff cf       	rjmp	.-2      	; 0x7fb6 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    7fda:	84 e1       	ldi	r24, 0x14	; 20
+    7fb8:	84 e1       	ldi	r24, 0x14	; 20
 }
-    7fdc:	de cf       	rjmp	.-68     	; 0x7f9a <putch>
+    7fba:	de cf       	rjmp	.-68     	; 0x7f78 <putch>
 
-00007fde <getNch>:
+00007fbc <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    7fde:	1f 93       	push	r17
-    7fe0:	18 2f       	mov	r17, r24
+    7fbc:	1f 93       	push	r17
+    7fbe:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    7fe2:	e3 df       	rcall	.-58     	; 0x7faa <getch>
-    7fe4:	11 50       	subi	r17, 0x01	; 1
-    7fe6:	e9 f7       	brne	.-6      	; 0x7fe2 <getNch+0x4>
+    7fc0:	e3 df       	rcall	.-58     	; 0x7f88 <getch>
+    7fc2:	11 50       	subi	r17, 0x01	; 1
+    7fc4:	e9 f7       	brne	.-6      	; 0x7fc0 <getNch+0x4>
   verifySpace();
-    7fe8:	f2 df       	rcall	.-28     	; 0x7fce <verifySpace>
+    7fc6:	f2 df       	rcall	.-28     	; 0x7fac <verifySpace>
 }
-    7fea:	1f 91       	pop	r17
-    7fec:	08 95       	ret
+    7fc8:	1f 91       	pop	r17
+    7fca:	08 95       	ret
 
-00007fee <appStart>:
+00007fcc <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    7fee:	28 2e       	mov	r2, r24
+    7fcc:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    7ff0:	80 e0       	ldi	r24, 0x00	; 0
-    7ff2:	e7 df       	rcall	.-50     	; 0x7fc2 <watchdogConfig>
+    7fce:	80 e0       	ldi	r24, 0x00	; 0
+    7fd0:	e7 df       	rcall	.-50     	; 0x7fa0 <watchdogConfig>
   __asm__ __volatile__ (
-    7ff4:	ee 27       	eor	r30, r30
-    7ff6:	ff 27       	eor	r31, r31
-    7ff8:	09 94       	ijmp
+    7fd2:	ee 27       	eor	r30, r30
+    7fd4:	ff 27       	eor	r31, r31
+    7fd6:	09 94       	ijmp

+ 180 - 198
optiboot/bootloaders/optiboot/optiboot_diecimila.lst

@@ -3,27 +3,27 @@ optiboot_atmega168.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f8  00003e00  00003e00  00000074  2**1
+  0 .text         000001d6  00003e00  00003e00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000026c  2**0
+  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000026e  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000296  2**0
+  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003e0  00000000  00000000  0000030a  2**0
+  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001f1  00000000  00000000  000006ea  2**0
+  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000433  00000000  00000000  000008db  2**0
+  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000d10  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000172  00000000  00000000  00000d90  2**0
+  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d7  00000000  00000000  00000f02  2**0
+  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011d9  2**0
+ 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -51,7 +51,7 @@ int main(void) {
     3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
       appStart(ch);
     3e0c:	89 2f       	mov	r24, r25
-    3e0e:	ee d0       	rcall	.+476    	; 0x3fec <appStart>
+    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -81,7 +81,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	c7 d0       	rcall	.+398    	; 0x3fc0 <watchdogConfig>
+    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
 
 #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
   /* Set LED pin as output */
@@ -131,68 +131,68 @@ void watchdogReset() {
   } while (--count);
     3e4e:	81 50       	subi	r24, 0x01	; 1
     3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	aa 24       	eor	r10, r10
-    3e54:	bb 24       	eor	r11, r11
+    3e52:	ee 24       	eor	r14, r14
+    3e54:	ff 24       	eor	r15, r15
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	33 e0       	ldi	r19, 0x03	; 3
-    3e58:	83 2e       	mov	r8, r19
+    3e56:	b3 e0       	ldi	r27, 0x03	; 3
+    3e58:	ab 2e       	mov	r10, r27
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	77 24       	eor	r7, r7
-    3e5c:	73 94       	inc	r7
+    3e5a:	bb 24       	eor	r11, r11
+    3e5c:	b3 94       	inc	r11
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	25 e0       	ldi	r18, 0x05	; 5
-    3e60:	92 2e       	mov	r9, r18
+    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
+    3e60:	da 2e       	mov	r13, r26
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3e62:	91 e1       	ldi	r25, 0x11	; 17
-    3e64:	c9 2e       	mov	r12, r25
+    3e62:	f1 e1       	ldi	r31, 0x11	; 17
+    3e64:	cf 2e       	mov	r12, r31
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e66:	a0 d0       	rcall	.+320    	; 0x3fa8 <getch>
+    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e68:	81 34       	cpi	r24, 0x41	; 65
     3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
       unsigned char which = getch();
-    3e6c:	9d d0       	rcall	.+314    	; 0x3fa8 <getch>
-    3e6e:	18 2f       	mov	r17, r24
+    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
+    3e6e:	08 2f       	mov	r16, r24
       verifySpace();
-    3e70:	ad d0       	rcall	.+346    	; 0x3fcc <verifySpace>
+    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
       if (which == 0x82) {
-    3e72:	12 38       	cpi	r17, 0x82	; 130
+    3e72:	02 38       	cpi	r16, 0x82	; 130
     3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(optiboot_version & 0xFF);
-    3e76:	81 e0       	ldi	r24, 0x01	; 1
+    3e76:	82 e0       	ldi	r24, 0x02	; 2
     3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
       } else if (which == 0x81) {
-    3e7a:	11 38       	cpi	r17, 0x81	; 129
+    3e7a:	01 38       	cpi	r16, 0x81	; 129
     3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	82 c0       	rjmp	.+260    	; 0x3f84 <main+0x184>
+    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
@@ -200,8 +200,8 @@ void watchdogReset() {
 	 */
 	putch(0x03);
     3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	8a d0       	rcall	.+276    	; 0x3f98 <putch>
-    3e84:	86 c0       	rjmp	.+268    	; 0x3f92 <main+0x192>
+    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
+    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
       }
     }
     else if(ch == STK_SET_DEVICE) {
@@ -218,8 +218,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	a3 d0       	rcall	.+326    	; 0x3fdc <getNch>
-    3e96:	7d c0       	rjmp	.+250    	; 0x3f92 <main+0x192>
+    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
+    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e98:	85 35       	cpi	r24, 0x55	; 85
@@ -227,11 +227,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e9c:	85 d0       	rcall	.+266    	; 0x3fa8 <getch>
+    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e9e:	e8 2e       	mov	r14, r24
     3ea0:	ff 24       	eor	r15, r15
-    3ea2:	82 d0       	rcall	.+260    	; 0x3fa8 <getch>
+    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
     3ea4:	08 2f       	mov	r16, r24
     3ea6:	10 e0       	ldi	r17, 0x00	; 0
     3ea8:	10 2f       	mov	r17, r16
@@ -247,9 +247,9 @@ void watchdogReset() {
     3eb2:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eb4:	8b d0       	rcall	.+278    	; 0x3fcc <verifySpace>
-    3eb6:	58 01       	movw	r10, r16
-    3eb8:	6c c0       	rjmp	.+216    	; 0x3f92 <main+0x192>
+    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
+    3eb6:	78 01       	movw	r14, r16
+    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_UNIVERSAL) {
     3eba:	86 35       	cpi	r24, 0x56	; 86
@@ -257,7 +257,7 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	8d d0       	rcall	.+282    	; 0x3fdc <getNch>
+    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
       putch(0x00);
     3ec2:	80 e0       	ldi	r24, 0x00	; 0
     3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
@@ -266,339 +266,321 @@ void watchdogReset() {
     else if(ch == STK_PROG_PAGE) {
     3ec6:	84 36       	cpi	r24, 0x64	; 100
     3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	41 c0       	rjmp	.+130    	; 0x3f4e <main+0x14e>
+    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
-    3ecc:	6d d0       	rcall	.+218    	; 0x3fa8 <getch>
-    3ece:	90 e0       	ldi	r25, 0x00	; 0
+      GETLENGTH(length);
+    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
+    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
     3ed0:	18 2f       	mov	r17, r24
-    3ed2:	00 27       	eor	r16, r16
-      length |= getch();
-    3ed4:	69 d0       	rcall	.+210    	; 0x3fa8 <getch>
-    3ed6:	90 e0       	ldi	r25, 0x00	; 0
-    3ed8:	08 2b       	or	r16, r24
-    3eda:	19 2b       	or	r17, r25
       savelength = length;
       desttype = getch();
-    3edc:	65 d0       	rcall	.+202    	; 0x3fa8 <getch>
-    3ede:	d8 2e       	mov	r13, r24
-    3ee0:	e8 01       	movw	r28, r16
-    3ee2:	e1 2c       	mov	r14, r1
-    3ee4:	f1 e0       	ldi	r31, 0x01	; 1
-    3ee6:	ff 2e       	mov	r15, r31
+    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
+    3ed4:	08 2f       	mov	r16, r24
+    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
 
       // read a page worth of contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee8:	5f d0       	rcall	.+190    	; 0x3fa8 <getch>
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	81 93       	st	Z+, r24
-    3eee:	7f 01       	movw	r14, r30
+    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
+    3edc:	89 93       	st	Y+, r24
       while (--length);
-    3ef0:	21 97       	sbiw	r28, 0x01	; 1
-    3ef2:	d1 f7       	brne	.-12     	; 0x3ee8 <main+0xe8>
+    3ede:	1c 17       	cp	r17, r28
+    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
 
       // Read command terminator, start reply
       verifySpace();
-    3ef4:	6b d0       	rcall	.+214    	; 0x3fcc <verifySpace>
+    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
-    3ef6:	f5 e4       	ldi	r31, 0x45	; 69
-    3ef8:	df 16       	cp	r13, r31
-    3efa:	09 f4       	brne	.+2      	; 0x3efe <main+0xfe>
-    3efc:	ff cf       	rjmp	.-2      	; 0x3efc <main+0xfc>
+    3ee4:	05 34       	cpi	r16, 0x45	; 69
+    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
+    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3efe:	f5 01       	movw	r30, r10
-    3f00:	87 be       	out	0x37, r8	; 55
-    3f02:	e8 95       	spm
+    3eea:	f7 01       	movw	r30, r14
+    3eec:	a7 be       	out	0x37, r10	; 55
+    3eee:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f04:	07 b6       	in	r0, 0x37	; 55
-    3f06:	00 fc       	sbrc	r0, 0
-    3f08:	fd cf       	rjmp	.-6      	; 0x3f04 <main+0x104>
-    3f0a:	b5 01       	movw	r22, r10
-    3f0c:	a8 01       	movw	r20, r16
-    3f0e:	a0 e0       	ldi	r26, 0x00	; 0
-    3f10:	b1 e0       	ldi	r27, 0x01	; 1
+    3ef0:	07 b6       	in	r0, 0x37	; 55
+    3ef2:	00 fc       	sbrc	r0, 0
+    3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
+    3ef6:	a7 01       	movw	r20, r14
+    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
+    3efa:	b1 e0       	ldi	r27, 0x01	; 1
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
-    3f12:	2c 91       	ld	r18, X
-    3f14:	30 e0       	ldi	r19, 0x00	; 0
+    3efc:	2c 91       	ld	r18, X
+    3efe:	30 e0       	ldi	r19, 0x00	; 0
 		a |= (*bufPtr++) << 8;
-    3f16:	11 96       	adiw	r26, 0x01	; 1
-    3f18:	8c 91       	ld	r24, X
-    3f1a:	11 97       	sbiw	r26, 0x01	; 1
-    3f1c:	90 e0       	ldi	r25, 0x00	; 0
-    3f1e:	98 2f       	mov	r25, r24
-    3f20:	88 27       	eor	r24, r24
-    3f22:	82 2b       	or	r24, r18
-    3f24:	93 2b       	or	r25, r19
+    3f00:	11 96       	adiw	r26, 0x01	; 1
+    3f02:	8c 91       	ld	r24, X
+    3f04:	11 97       	sbiw	r26, 0x01	; 1
+    3f06:	90 e0       	ldi	r25, 0x00	; 0
+    3f08:	98 2f       	mov	r25, r24
+    3f0a:	88 27       	eor	r24, r24
+    3f0c:	82 2b       	or	r24, r18
+    3f0e:	93 2b       	or	r25, r19
 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
 
 /* main program starts here */
 int main(void) {
-    3f26:	12 96       	adiw	r26, 0x02	; 2
+    3f10:	12 96       	adiw	r26, 0x02	; 2
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f28:	fb 01       	movw	r30, r22
-    3f2a:	0c 01       	movw	r0, r24
-    3f2c:	77 be       	out	0x37, r7	; 55
-    3f2e:	e8 95       	spm
-    3f30:	11 24       	eor	r1, r1
+    3f12:	fa 01       	movw	r30, r20
+    3f14:	0c 01       	movw	r0, r24
+    3f16:	b7 be       	out	0x37, r11	; 55
+    3f18:	e8 95       	spm
+    3f1a:	11 24       	eor	r1, r1
 		addrPtr += 2;
-    3f32:	6e 5f       	subi	r22, 0xFE	; 254
-    3f34:	7f 4f       	sbci	r23, 0xFF	; 255
+    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
+    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    3f36:	42 50       	subi	r20, 0x02	; 2
-    3f38:	50 40       	sbci	r21, 0x00	; 0
-    3f3a:	59 f7       	brne	.-42     	; 0x3f12 <main+0x112>
+    3f20:	1a 17       	cp	r17, r26
+    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3f3c:	f5 01       	movw	r30, r10
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
+    3f24:	f7 01       	movw	r30, r14
+    3f26:	d7 be       	out	0x37, r13	; 55
+    3f28:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f42:	07 b6       	in	r0, 0x37	; 55
-    3f44:	00 fc       	sbrc	r0, 0
-    3f46:	fd cf       	rjmp	.-6      	; 0x3f42 <main+0x142>
+    3f2a:	07 b6       	in	r0, 0x37	; 55
+    3f2c:	00 fc       	sbrc	r0, 0
+    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3f48:	c7 be       	out	0x37, r12	; 55
-    3f4a:	e8 95       	spm
-    3f4c:	22 c0       	rjmp	.+68     	; 0x3f92 <main+0x192>
+    3f30:	c7 be       	out	0x37, r12	; 55
+    3f32:	e8 95       	spm
+    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f4e:	84 37       	cpi	r24, 0x74	; 116
-    3f50:	91 f4       	brne	.+36     	; 0x3f76 <main+0x176>
+    3f36:	84 37       	cpi	r24, 0x74	; 116
+    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
-    3f52:	2a d0       	rcall	.+84     	; 0x3fa8 <getch>
-    3f54:	90 e0       	ldi	r25, 0x00	; 0
-    3f56:	d8 2f       	mov	r29, r24
-    3f58:	cc 27       	eor	r28, r28
-      length |= getch();
-    3f5a:	26 d0       	rcall	.+76     	; 0x3fa8 <getch>
-    3f5c:	90 e0       	ldi	r25, 0x00	; 0
-    3f5e:	c8 2b       	or	r28, r24
-    3f60:	d9 2b       	or	r29, r25
+      GETLENGTH(length);
+    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
+    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
+    3f3e:	08 2f       	mov	r16, r24
+
       desttype = getch();
-    3f62:	22 d0       	rcall	.+68     	; 0x3fa8 <getch>
+    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
 
       verifySpace();
-    3f64:	33 d0       	rcall	.+102    	; 0x3fcc <verifySpace>
-    3f66:	85 01       	movw	r16, r10
+    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
+    3f44:	e7 01       	movw	r28, r14
 	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
 	    // read a Flash byte and increment the address
 	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
 	    putch(ch);
-    3f68:	f8 01       	movw	r30, r16
-    3f6a:	85 91       	lpm	r24, Z+
-    3f6c:	8f 01       	movw	r16, r30
-    3f6e:	14 d0       	rcall	.+40     	; 0x3f98 <putch>
+    3f46:	fe 01       	movw	r30, r28
+    3f48:	85 91       	lpm	r24, Z+
+    3f4a:	ef 01       	movw	r28, r30
+    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
 	} while (--length);
-    3f70:	21 97       	sbiw	r28, 0x01	; 1
-    3f72:	d1 f7       	brne	.-12     	; 0x3f68 <main+0x168>
-    3f74:	0e c0       	rjmp	.+28     	; 0x3f92 <main+0x192>
+    3f4e:	01 50       	subi	r16, 0x01	; 1
+    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
+    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
 	  
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f76:	85 37       	cpi	r24, 0x75	; 117
-    3f78:	39 f4       	brne	.+14     	; 0x3f88 <main+0x188>
+    3f54:	85 37       	cpi	r24, 0x75	; 117
+    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f7a:	28 d0       	rcall	.+80     	; 0x3fcc <verifySpace>
+    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
       putch(SIGNATURE_0);
-    3f7c:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7e:	0c d0       	rcall	.+24     	; 0x3f98 <putch>
+    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
+    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
       putch(SIGNATURE_1);
-    3f80:	84 e9       	ldi	r24, 0x94	; 148
-    3f82:	0a d0       	rcall	.+20     	; 0x3f98 <putch>
+    3f5e:	84 e9       	ldi	r24, 0x94	; 148
+    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
       putch(SIGNATURE_2);
-    3f84:	86 e0       	ldi	r24, 0x06	; 6
-    3f86:	7d cf       	rjmp	.-262    	; 0x3e82 <main+0x82>
+    3f62:	86 e0       	ldi	r24, 0x06	; 6
+    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f88:	81 35       	cpi	r24, 0x51	; 81
-    3f8a:	11 f4       	brne	.+4      	; 0x3f90 <main+0x190>
+    3f66:	81 35       	cpi	r24, 0x51	; 81
+    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8c:	88 e0       	ldi	r24, 0x08	; 8
-    3f8e:	18 d0       	rcall	.+48     	; 0x3fc0 <watchdogConfig>
+    3f6a:	88 e0       	ldi	r24, 0x08	; 8
+    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f90:	1d d0       	rcall	.+58     	; 0x3fcc <verifySpace>
+    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
     }
     putch(STK_OK);
-    3f92:	80 e1       	ldi	r24, 0x10	; 16
-    3f94:	01 d0       	rcall	.+2      	; 0x3f98 <putch>
-    3f96:	67 cf       	rjmp	.-306    	; 0x3e66 <main+0x66>
+    3f70:	80 e1       	ldi	r24, 0x10	; 16
+    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
+    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
 
-00003f98 <putch>:
+00003f76 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f98:	98 2f       	mov	r25, r24
+    3f76:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    3f9a:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9e:	85 ff       	sbrs	r24, 5
-    3fa0:	fc cf       	rjmp	.-8      	; 0x3f9a <putch+0x2>
+    3f78:	80 91 c0 00 	lds	r24, 0x00C0
+    3f7c:	85 ff       	sbrs	r24, 5
+    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
   UART_UDR = ch;
-    3fa2:	90 93 c6 00 	sts	0x00C6, r25
+    3f80:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa6:	08 95       	ret
+    3f84:	08 95       	ret
 
-00003fa8 <getch>:
+00003f86 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    3fa8:	80 91 c0 00 	lds	r24, 0x00C0
-    3fac:	87 ff       	sbrs	r24, 7
-    3fae:	fc cf       	rjmp	.-8      	; 0x3fa8 <getch>
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	87 ff       	sbrs	r24, 7
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb4:	84 fd       	sbrc	r24, 4
-    3fb6:	01 c0       	rjmp	.+2      	; 0x3fba <getch+0x12>
+    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
+    3f92:	84 fd       	sbrc	r24, 4
+    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb8:	a8 95       	wdr
+    3f96:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
   ch = UART_UDR;
-    3fba:	80 91 c6 00 	lds	r24, 0x00C6
+    3f98:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbe:	08 95       	ret
+    3f9c:	08 95       	ret
 
-00003fc0 <watchdogConfig>:
+00003f9e <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fc0:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc2:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc4:	98 e1       	ldi	r25, 0x18	; 24
-    3fc6:	90 83       	st	Z, r25
+    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
+    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
+    3fa2:	98 e1       	ldi	r25, 0x18	; 24
+    3fa4:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc8:	80 83       	st	Z, r24
+    3fa6:	80 83       	st	Z, r24
 }
-    3fca:	08 95       	ret
+    3fa8:	08 95       	ret
 
-00003fcc <verifySpace>:
+00003faa <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fcc:	ed df       	rcall	.-38     	; 0x3fa8 <getch>
-    3fce:	80 32       	cpi	r24, 0x20	; 32
-    3fd0:	19 f0       	breq	.+6      	; 0x3fd8 <verifySpace+0xc>
+    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
+    3fac:	80 32       	cpi	r24, 0x20	; 32
+    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd2:	88 e0       	ldi	r24, 0x08	; 8
-    3fd4:	f5 df       	rcall	.-22     	; 0x3fc0 <watchdogConfig>
-    3fd6:	ff cf       	rjmp	.-2      	; 0x3fd6 <verifySpace+0xa>
+    3fb0:	88 e0       	ldi	r24, 0x08	; 8
+    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
+    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd8:	84 e1       	ldi	r24, 0x14	; 20
+    3fb6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fda:	de cf       	rjmp	.-68     	; 0x3f98 <putch>
+    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
 
-00003fdc <getNch>:
+00003fba <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fdc:	1f 93       	push	r17
-    3fde:	18 2f       	mov	r17, r24
+    3fba:	1f 93       	push	r17
+    3fbc:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fe0:	e3 df       	rcall	.-58     	; 0x3fa8 <getch>
-    3fe2:	11 50       	subi	r17, 0x01	; 1
-    3fe4:	e9 f7       	brne	.-6      	; 0x3fe0 <getNch+0x4>
+    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
+    3fc0:	11 50       	subi	r17, 0x01	; 1
+    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
   verifySpace();
-    3fe6:	f2 df       	rcall	.-28     	; 0x3fcc <verifySpace>
+    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
 }
-    3fe8:	1f 91       	pop	r17
-    3fea:	08 95       	ret
+    3fc6:	1f 91       	pop	r17
+    3fc8:	08 95       	ret
 
-00003fec <appStart>:
+00003fca <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fec:	28 2e       	mov	r2, r24
+    3fca:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    3fee:	80 e0       	ldi	r24, 0x00	; 0
-    3ff0:	e7 df       	rcall	.-50     	; 0x3fc0 <watchdogConfig>
+    3fcc:	80 e0       	ldi	r24, 0x00	; 0
+    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
   __asm__ __volatile__ (
-    3ff2:	ee 27       	eor	r30, r30
-    3ff4:	ff 27       	eor	r31, r31
-    3ff6:	09 94       	ijmp
+    3fd0:	ee 27       	eor	r30, r30
+    3fd2:	ff 27       	eor	r31, r31
+    3fd4:	09 94       	ijmp

+ 28 - 30
optiboot/bootloaders/optiboot/optiboot_lilypad.hex

@@ -1,35 +1,33 @@
-:103E0000112494B714BE892F8D7011F0892FEED034
+:103E0000112494B714BE892F8D7011F0892FDDD045
 :103E100085E08093810082E08093C00088E18093F8
 :103E2000C10086E08093C20088E08093C4008EE0E9
-:103E3000C7D0259A86E028E13EEF91E030938500D7
+:103E3000B6D0259A86E028E13EEF91E030938500E8
 :103E40002093840096BBB09BFECF1D9AA89581500D
-:103E5000A9F7AA24BB2433E0832E7724739425E0AA
-:103E6000922E91E1C92EA0D0813469F49DD0182FF3
-:103E7000ADD0123811F481E004C0113809F482C0C9
-:103E800083E08AD086C0823411F484E103C0853493
-:103E900019F485E0A3D07DC0853579F485D0E82E6E
-:103EA000FF2482D0082F10E0102F00270E291F2991
-:103EB000000F111F8BD058016CC0863521F484E0AF
-:103EC0008DD080E0DECF843609F041C06DD090E027
-:103ED000182F002769D090E0082B192B65D0D82E19
-:103EE000E801E12CF1E0FF2E5FD0F70181937F0123
-:103EF0002197D1F76BD0F5E4DF1609F4FFCFF50178
-:103F000087BEE89507B600FCFDCFB501A801A0E08B
-:103F1000B1E02C9130E011968C91119790E0982FA0
-:103F20008827822B932B1296FB010C0177BEE89514
-:103F300011246E5F7F4F4250504059F7F50197BEF4
-:103F4000E89507B600FCFDCFC7BEE89522C08437D0
-:103F500091F42AD090E0D82FCC2726D090E0C82B1F
-:103F6000D92B22D033D08501F80185918F0114D04F
-:103F70002197D1F70EC0853739F428D08EE10CD0C7
-:103F800084E90AD086E07DCF813511F488E018D02D
-:103F90001DD080E101D067CF982F8091C00085FFB0
-:103FA000FCCF9093C60008958091C00087FFFCCF9E
-:103FB0008091C00084FD01C0A8958091C60008953D
-:103FC000E0E6F0E098E1908380830895EDDF8032B1
-:103FD00019F088E0F5DFFFCF84E1DECF1F93182FC3
-:103FE000E3DF1150E9F7F2DF1F910895282E80E0FA
-:083FF000E7DFEE27FF2709942B
-:023FFE000106BA
+:103E5000A9F7EE24FF24B3E0AB2EBB24B394A5E076
+:103E6000DA2EF1E1CF2E8FD0813469F48CD0082F77
+:103E70009CD0023811F482E004C0013809F471C00A
+:103E800083E079D075C0823411F484E103C08534B5
+:103E900019F485E092D06CC0853579F474D0E82EA1
+:103EA000FF2471D0082F10E0102F00270E291F29A2
+:103EB000000F111F7AD078015BC0863521F484E0B1
+:103EC0007CD080E0DECF843609F035C05CD05BD09A
+:103ED000182F59D0082FC0E0D1E055D089931C1776
+:103EE000E1F763D0053409F4FFCFF701A7BEE895E9
+:103EF00007B600FCFDCFA701A0E0B1E02C9130E0B7
+:103F000011968C91119790E0982F8827822B932BF4
+:103F10001296FA010C01B7BEE89511244E5F5F4F6F
+:103F20001A1761F7F701D7BEE89507B600FCFDCF79
+:103F3000C7BEE8951DC0843769F425D024D0082F6A
+:103F400022D033D0E701FE018591EF0114D001505A
+:103F5000D1F70EC0853739F428D08EE10CD084E932
+:103F60000AD086E08ECF813511F488E018D01DD0BC
+:103F700080E101D078CF982F8091C00085FFFCCFE1
+:103F80009093C60008958091C00087FFFCCF809178
+:103F9000C00084FD01C0A8958091C6000895E0E6A8
+:103FA000F0E098E1908380830895EDDF803219F08E
+:103FB00088E0F5DFFFCF84E1DECF1F93182FE3DF2A
+:103FC0001150E9F7F2DF1F910895282E80E0E7DF16
+:063FD000EE27FF27099413
+:023FFE000206B9
 :0400000300003E00BB
 :00000001FF

+ 180 - 198
optiboot/bootloaders/optiboot/optiboot_lilypad.lst

@@ -3,27 +3,27 @@ optiboot_atmega168.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f8  00003e00  00003e00  00000074  2**1
+  0 .text         000001d6  00003e00  00003e00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000026c  2**0
+  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000026e  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000296  2**0
+  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003e0  00000000  00000000  0000030a  2**0
+  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001f1  00000000  00000000  000006ea  2**0
+  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000433  00000000  00000000  000008db  2**0
+  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000d10  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000172  00000000  00000000  00000d90  2**0
+  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d7  00000000  00000000  00000f02  2**0
+  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011d9  2**0
+ 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -51,7 +51,7 @@ int main(void) {
     3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
       appStart(ch);
     3e0c:	89 2f       	mov	r24, r25
-    3e0e:	ee d0       	rcall	.+476    	; 0x3fec <appStart>
+    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -81,7 +81,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	c7 d0       	rcall	.+398    	; 0x3fc0 <watchdogConfig>
+    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
 
 #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
   /* Set LED pin as output */
@@ -131,68 +131,68 @@ void watchdogReset() {
   } while (--count);
     3e4e:	81 50       	subi	r24, 0x01	; 1
     3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	aa 24       	eor	r10, r10
-    3e54:	bb 24       	eor	r11, r11
+    3e52:	ee 24       	eor	r14, r14
+    3e54:	ff 24       	eor	r15, r15
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	33 e0       	ldi	r19, 0x03	; 3
-    3e58:	83 2e       	mov	r8, r19
+    3e56:	b3 e0       	ldi	r27, 0x03	; 3
+    3e58:	ab 2e       	mov	r10, r27
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	77 24       	eor	r7, r7
-    3e5c:	73 94       	inc	r7
+    3e5a:	bb 24       	eor	r11, r11
+    3e5c:	b3 94       	inc	r11
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	25 e0       	ldi	r18, 0x05	; 5
-    3e60:	92 2e       	mov	r9, r18
+    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
+    3e60:	da 2e       	mov	r13, r26
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3e62:	91 e1       	ldi	r25, 0x11	; 17
-    3e64:	c9 2e       	mov	r12, r25
+    3e62:	f1 e1       	ldi	r31, 0x11	; 17
+    3e64:	cf 2e       	mov	r12, r31
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e66:	a0 d0       	rcall	.+320    	; 0x3fa8 <getch>
+    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e68:	81 34       	cpi	r24, 0x41	; 65
     3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
       unsigned char which = getch();
-    3e6c:	9d d0       	rcall	.+314    	; 0x3fa8 <getch>
-    3e6e:	18 2f       	mov	r17, r24
+    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
+    3e6e:	08 2f       	mov	r16, r24
       verifySpace();
-    3e70:	ad d0       	rcall	.+346    	; 0x3fcc <verifySpace>
+    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
       if (which == 0x82) {
-    3e72:	12 38       	cpi	r17, 0x82	; 130
+    3e72:	02 38       	cpi	r16, 0x82	; 130
     3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(optiboot_version & 0xFF);
-    3e76:	81 e0       	ldi	r24, 0x01	; 1
+    3e76:	82 e0       	ldi	r24, 0x02	; 2
     3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
       } else if (which == 0x81) {
-    3e7a:	11 38       	cpi	r17, 0x81	; 129
+    3e7a:	01 38       	cpi	r16, 0x81	; 129
     3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	82 c0       	rjmp	.+260    	; 0x3f84 <main+0x184>
+    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
@@ -200,8 +200,8 @@ void watchdogReset() {
 	 */
 	putch(0x03);
     3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	8a d0       	rcall	.+276    	; 0x3f98 <putch>
-    3e84:	86 c0       	rjmp	.+268    	; 0x3f92 <main+0x192>
+    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
+    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
       }
     }
     else if(ch == STK_SET_DEVICE) {
@@ -218,8 +218,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	a3 d0       	rcall	.+326    	; 0x3fdc <getNch>
-    3e96:	7d c0       	rjmp	.+250    	; 0x3f92 <main+0x192>
+    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
+    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e98:	85 35       	cpi	r24, 0x55	; 85
@@ -227,11 +227,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e9c:	85 d0       	rcall	.+266    	; 0x3fa8 <getch>
+    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e9e:	e8 2e       	mov	r14, r24
     3ea0:	ff 24       	eor	r15, r15
-    3ea2:	82 d0       	rcall	.+260    	; 0x3fa8 <getch>
+    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
     3ea4:	08 2f       	mov	r16, r24
     3ea6:	10 e0       	ldi	r17, 0x00	; 0
     3ea8:	10 2f       	mov	r17, r16
@@ -247,9 +247,9 @@ void watchdogReset() {
     3eb2:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eb4:	8b d0       	rcall	.+278    	; 0x3fcc <verifySpace>
-    3eb6:	58 01       	movw	r10, r16
-    3eb8:	6c c0       	rjmp	.+216    	; 0x3f92 <main+0x192>
+    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
+    3eb6:	78 01       	movw	r14, r16
+    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_UNIVERSAL) {
     3eba:	86 35       	cpi	r24, 0x56	; 86
@@ -257,7 +257,7 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	8d d0       	rcall	.+282    	; 0x3fdc <getNch>
+    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
       putch(0x00);
     3ec2:	80 e0       	ldi	r24, 0x00	; 0
     3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
@@ -266,339 +266,321 @@ void watchdogReset() {
     else if(ch == STK_PROG_PAGE) {
     3ec6:	84 36       	cpi	r24, 0x64	; 100
     3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	41 c0       	rjmp	.+130    	; 0x3f4e <main+0x14e>
+    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
-    3ecc:	6d d0       	rcall	.+218    	; 0x3fa8 <getch>
-    3ece:	90 e0       	ldi	r25, 0x00	; 0
+      GETLENGTH(length);
+    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
+    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
     3ed0:	18 2f       	mov	r17, r24
-    3ed2:	00 27       	eor	r16, r16
-      length |= getch();
-    3ed4:	69 d0       	rcall	.+210    	; 0x3fa8 <getch>
-    3ed6:	90 e0       	ldi	r25, 0x00	; 0
-    3ed8:	08 2b       	or	r16, r24
-    3eda:	19 2b       	or	r17, r25
       savelength = length;
       desttype = getch();
-    3edc:	65 d0       	rcall	.+202    	; 0x3fa8 <getch>
-    3ede:	d8 2e       	mov	r13, r24
-    3ee0:	e8 01       	movw	r28, r16
-    3ee2:	e1 2c       	mov	r14, r1
-    3ee4:	f1 e0       	ldi	r31, 0x01	; 1
-    3ee6:	ff 2e       	mov	r15, r31
+    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
+    3ed4:	08 2f       	mov	r16, r24
+    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
 
       // read a page worth of contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee8:	5f d0       	rcall	.+190    	; 0x3fa8 <getch>
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	81 93       	st	Z+, r24
-    3eee:	7f 01       	movw	r14, r30
+    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
+    3edc:	89 93       	st	Y+, r24
       while (--length);
-    3ef0:	21 97       	sbiw	r28, 0x01	; 1
-    3ef2:	d1 f7       	brne	.-12     	; 0x3ee8 <main+0xe8>
+    3ede:	1c 17       	cp	r17, r28
+    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
 
       // Read command terminator, start reply
       verifySpace();
-    3ef4:	6b d0       	rcall	.+214    	; 0x3fcc <verifySpace>
+    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
-    3ef6:	f5 e4       	ldi	r31, 0x45	; 69
-    3ef8:	df 16       	cp	r13, r31
-    3efa:	09 f4       	brne	.+2      	; 0x3efe <main+0xfe>
-    3efc:	ff cf       	rjmp	.-2      	; 0x3efc <main+0xfc>
+    3ee4:	05 34       	cpi	r16, 0x45	; 69
+    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
+    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3efe:	f5 01       	movw	r30, r10
-    3f00:	87 be       	out	0x37, r8	; 55
-    3f02:	e8 95       	spm
+    3eea:	f7 01       	movw	r30, r14
+    3eec:	a7 be       	out	0x37, r10	; 55
+    3eee:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f04:	07 b6       	in	r0, 0x37	; 55
-    3f06:	00 fc       	sbrc	r0, 0
-    3f08:	fd cf       	rjmp	.-6      	; 0x3f04 <main+0x104>
-    3f0a:	b5 01       	movw	r22, r10
-    3f0c:	a8 01       	movw	r20, r16
-    3f0e:	a0 e0       	ldi	r26, 0x00	; 0
-    3f10:	b1 e0       	ldi	r27, 0x01	; 1
+    3ef0:	07 b6       	in	r0, 0x37	; 55
+    3ef2:	00 fc       	sbrc	r0, 0
+    3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
+    3ef6:	a7 01       	movw	r20, r14
+    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
+    3efa:	b1 e0       	ldi	r27, 0x01	; 1
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
-    3f12:	2c 91       	ld	r18, X
-    3f14:	30 e0       	ldi	r19, 0x00	; 0
+    3efc:	2c 91       	ld	r18, X
+    3efe:	30 e0       	ldi	r19, 0x00	; 0
 		a |= (*bufPtr++) << 8;
-    3f16:	11 96       	adiw	r26, 0x01	; 1
-    3f18:	8c 91       	ld	r24, X
-    3f1a:	11 97       	sbiw	r26, 0x01	; 1
-    3f1c:	90 e0       	ldi	r25, 0x00	; 0
-    3f1e:	98 2f       	mov	r25, r24
-    3f20:	88 27       	eor	r24, r24
-    3f22:	82 2b       	or	r24, r18
-    3f24:	93 2b       	or	r25, r19
+    3f00:	11 96       	adiw	r26, 0x01	; 1
+    3f02:	8c 91       	ld	r24, X
+    3f04:	11 97       	sbiw	r26, 0x01	; 1
+    3f06:	90 e0       	ldi	r25, 0x00	; 0
+    3f08:	98 2f       	mov	r25, r24
+    3f0a:	88 27       	eor	r24, r24
+    3f0c:	82 2b       	or	r24, r18
+    3f0e:	93 2b       	or	r25, r19
 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
 
 /* main program starts here */
 int main(void) {
-    3f26:	12 96       	adiw	r26, 0x02	; 2
+    3f10:	12 96       	adiw	r26, 0x02	; 2
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f28:	fb 01       	movw	r30, r22
-    3f2a:	0c 01       	movw	r0, r24
-    3f2c:	77 be       	out	0x37, r7	; 55
-    3f2e:	e8 95       	spm
-    3f30:	11 24       	eor	r1, r1
+    3f12:	fa 01       	movw	r30, r20
+    3f14:	0c 01       	movw	r0, r24
+    3f16:	b7 be       	out	0x37, r11	; 55
+    3f18:	e8 95       	spm
+    3f1a:	11 24       	eor	r1, r1
 		addrPtr += 2;
-    3f32:	6e 5f       	subi	r22, 0xFE	; 254
-    3f34:	7f 4f       	sbci	r23, 0xFF	; 255
+    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
+    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    3f36:	42 50       	subi	r20, 0x02	; 2
-    3f38:	50 40       	sbci	r21, 0x00	; 0
-    3f3a:	59 f7       	brne	.-42     	; 0x3f12 <main+0x112>
+    3f20:	1a 17       	cp	r17, r26
+    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3f3c:	f5 01       	movw	r30, r10
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
+    3f24:	f7 01       	movw	r30, r14
+    3f26:	d7 be       	out	0x37, r13	; 55
+    3f28:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f42:	07 b6       	in	r0, 0x37	; 55
-    3f44:	00 fc       	sbrc	r0, 0
-    3f46:	fd cf       	rjmp	.-6      	; 0x3f42 <main+0x142>
+    3f2a:	07 b6       	in	r0, 0x37	; 55
+    3f2c:	00 fc       	sbrc	r0, 0
+    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3f48:	c7 be       	out	0x37, r12	; 55
-    3f4a:	e8 95       	spm
-    3f4c:	22 c0       	rjmp	.+68     	; 0x3f92 <main+0x192>
+    3f30:	c7 be       	out	0x37, r12	; 55
+    3f32:	e8 95       	spm
+    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f4e:	84 37       	cpi	r24, 0x74	; 116
-    3f50:	91 f4       	brne	.+36     	; 0x3f76 <main+0x176>
+    3f36:	84 37       	cpi	r24, 0x74	; 116
+    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
-    3f52:	2a d0       	rcall	.+84     	; 0x3fa8 <getch>
-    3f54:	90 e0       	ldi	r25, 0x00	; 0
-    3f56:	d8 2f       	mov	r29, r24
-    3f58:	cc 27       	eor	r28, r28
-      length |= getch();
-    3f5a:	26 d0       	rcall	.+76     	; 0x3fa8 <getch>
-    3f5c:	90 e0       	ldi	r25, 0x00	; 0
-    3f5e:	c8 2b       	or	r28, r24
-    3f60:	d9 2b       	or	r29, r25
+      GETLENGTH(length);
+    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
+    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
+    3f3e:	08 2f       	mov	r16, r24
+
       desttype = getch();
-    3f62:	22 d0       	rcall	.+68     	; 0x3fa8 <getch>
+    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
 
       verifySpace();
-    3f64:	33 d0       	rcall	.+102    	; 0x3fcc <verifySpace>
-    3f66:	85 01       	movw	r16, r10
+    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
+    3f44:	e7 01       	movw	r28, r14
 	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
 	    // read a Flash byte and increment the address
 	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
 	    putch(ch);
-    3f68:	f8 01       	movw	r30, r16
-    3f6a:	85 91       	lpm	r24, Z+
-    3f6c:	8f 01       	movw	r16, r30
-    3f6e:	14 d0       	rcall	.+40     	; 0x3f98 <putch>
+    3f46:	fe 01       	movw	r30, r28
+    3f48:	85 91       	lpm	r24, Z+
+    3f4a:	ef 01       	movw	r28, r30
+    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
 	} while (--length);
-    3f70:	21 97       	sbiw	r28, 0x01	; 1
-    3f72:	d1 f7       	brne	.-12     	; 0x3f68 <main+0x168>
-    3f74:	0e c0       	rjmp	.+28     	; 0x3f92 <main+0x192>
+    3f4e:	01 50       	subi	r16, 0x01	; 1
+    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
+    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
 	  
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f76:	85 37       	cpi	r24, 0x75	; 117
-    3f78:	39 f4       	brne	.+14     	; 0x3f88 <main+0x188>
+    3f54:	85 37       	cpi	r24, 0x75	; 117
+    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f7a:	28 d0       	rcall	.+80     	; 0x3fcc <verifySpace>
+    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
       putch(SIGNATURE_0);
-    3f7c:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7e:	0c d0       	rcall	.+24     	; 0x3f98 <putch>
+    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
+    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
       putch(SIGNATURE_1);
-    3f80:	84 e9       	ldi	r24, 0x94	; 148
-    3f82:	0a d0       	rcall	.+20     	; 0x3f98 <putch>
+    3f5e:	84 e9       	ldi	r24, 0x94	; 148
+    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
       putch(SIGNATURE_2);
-    3f84:	86 e0       	ldi	r24, 0x06	; 6
-    3f86:	7d cf       	rjmp	.-262    	; 0x3e82 <main+0x82>
+    3f62:	86 e0       	ldi	r24, 0x06	; 6
+    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f88:	81 35       	cpi	r24, 0x51	; 81
-    3f8a:	11 f4       	brne	.+4      	; 0x3f90 <main+0x190>
+    3f66:	81 35       	cpi	r24, 0x51	; 81
+    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8c:	88 e0       	ldi	r24, 0x08	; 8
-    3f8e:	18 d0       	rcall	.+48     	; 0x3fc0 <watchdogConfig>
+    3f6a:	88 e0       	ldi	r24, 0x08	; 8
+    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f90:	1d d0       	rcall	.+58     	; 0x3fcc <verifySpace>
+    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
     }
     putch(STK_OK);
-    3f92:	80 e1       	ldi	r24, 0x10	; 16
-    3f94:	01 d0       	rcall	.+2      	; 0x3f98 <putch>
-    3f96:	67 cf       	rjmp	.-306    	; 0x3e66 <main+0x66>
+    3f70:	80 e1       	ldi	r24, 0x10	; 16
+    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
+    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
 
-00003f98 <putch>:
+00003f76 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f98:	98 2f       	mov	r25, r24
+    3f76:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    3f9a:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9e:	85 ff       	sbrs	r24, 5
-    3fa0:	fc cf       	rjmp	.-8      	; 0x3f9a <putch+0x2>
+    3f78:	80 91 c0 00 	lds	r24, 0x00C0
+    3f7c:	85 ff       	sbrs	r24, 5
+    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
   UART_UDR = ch;
-    3fa2:	90 93 c6 00 	sts	0x00C6, r25
+    3f80:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa6:	08 95       	ret
+    3f84:	08 95       	ret
 
-00003fa8 <getch>:
+00003f86 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    3fa8:	80 91 c0 00 	lds	r24, 0x00C0
-    3fac:	87 ff       	sbrs	r24, 7
-    3fae:	fc cf       	rjmp	.-8      	; 0x3fa8 <getch>
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	87 ff       	sbrs	r24, 7
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb4:	84 fd       	sbrc	r24, 4
-    3fb6:	01 c0       	rjmp	.+2      	; 0x3fba <getch+0x12>
+    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
+    3f92:	84 fd       	sbrc	r24, 4
+    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb8:	a8 95       	wdr
+    3f96:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
   ch = UART_UDR;
-    3fba:	80 91 c6 00 	lds	r24, 0x00C6
+    3f98:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbe:	08 95       	ret
+    3f9c:	08 95       	ret
 
-00003fc0 <watchdogConfig>:
+00003f9e <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fc0:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc2:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc4:	98 e1       	ldi	r25, 0x18	; 24
-    3fc6:	90 83       	st	Z, r25
+    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
+    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
+    3fa2:	98 e1       	ldi	r25, 0x18	; 24
+    3fa4:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc8:	80 83       	st	Z, r24
+    3fa6:	80 83       	st	Z, r24
 }
-    3fca:	08 95       	ret
+    3fa8:	08 95       	ret
 
-00003fcc <verifySpace>:
+00003faa <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fcc:	ed df       	rcall	.-38     	; 0x3fa8 <getch>
-    3fce:	80 32       	cpi	r24, 0x20	; 32
-    3fd0:	19 f0       	breq	.+6      	; 0x3fd8 <verifySpace+0xc>
+    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
+    3fac:	80 32       	cpi	r24, 0x20	; 32
+    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd2:	88 e0       	ldi	r24, 0x08	; 8
-    3fd4:	f5 df       	rcall	.-22     	; 0x3fc0 <watchdogConfig>
-    3fd6:	ff cf       	rjmp	.-2      	; 0x3fd6 <verifySpace+0xa>
+    3fb0:	88 e0       	ldi	r24, 0x08	; 8
+    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
+    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd8:	84 e1       	ldi	r24, 0x14	; 20
+    3fb6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fda:	de cf       	rjmp	.-68     	; 0x3f98 <putch>
+    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
 
-00003fdc <getNch>:
+00003fba <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fdc:	1f 93       	push	r17
-    3fde:	18 2f       	mov	r17, r24
+    3fba:	1f 93       	push	r17
+    3fbc:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fe0:	e3 df       	rcall	.-58     	; 0x3fa8 <getch>
-    3fe2:	11 50       	subi	r17, 0x01	; 1
-    3fe4:	e9 f7       	brne	.-6      	; 0x3fe0 <getNch+0x4>
+    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
+    3fc0:	11 50       	subi	r17, 0x01	; 1
+    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
   verifySpace();
-    3fe6:	f2 df       	rcall	.-28     	; 0x3fcc <verifySpace>
+    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
 }
-    3fe8:	1f 91       	pop	r17
-    3fea:	08 95       	ret
+    3fc6:	1f 91       	pop	r17
+    3fc8:	08 95       	ret
 
-00003fec <appStart>:
+00003fca <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fec:	28 2e       	mov	r2, r24
+    3fca:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    3fee:	80 e0       	ldi	r24, 0x00	; 0
-    3ff0:	e7 df       	rcall	.-50     	; 0x3fc0 <watchdogConfig>
+    3fcc:	80 e0       	ldi	r24, 0x00	; 0
+    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
   __asm__ __volatile__ (
-    3ff2:	ee 27       	eor	r30, r30
-    3ff4:	ff 27       	eor	r31, r31
-    3ff6:	09 94       	ijmp
+    3fd0:	ee 27       	eor	r30, r30
+    3fd2:	ff 27       	eor	r31, r31
+    3fd4:	09 94       	ijmp

+ 37 - 39
optiboot/bootloaders/optiboot/optiboot_luminet.hex

@@ -1,41 +1,39 @@
-:101D0000112484B714BE81FF24D185E08EBD8EE0FE
-:101D10000CD1D49AD29A86E023EC3FEF91E03DBDFE
-:101D20002CBD9BB9589BFECFCC9AA8958150B9F792
-:101D3000EE24FF2493E0992EBB24B39485E0A82ED3
-:101D40000FE7D02E1EECC12EDDD0813461F4DAD045
-:101D5000082FEFD0023829F1013811F485E001C0D5
-:101D600083E0C1D0BDC0823411F484E103C0853466
-:101D700019F485E0E6D0B4C0853579F4C3D0E82EF7
-:101D8000FF24C0D0082F10E0102F00270E291F2994
-:101D9000000F111FCED07801A3C0863521F484E056
-:101DA000D0D080E0DECF843609F05FC0ABD0AAD0BF
-:101DB000182FA8D0C0E0D1E0A5D089931C17E1F777
-:101DC000F70197BEE895B5D007B600FCFDCFE1144A
-:101DD000F10411F0A7012AC08091000120910101B6
-:101DE00030E0322F222790E0282B392B30938501C9
-:101DF00020938401409108018091090190E0982F7F
-:101E0000882750E0842B952B90938701809386013F
-:101E10002450304020930801232F332720930901B9
-:101E2000D0920001C092010140E050E0A0E0B1E09A
-:101E30002C9130E011968C91119790E0982F882783
-:101E4000822B932B1296FA010C01B7BEE895112450
-:101E50004E5F5F4FF1E0A034BF0751F7F701A7BE17
-:101E6000E89507B600FCFDCF3BC0843759F54AD052
-:101E700049D0182F47D05DD0E701012F209719F4E2
-:101E80008091840114C0C130D10519F4809185017D
-:101E90000EC0C830D10519F48091860108C0C93040
-:101EA000D10519F48091870102C0FE018491219629
-:101EB0001AD0015019F70894E11CF11C1150E10EE1
-:101EC000F11C0EC0853739F434D08EE10CD083E993
-:101ED0000AD08CE046CF813511F488E026D029D095
-:101EE00080E101D031CF2AE030E08095089410F4F1
-:101EF000DA9802C0DA9A000014D013D086952A9599
-:101F0000B1F7089529E030E0CB99FECF0AD009D08F
-:101F100008D08894CB9908942A9511F08795F7CF2B
-:101F200008959EE09A95F1F7089598E191BD81BDDD
-:101F30000895E8DF803219F088E0F7DFFFCF84E111
-:101F4000D2CF1F93182FDEDF1150E9F7F2DF1F9178
-:0E1F50000895282E80E0E9DFE4E0FF270994E1
-:021EFE000005DD
+:101D0000112494B714BE892F8D7011F0892F0ED134
+:101D10008EE0F8D0D29AEE24FF2493E0B92EAA24C4
+:101D2000A39485E0982E0FE7D02E1EECC12ED7D0BD
+:101D3000813471F4D4D0082FE9D0023811F482E054
+:101D400005C0013811F486E001C083E0B9D0B5C008
+:101D5000823411F484E103C0853419F485E0DED0C7
+:101D6000ACC0853579F4BBD0E82EFF24B8D0082F5D
+:101D700010E0102F00270E291F29000F111FC6D0B9
+:101D800078019BC0863521F484E0C8D080E0DECFA6
+:101D9000843609F05EC0A3D0A2D0182FA0D0082F9F
+:101DA000C0E0D1E09CD089931C17E1F7AFD0E114DB
+:101DB000F10441F5809100012091010130E0322FC2
+:101DC000222790E0282B392B309385012093840122
+:101DD000409108018091090190E0982F882750E0F8
+:101DE000842B952B9093870180938601245030405B
+:101DF00020930801232F332720930901D09200015B
+:101E0000C0920101053409F4FFCFF701B7BEE89590
+:101E100007B600FCFDCFA701A0E0B1E02C9130E0B7
+:101E200011968C91119790E0982F8827822B932BF5
+:101E30001296FA010C01A7BEE89511244E5F5F4F80
+:101E40001A1761F7F70197BEE89507B600FCFDCFBA
+:101E500034C0843721F543D042D0082F40D056D02B
+:101E6000E701209719F48091840114C0C130D10595
+:101E700019F4809185010EC0C830D10519F4809104
+:101E8000860108C0C930D10519F48091870102C0CC
+:101E9000FE01849115D0015081F02196E2CF853763
+:101EA00039F434D08EE10CD083E90AD08CE04ECFE7
+:101EB000813511F488E026D029D080E101D037CFD8
+:101EC0002AE030E08095089410F4DA9802C0DA9A9B
+:101ED000000014D013D086952A95B1F7089529E013
+:101EE00030E0CB99FECF0AD009D008D08894CB99A6
+:101EF00008942A9511F08795F7CF08959EE09A955A
+:101F0000F1F7089598E191BD81BD0895E8DF803231
+:101F100019F088E0F7DFFFCF84E1D2CF1F93182FAD
+:101F2000DEDF1150E9F7F2DF1F910895282E80E0DF
+:081F3000E9DFE4E0FF2709945A
+:021FFE000206D9
 :0400000300001D00DC
 :00000001FF

+ 392 - 441
optiboot/bootloaders/optiboot/optiboot_luminet.lst

@@ -1,660 +1,611 @@
 
-optiboot_luminet.elf:     file format elf32-avr
+optiboot_attiny84.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         0000025e  00001d00  00001d00  00000054  2**1
+  0 .text         00000238  00001d00  00001d00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00001efe  00001efe  000002b2  2**0
-                  CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  000002b4  2**0
+  1 .version      00000002  00001ffe  00001ffe  000002ac  2**0
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+  2 .debug_aranges 00000028  00000000  00000000  000002ae  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000006d  00000000  00000000  000002dc  2**0
+  3 .debug_pubnames 00000082  00000000  00000000  000002d6  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002d2  00000000  00000000  00000349  2**0
+  4 .debug_info   000003e1  00000000  00000000  00000358  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000176  00000000  00000000  0000061b  2**0
+  5 .debug_abbrev 000001a5  00000000  00000000  00000739  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000471  00000000  00000000  00000791  2**0
+  6 .debug_line   0000042a  00000000  00000000  000008de  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000090  00000000  00000000  00000c04  2**2
+  7 .debug_frame  00000090  00000000  00000000  00000d08  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000152  00000000  00000000  00000c94  2**0
+  8 .debug_str    00000185  00000000  00000000  00000d98  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002b4  00000000  00000000  00000de6  2**0
+  9 .debug_loc    00000324  00000000  00000000  00000f1d  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000098  00000000  00000000  0000109a  2**0
+ 10 .debug_ranges 000000d0  00000000  00000000  00001241  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00001d00 <main>:
-# define UART_SRL UBRR3L
-# define UART_UDR UDR3
+#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
+
 /* main program starts here */
 int main(void) {
     1d00:	11 24       	eor	r1, r1
-#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
-  SP=RAMEND;  // This is done by hardware reset
-#endif
-
-  // Adaboot no-wait mod
+   * modified Adaboot no-wait mod.
+   * Pass the reset reason to app.  Also, it appears that an Uno poweron
+   * can leave multiple reset flags set; we only want the bootloader to
+   * run on an 'external reset only' status
+   */
   ch = MCUSR;
-    1d02:	84 b7       	in	r24, 0x34	; 52
+    1d02:	94 b7       	in	r25, 0x34	; 52
   MCUSR = 0;
     1d04:	14 be       	out	0x34, r1	; 52
-  if (!(ch & _BV(EXTRF))) appStart(ch);
-    1d06:	81 ff       	sbrs	r24, 1
-    1d08:	24 d1       	rcall	.+584    	; 0x1f52 <appStart>
-
-#if LED_START_FLASHES > 0
-  // Set up Timer 1 for timeout counter
-  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    1d0a:	85 e0       	ldi	r24, 0x05	; 5
-    1d0c:	8e bd       	out	0x2e, r24	; 46
+  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
+    1d06:	89 2f       	mov	r24, r25
+    1d08:	8d 70       	andi	r24, 0x0D	; 13
+    1d0a:	11 f0       	breq	.+4      	; 0x1d10 <main+0x10>
+      appStart(ch);
+    1d0c:	89 2f       	mov	r24, r25
+    1d0e:	0e d1       	rcall	.+540    	; 0x1f2c <appStart>
   UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #endif
 #endif
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
-    1d0e:	8e e0       	ldi	r24, 0x0E	; 14
-    1d10:	0c d1       	rcall	.+536    	; 0x1f2a <watchdogConfig>
-
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
-  /* Set LED pin as output */
+    1d10:	8e e0       	ldi	r24, 0x0E	; 14
+    1d12:	f8 d0       	rcall	.+496    	; 0x1f04 <watchdogConfig>
   LED_DDR |= _BV(LED);
-    1d12:	d4 9a       	sbi	0x1a, 4	; 26
 #endif
 
 #ifdef SOFT_UART
   /* Set TX pin as output */
   UART_DDR |= _BV(UART_TX_BIT);
     1d14:	d2 9a       	sbi	0x1a, 2	; 26
-    1d16:	86 e0       	ldi	r24, 0x06	; 6
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    1d18:	23 ec       	ldi	r18, 0xC3	; 195
-    1d1a:	3f ef       	ldi	r19, 0xFF	; 255
-    TIFR1 = _BV(TOV1);
-    1d1c:	91 e0       	ldi	r25, 0x01	; 1
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    1d1e:	3d bd       	out	0x2d, r19	; 45
-    1d20:	2c bd       	out	0x2c, r18	; 44
-    TIFR1 = _BV(TOV1);
-    1d22:	9b b9       	out	0x0b, r25	; 11
-    while(!(TIFR1 & _BV(TOV1)));
-    1d24:	58 9b       	sbis	0x0b, 0	; 11
-    1d26:	fe cf       	rjmp	.-4      	; 0x1d24 <main+0x24>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-    1d28:	cc 9a       	sbi	0x19, 4	; 25
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    1d2a:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-#endif
-    watchdogReset();
-  } while (--count);
-    1d2c:	81 50       	subi	r24, 0x01	; 1
-    1d2e:	b9 f7       	brne	.-18     	; 0x1d1e <main+0x1e>
-    1d30:	ee 24       	eor	r14, r14
-    1d32:	ff 24       	eor	r15, r15
-
-      // If we are in NRWW section, page erase has to be delayed until now.
-      // Todo: Take RAMPZ into account (not doing so just means that we will
-      //  treat the top of both "pages" of flash as NRWW, for a slight speed
-      //  decrease, so fixing this is not urgent.)
-      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    1d34:	93 e0       	ldi	r25, 0x03	; 3
-    1d36:	99 2e       	mov	r9, r25
-      ch = SPM_PAGESIZE / 2;
-      do {
-        uint16_t a;
-        a = *bufPtr++;
-        a |= (*bufPtr++) << 8;
-        __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    1d38:	bb 24       	eor	r11, r11
-    1d3a:	b3 94       	inc	r11
-        addrPtr += 2;
-      } while (--ch);
-
-      // Write from programming buffer
-      __boot_page_write_short((uint16_t)(void*)address);
-    1d3c:	85 e0       	ldi	r24, 0x05	; 5
-    1d3e:	a8 2e       	mov	r10, r24
+    1d16:	ee 24       	eor	r14, r14
+    1d18:	ff 24       	eor	r15, r15
+	     * Start the page erase and wait for it to finish.  There
+	     * used to be code to do this while receiving the data over
+	     * the serial link, but the performance improvement was slight,
+	     * and we needed the space back.
+	     */
+	    __boot_page_erase_short((uint16_t)(void*)address);
+    1d1a:	93 e0       	ldi	r25, 0x03	; 3
+    1d1c:	b9 2e       	mov	r11, r25
+	     */
+	    do {
+		uint16_t a;
+		a = *bufPtr++;
+		a |= (*bufPtr++) << 8;
+		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
+    1d1e:	aa 24       	eor	r10, r10
+    1d20:	a3 94       	inc	r10
+	    } while (len -= 2);
+
+	    /*
+	     * Actually Write the buffer to flash (and wait for it to finish.)
+	     */
+	    __boot_page_write_short((uint16_t)(void*)address);
+    1d22:	85 e0       	ldi	r24, 0x05	; 5
+    1d24:	98 2e       	mov	r9, r24
         vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
         buff[8] = vect & 0xff;
         buff[9] = vect >> 8;
 
         // Add jump to bootloader at RESET vector
         buff[0] = 0x7f;
-    1d40:	0f e7       	ldi	r16, 0x7F	; 127
-    1d42:	d0 2e       	mov	r13, r16
+    1d26:	0f e7       	ldi	r16, 0x7F	; 127
+    1d28:	d0 2e       	mov	r13, r16
         buff[1] = 0xce; // rjmp 0x1d00 instruction
-    1d44:	1e ec       	ldi	r17, 0xCE	; 206
-    1d46:	c1 2e       	mov	r12, r17
+    1d2a:	1e ec       	ldi	r17, 0xCE	; 206
+    1d2c:	c1 2e       	mov	r12, r17
 #endif
 
-  /* Forever loop */
+  /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    1d48:	dd d0       	rcall	.+442    	; 0x1f04 <getch>
+    1d2e:	d7 d0       	rcall	.+430    	; 0x1ede <getch>
 
     if(ch == STK_GET_PARAMETER) {
-    1d4a:	81 34       	cpi	r24, 0x41	; 65
-    1d4c:	61 f4       	brne	.+24     	; 0x1d66 <main+0x66>
+    1d30:	81 34       	cpi	r24, 0x41	; 65
+    1d32:	71 f4       	brne	.+28     	; 0x1d50 <main+0x50>
       unsigned char which = getch();
-    1d4e:	da d0       	rcall	.+436    	; 0x1f04 <getch>
-    1d50:	08 2f       	mov	r16, r24
+    1d34:	d4 d0       	rcall	.+424    	; 0x1ede <getch>
+    1d36:	08 2f       	mov	r16, r24
       verifySpace();
-    1d52:	ef d0       	rcall	.+478    	; 0x1f32 <verifySpace>
+    1d38:	e9 d0       	rcall	.+466    	; 0x1f0c <verifySpace>
+      /*
+       * Send optiboot version as "SW version"
+       * Note that the references to memory are optimized away.
+       */
       if (which == 0x82) {
-    1d54:	02 38       	cpi	r16, 0x82	; 130
-    1d56:	29 f1       	breq	.+74     	; 0x1da2 <main+0xa2>
-	/*
-	 * Send optiboot version as "minor SW version"
-	 */
-	putch(OPTIBOOT_MINVER);
+    1d3a:	02 38       	cpi	r16, 0x82	; 130
+    1d3c:	11 f4       	brne	.+4      	; 0x1d42 <main+0x42>
+	  putch(optiboot_version & 0xFF);
+    1d3e:	82 e0       	ldi	r24, 0x02	; 2
+    1d40:	05 c0       	rjmp	.+10     	; 0x1d4c <main+0x4c>
       } else if (which == 0x81) {
-    1d58:	01 38       	cpi	r16, 0x81	; 129
-    1d5a:	11 f4       	brne	.+4      	; 0x1d60 <main+0x60>
-	  putch(OPTIBOOT_MAJVER);
-    1d5c:	85 e0       	ldi	r24, 0x05	; 5
-    1d5e:	01 c0       	rjmp	.+2      	; 0x1d62 <main+0x62>
+    1d42:	01 38       	cpi	r16, 0x81	; 129
+    1d44:	11 f4       	brne	.+4      	; 0x1d4a <main+0x4a>
+	  putch(optiboot_version >> 8);
+    1d46:	86 e0       	ldi	r24, 0x06	; 6
+    1d48:	01 c0       	rjmp	.+2      	; 0x1d4c <main+0x4c>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    1d60:	83 e0       	ldi	r24, 0x03	; 3
-    1d62:	c1 d0       	rcall	.+386    	; 0x1ee6 <putch>
-    1d64:	bd c0       	rjmp	.+378    	; 0x1ee0 <main+0x1e0>
+    1d4a:	83 e0       	ldi	r24, 0x03	; 3
+    1d4c:	b9 d0       	rcall	.+370    	; 0x1ec0 <putch>
+    1d4e:	b5 c0       	rjmp	.+362    	; 0x1eba <main+0x1ba>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    1d66:	82 34       	cpi	r24, 0x42	; 66
-    1d68:	11 f4       	brne	.+4      	; 0x1d6e <main+0x6e>
+    1d50:	82 34       	cpi	r24, 0x42	; 66
+    1d52:	11 f4       	brne	.+4      	; 0x1d58 <main+0x58>
       // SET DEVICE is ignored
       getNch(20);
-    1d6a:	84 e1       	ldi	r24, 0x14	; 20
-    1d6c:	03 c0       	rjmp	.+6      	; 0x1d74 <main+0x74>
+    1d54:	84 e1       	ldi	r24, 0x14	; 20
+    1d56:	03 c0       	rjmp	.+6      	; 0x1d5e <main+0x5e>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    1d6e:	85 34       	cpi	r24, 0x45	; 69
-    1d70:	19 f4       	brne	.+6      	; 0x1d78 <main+0x78>
+    1d58:	85 34       	cpi	r24, 0x45	; 69
+    1d5a:	19 f4       	brne	.+6      	; 0x1d62 <main+0x62>
       // SET DEVICE EXT is ignored
       getNch(5);
-    1d72:	85 e0       	ldi	r24, 0x05	; 5
-    1d74:	e6 d0       	rcall	.+460    	; 0x1f42 <getNch>
-    1d76:	b4 c0       	rjmp	.+360    	; 0x1ee0 <main+0x1e0>
+    1d5c:	85 e0       	ldi	r24, 0x05	; 5
+    1d5e:	de d0       	rcall	.+444    	; 0x1f1c <verifySpace+0x10>
+    1d60:	ac c0       	rjmp	.+344    	; 0x1eba <main+0x1ba>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    1d78:	85 35       	cpi	r24, 0x55	; 85
-    1d7a:	79 f4       	brne	.+30     	; 0x1d9a <main+0x9a>
+    1d62:	85 35       	cpi	r24, 0x55	; 85
+    1d64:	79 f4       	brne	.+30     	; 0x1d84 <main+0x84>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    1d7c:	c3 d0       	rcall	.+390    	; 0x1f04 <getch>
+    1d66:	bb d0       	rcall	.+374    	; 0x1ede <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
-    1d7e:	e8 2e       	mov	r14, r24
-    1d80:	ff 24       	eor	r15, r15
-    1d82:	c0 d0       	rcall	.+384    	; 0x1f04 <getch>
-    1d84:	08 2f       	mov	r16, r24
-    1d86:	10 e0       	ldi	r17, 0x00	; 0
-    1d88:	10 2f       	mov	r17, r16
-    1d8a:	00 27       	eor	r16, r16
-    1d8c:	0e 29       	or	r16, r14
-    1d8e:	1f 29       	or	r17, r15
+    1d68:	e8 2e       	mov	r14, r24
+    1d6a:	ff 24       	eor	r15, r15
+    1d6c:	b8 d0       	rcall	.+368    	; 0x1ede <getch>
+    1d6e:	08 2f       	mov	r16, r24
+    1d70:	10 e0       	ldi	r17, 0x00	; 0
+    1d72:	10 2f       	mov	r17, r16
+    1d74:	00 27       	eor	r16, r16
+    1d76:	0e 29       	or	r16, r14
+    1d78:	1f 29       	or	r17, r15
 #ifdef RAMPZ
       // Transfer top bit to RAMPZ
       RAMPZ = (newAddress & 0x8000) ? 1 : 0;
 #endif
       newAddress += newAddress; // Convert from word address to byte address
-    1d90:	00 0f       	add	r16, r16
-    1d92:	11 1f       	adc	r17, r17
+    1d7a:	00 0f       	add	r16, r16
+    1d7c:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    1d94:	ce d0       	rcall	.+412    	; 0x1f32 <verifySpace>
-    1d96:	78 01       	movw	r14, r16
-    1d98:	a3 c0       	rjmp	.+326    	; 0x1ee0 <main+0x1e0>
+    1d7e:	c6 d0       	rcall	.+396    	; 0x1f0c <verifySpace>
+    1d80:	78 01       	movw	r14, r16
+    1d82:	9b c0       	rjmp	.+310    	; 0x1eba <main+0x1ba>
     }
     else if(ch == STK_UNIVERSAL) {
-    1d9a:	86 35       	cpi	r24, 0x56	; 86
-    1d9c:	21 f4       	brne	.+8      	; 0x1da6 <main+0xa6>
+    1d84:	86 35       	cpi	r24, 0x56	; 86
+    1d86:	21 f4       	brne	.+8      	; 0x1d90 <main+0x90>
       // UNIVERSAL command is ignored
       getNch(4);
-    1d9e:	84 e0       	ldi	r24, 0x04	; 4
-    1da0:	d0 d0       	rcall	.+416    	; 0x1f42 <getNch>
+    1d88:	84 e0       	ldi	r24, 0x04	; 4
+    1d8a:	c8 d0       	rcall	.+400    	; 0x1f1c <verifySpace+0x10>
       putch(0x00);
-    1da2:	80 e0       	ldi	r24, 0x00	; 0
-    1da4:	de cf       	rjmp	.-68     	; 0x1d62 <main+0x62>
+    1d8c:	80 e0       	ldi	r24, 0x00	; 0
+    1d8e:	de cf       	rjmp	.-68     	; 0x1d4c <main+0x4c>
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    1da6:	84 36       	cpi	r24, 0x64	; 100
-    1da8:	09 f0       	breq	.+2      	; 0x1dac <main+0xac>
-    1daa:	5f c0       	rjmp	.+190    	; 0x1e6a <main+0x16a>
+    1d90:	84 36       	cpi	r24, 0x64	; 100
+    1d92:	09 f0       	breq	.+2      	; 0x1d96 <main+0x96>
+    1d94:	5e c0       	rjmp	.+188    	; 0x1e52 <main+0x152>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
+      uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t addrPtr;
-
-      getch();			/* getlen() */
-    1dac:	ab d0       	rcall	.+342    	; 0x1f04 <getch>
-      length = getch();
-    1dae:	aa d0       	rcall	.+340    	; 0x1f04 <getch>
-    1db0:	18 2f       	mov	r17, r24
-      getch();
-    1db2:	a8 d0       	rcall	.+336    	; 0x1f04 <getch>
-    1db4:	c0 e0       	ldi	r28, 0x00	; 0
-    1db6:	d1 e0       	ldi	r29, 0x01	; 1
-      // If we are in RWW section, immediately start page erase
-      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-
-      // While that is going on, read in page contents
+      pagelen_t savelength;
+
+      GETLENGTH(length);
+    1d96:	a3 d0       	rcall	.+326    	; 0x1ede <getch>
+    1d98:	a2 d0       	rcall	.+324    	; 0x1ede <getch>
+    1d9a:	18 2f       	mov	r17, r24
+      savelength = length;
+      desttype = getch();
+    1d9c:	a0 d0       	rcall	.+320    	; 0x1ede <getch>
+    1d9e:	08 2f       	mov	r16, r24
+    1da0:	c0 e0       	ldi	r28, 0x00	; 0
+    1da2:	d1 e0       	ldi	r29, 0x01	; 1
+
+      // read a page worth of contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    1db8:	a5 d0       	rcall	.+330    	; 0x1f04 <getch>
-    1dba:	89 93       	st	Y+, r24
+    1da4:	9c d0       	rcall	.+312    	; 0x1ede <getch>
+    1da6:	89 93       	st	Y+, r24
       while (--length);
-    1dbc:	1c 17       	cp	r17, r28
-    1dbe:	e1 f7       	brne	.-8      	; 0x1db8 <main+0xb8>
-
-      // If we are in NRWW section, page erase has to be delayed until now.
-      // Todo: Take RAMPZ into account (not doing so just means that we will
-      //  treat the top of both "pages" of flash as NRWW, for a slight speed
-      //  decrease, so fixing this is not urgent.)
-      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    1dc0:	f7 01       	movw	r30, r14
-    1dc2:	97 be       	out	0x37, r9	; 55
-    1dc4:	e8 95       	spm
+    1da8:	1c 17       	cp	r17, r28
+    1daa:	e1 f7       	brne	.-8      	; 0x1da4 <main+0xa4>
 
       // Read command terminator, start reply
       verifySpace();
-    1dc6:	b5 d0       	rcall	.+362    	; 0x1f32 <verifySpace>
-
-      // If only a partial page is to be programmed, the erase might not be complete.
-      // So check that here
-      boot_spm_busy_wait();
-    1dc8:	07 b6       	in	r0, 0x37	; 55
-    1dca:	00 fc       	sbrc	r0, 0
-    1dcc:	fd cf       	rjmp	.-6      	; 0x1dc8 <main+0xc8>
+    1dac:	af d0       	rcall	.+350    	; 0x1f0c <verifySpace>
 
 #ifdef VIRTUAL_BOOT_PARTITION
       if ((uint16_t)(void*)address == 0) {
-    1dce:	e1 14       	cp	r14, r1
-    1dd0:	f1 04       	cpc	r15, r1
-    1dd2:	11 f0       	breq	.+4      	; 0x1dd8 <main+0xd8>
-    1dd4:	a7 01       	movw	r20, r14
-    1dd6:	2a c0       	rjmp	.+84     	; 0x1e2c <main+0x12c>
+    1dae:	e1 14       	cp	r14, r1
+    1db0:	f1 04       	cpc	r15, r1
+    1db2:	41 f5       	brne	.+80     	; 0x1e04 <main+0x104>
         // This is the reset vector page. We need to live-patch the code so the
         // bootloader runs.
         //
         // Move RESET vector to WDT vector
         uint16_t vect = buff[0] | (buff[1]<<8);
-    1dd8:	80 91 00 01 	lds	r24, 0x0100
-    1ddc:	20 91 01 01 	lds	r18, 0x0101
-    1de0:	30 e0       	ldi	r19, 0x00	; 0
-    1de2:	32 2f       	mov	r19, r18
-    1de4:	22 27       	eor	r18, r18
-    1de6:	90 e0       	ldi	r25, 0x00	; 0
-    1de8:	28 2b       	or	r18, r24
-    1dea:	39 2b       	or	r19, r25
+    1db4:	80 91 00 01 	lds	r24, 0x0100
+    1db8:	20 91 01 01 	lds	r18, 0x0101
+    1dbc:	30 e0       	ldi	r19, 0x00	; 0
+    1dbe:	32 2f       	mov	r19, r18
+    1dc0:	22 27       	eor	r18, r18
+    1dc2:	90 e0       	ldi	r25, 0x00	; 0
+    1dc4:	28 2b       	or	r18, r24
+    1dc6:	39 2b       	or	r19, r25
         rstVect = vect;
-    1dec:	30 93 85 01 	sts	0x0185, r19
-    1df0:	20 93 84 01 	sts	0x0184, r18
+    1dc8:	30 93 85 01 	sts	0x0185, r19
+    1dcc:	20 93 84 01 	sts	0x0184, r18
         wdtVect = buff[8] | (buff[9]<<8);
-    1df4:	40 91 08 01 	lds	r20, 0x0108
-    1df8:	80 91 09 01 	lds	r24, 0x0109
-    1dfc:	90 e0       	ldi	r25, 0x00	; 0
-    1dfe:	98 2f       	mov	r25, r24
-    1e00:	88 27       	eor	r24, r24
-    1e02:	50 e0       	ldi	r21, 0x00	; 0
-    1e04:	84 2b       	or	r24, r20
-    1e06:	95 2b       	or	r25, r21
-    1e08:	90 93 87 01 	sts	0x0187, r25
-    1e0c:	80 93 86 01 	sts	0x0186, r24
+    1dd0:	40 91 08 01 	lds	r20, 0x0108
+    1dd4:	80 91 09 01 	lds	r24, 0x0109
+    1dd8:	90 e0       	ldi	r25, 0x00	; 0
+    1dda:	98 2f       	mov	r25, r24
+    1ddc:	88 27       	eor	r24, r24
+    1dde:	50 e0       	ldi	r21, 0x00	; 0
+    1de0:	84 2b       	or	r24, r20
+    1de2:	95 2b       	or	r25, r21
+    1de4:	90 93 87 01 	sts	0x0187, r25
+    1de8:	80 93 86 01 	sts	0x0186, r24
         vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
-    1e10:	24 50       	subi	r18, 0x04	; 4
-    1e12:	30 40       	sbci	r19, 0x00	; 0
+    1dec:	24 50       	subi	r18, 0x04	; 4
+    1dee:	30 40       	sbci	r19, 0x00	; 0
         buff[8] = vect & 0xff;
-    1e14:	20 93 08 01 	sts	0x0108, r18
+    1df0:	20 93 08 01 	sts	0x0108, r18
         buff[9] = vect >> 8;
-    1e18:	23 2f       	mov	r18, r19
-    1e1a:	33 27       	eor	r19, r19
-    1e1c:	20 93 09 01 	sts	0x0109, r18
+    1df4:	23 2f       	mov	r18, r19
+    1df6:	33 27       	eor	r19, r19
+    1df8:	20 93 09 01 	sts	0x0109, r18
 
         // Add jump to bootloader at RESET vector
         buff[0] = 0x7f;
-    1e20:	d0 92 00 01 	sts	0x0100, r13
+    1dfc:	d0 92 00 01 	sts	0x0100, r13
         buff[1] = 0xce; // rjmp 0x1d00 instruction
-    1e24:	c0 92 01 01 	sts	0x0101, r12
-    1e28:	40 e0       	ldi	r20, 0x00	; 0
-    1e2a:	50 e0       	ldi	r21, 0x00	; 0
-    1e2c:	a0 e0       	ldi	r26, 0x00	; 0
-    1e2e:	b1 e0       	ldi	r27, 0x01	; 1
-      bufPtr = buff;
-      addrPtr = (uint16_t)(void*)address;
-      ch = SPM_PAGESIZE / 2;
-      do {
-        uint16_t a;
-        a = *bufPtr++;
-    1e30:	2c 91       	ld	r18, X
-    1e32:	30 e0       	ldi	r19, 0x00	; 0
-        a |= (*bufPtr++) << 8;
-    1e34:	11 96       	adiw	r26, 0x01	; 1
-    1e36:	8c 91       	ld	r24, X
-    1e38:	11 97       	sbiw	r26, 0x01	; 1
-    1e3a:	90 e0       	ldi	r25, 0x00	; 0
-    1e3c:	98 2f       	mov	r25, r24
-    1e3e:	88 27       	eor	r24, r24
-    1e40:	82 2b       	or	r24, r18
-    1e42:	93 2b       	or	r25, r19
-# define UART_SRL UBRR3L
-# define UART_UDR UDR3
+    1e00:	c0 92 01 01 	sts	0x0101, r12
+ * void writebuffer(memtype, buffer, address, length)
+ */
+static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
+			       uint16_t address, pagelen_t len)
+{
+    switch (memtype) {
+    1e04:	05 34       	cpi	r16, 0x45	; 69
+    1e06:	09 f4       	brne	.+2      	; 0x1e0a <main+0x10a>
+    1e08:	ff cf       	rjmp	.-2      	; 0x1e08 <main+0x108>
+	     * Start the page erase and wait for it to finish.  There
+	     * used to be code to do this while receiving the data over
+	     * the serial link, but the performance improvement was slight,
+	     * and we needed the space back.
+	     */
+	    __boot_page_erase_short((uint16_t)(void*)address);
+    1e0a:	f7 01       	movw	r30, r14
+    1e0c:	b7 be       	out	0x37, r11	; 55
+    1e0e:	e8 95       	spm
+	    boot_spm_busy_wait();
+    1e10:	07 b6       	in	r0, 0x37	; 55
+    1e12:	00 fc       	sbrc	r0, 0
+    1e14:	fd cf       	rjmp	.-6      	; 0x1e10 <main+0x110>
+    1e16:	a7 01       	movw	r20, r14
+    1e18:	a0 e0       	ldi	r26, 0x00	; 0
+    1e1a:	b1 e0       	ldi	r27, 0x01	; 1
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
+	     */
+	    do {
+		uint16_t a;
+		a = *bufPtr++;
+    1e1c:	2c 91       	ld	r18, X
+    1e1e:	30 e0       	ldi	r19, 0x00	; 0
+		a |= (*bufPtr++) << 8;
+    1e20:	11 96       	adiw	r26, 0x01	; 1
+    1e22:	8c 91       	ld	r24, X
+    1e24:	11 97       	sbiw	r26, 0x01	; 1
+    1e26:	90 e0       	ldi	r25, 0x00	; 0
+    1e28:	98 2f       	mov	r25, r24
+    1e2a:	88 27       	eor	r24, r24
+    1e2c:	82 2b       	or	r24, r18
+    1e2e:	93 2b       	or	r25, r19
+#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
+
 /* main program starts here */
 int main(void) {
-    1e44:	12 96       	adiw	r26, 0x02	; 2
-      ch = SPM_PAGESIZE / 2;
-      do {
-        uint16_t a;
-        a = *bufPtr++;
-        a |= (*bufPtr++) << 8;
-        __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    1e46:	fa 01       	movw	r30, r20
-    1e48:	0c 01       	movw	r0, r24
-    1e4a:	b7 be       	out	0x37, r11	; 55
-    1e4c:	e8 95       	spm
-    1e4e:	11 24       	eor	r1, r1
-        addrPtr += 2;
-    1e50:	4e 5f       	subi	r20, 0xFE	; 254
-    1e52:	5f 4f       	sbci	r21, 0xFF	; 255
-      } while (--ch);
-    1e54:	f1 e0       	ldi	r31, 0x01	; 1
-    1e56:	a0 34       	cpi	r26, 0x40	; 64
-    1e58:	bf 07       	cpc	r27, r31
-    1e5a:	51 f7       	brne	.-44     	; 0x1e30 <main+0x130>
-
-      // Write from programming buffer
-      __boot_page_write_short((uint16_t)(void*)address);
-    1e5c:	f7 01       	movw	r30, r14
-    1e5e:	a7 be       	out	0x37, r10	; 55
-    1e60:	e8 95       	spm
-      boot_spm_busy_wait();
-    1e62:	07 b6       	in	r0, 0x37	; 55
-    1e64:	00 fc       	sbrc	r0, 0
-    1e66:	fd cf       	rjmp	.-6      	; 0x1e62 <main+0x162>
-    1e68:	3b c0       	rjmp	.+118    	; 0x1ee0 <main+0x1e0>
-      boot_rww_enable();
-#endif
+    1e30:	12 96       	adiw	r26, 0x02	; 2
+	     */
+	    do {
+		uint16_t a;
+		a = *bufPtr++;
+		a |= (*bufPtr++) << 8;
+		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
+    1e32:	fa 01       	movw	r30, r20
+    1e34:	0c 01       	movw	r0, r24
+    1e36:	a7 be       	out	0x37, r10	; 55
+    1e38:	e8 95       	spm
+    1e3a:	11 24       	eor	r1, r1
+		addrPtr += 2;
+    1e3c:	4e 5f       	subi	r20, 0xFE	; 254
+    1e3e:	5f 4f       	sbci	r21, 0xFF	; 255
+	    } while (len -= 2);
+    1e40:	1a 17       	cp	r17, r26
+    1e42:	61 f7       	brne	.-40     	; 0x1e1c <main+0x11c>
+
+	    /*
+	     * Actually Write the buffer to flash (and wait for it to finish.)
+	     */
+	    __boot_page_write_short((uint16_t)(void*)address);
+    1e44:	f7 01       	movw	r30, r14
+    1e46:	97 be       	out	0x37, r9	; 55
+    1e48:	e8 95       	spm
+	    boot_spm_busy_wait();
+    1e4a:	07 b6       	in	r0, 0x37	; 55
+    1e4c:	00 fc       	sbrc	r0, 0
+    1e4e:	fd cf       	rjmp	.-6      	; 0x1e4a <main+0x14a>
+    1e50:	34 c0       	rjmp	.+104    	; 0x1eba <main+0x1ba>
+      writebuffer(desttype, buff, address, savelength);
+
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    1e6a:	84 37       	cpi	r24, 0x74	; 116
-    1e6c:	59 f5       	brne	.+86     	; 0x1ec4 <main+0x1c4>
-      // READ PAGE - we only read flash
-      getch();			/* getlen() */
-    1e6e:	4a d0       	rcall	.+148    	; 0x1f04 <getch>
-      length = getch();
-    1e70:	49 d0       	rcall	.+146    	; 0x1f04 <getch>
-    1e72:	18 2f       	mov	r17, r24
-      getch();
-    1e74:	47 d0       	rcall	.+142    	; 0x1f04 <getch>
+    1e52:	84 37       	cpi	r24, 0x74	; 116
+    1e54:	21 f5       	brne	.+72     	; 0x1e9e <main+0x19e>
+      uint8_t desttype;
+      GETLENGTH(length);
+    1e56:	43 d0       	rcall	.+134    	; 0x1ede <getch>
+    1e58:	42 d0       	rcall	.+132    	; 0x1ede <getch>
+    1e5a:	08 2f       	mov	r16, r24
+
+      desttype = getch();
+    1e5c:	40 d0       	rcall	.+128    	; 0x1ede <getch>
 
       verifySpace();
-    1e76:	5d d0       	rcall	.+186    	; 0x1f32 <verifySpace>
-    1e78:	e7 01       	movw	r28, r14
-    1e7a:	01 2f       	mov	r16, r17
-      do {
+    1e5e:	56 d0       	rcall	.+172    	; 0x1f0c <verifySpace>
+    1e60:	e7 01       	movw	r28, r14
+#endif
+    default:
+	do {
 #ifdef VIRTUAL_BOOT_PARTITION
         // Undo vector patch in bottom page so verify passes
-        if (address == 0)       ch=rstVect & 0xff;
-    1e7c:	20 97       	sbiw	r28, 0x00	; 0
-    1e7e:	19 f4       	brne	.+6      	; 0x1e86 <main+0x186>
-    1e80:	80 91 84 01 	lds	r24, 0x0184
-    1e84:	14 c0       	rjmp	.+40     	; 0x1eae <main+0x1ae>
-        else if (address == 1)  ch=rstVect >> 8;
-    1e86:	c1 30       	cpi	r28, 0x01	; 1
-    1e88:	d1 05       	cpc	r29, r1
-    1e8a:	19 f4       	brne	.+6      	; 0x1e92 <main+0x192>
-    1e8c:	80 91 85 01 	lds	r24, 0x0185
-    1e90:	0e c0       	rjmp	.+28     	; 0x1eae <main+0x1ae>
-        else if (address == 8)  ch=wdtVect & 0xff;
-    1e92:	c8 30       	cpi	r28, 0x08	; 8
-    1e94:	d1 05       	cpc	r29, r1
-    1e96:	19 f4       	brne	.+6      	; 0x1e9e <main+0x19e>
-    1e98:	80 91 86 01 	lds	r24, 0x0186
-    1e9c:	08 c0       	rjmp	.+16     	; 0x1eae <main+0x1ae>
-        else if (address == 9) ch=wdtVect >> 8;
-    1e9e:	c9 30       	cpi	r28, 0x09	; 9
-    1ea0:	d1 05       	cpc	r29, r1
-    1ea2:	19 f4       	brne	.+6      	; 0x1eaa <main+0x1aa>
-    1ea4:	80 91 87 01 	lds	r24, 0x0187
-    1ea8:	02 c0       	rjmp	.+4      	; 0x1eae <main+0x1ae>
-        else ch = pgm_read_byte_near(address);
-    1eaa:	fe 01       	movw	r30, r28
-    1eac:	84 91       	lpm	r24, Z+
-        address++;
-    1eae:	21 96       	adiw	r28, 0x01	; 1
-        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    if (address == 0)       ch=rstVect & 0xff;
+    1e62:	20 97       	sbiw	r28, 0x00	; 0
+    1e64:	19 f4       	brne	.+6      	; 0x1e6c <main+0x16c>
+    1e66:	80 91 84 01 	lds	r24, 0x0184
+    1e6a:	14 c0       	rjmp	.+40     	; 0x1e94 <main+0x194>
+	    else if (address == 1)  ch=rstVect >> 8;
+    1e6c:	c1 30       	cpi	r28, 0x01	; 1
+    1e6e:	d1 05       	cpc	r29, r1
+    1e70:	19 f4       	brne	.+6      	; 0x1e78 <main+0x178>
+    1e72:	80 91 85 01 	lds	r24, 0x0185
+    1e76:	0e c0       	rjmp	.+28     	; 0x1e94 <main+0x194>
+	    else if (address == 8)  ch=wdtVect & 0xff;
+    1e78:	c8 30       	cpi	r28, 0x08	; 8
+    1e7a:	d1 05       	cpc	r29, r1
+    1e7c:	19 f4       	brne	.+6      	; 0x1e84 <main+0x184>
+    1e7e:	80 91 86 01 	lds	r24, 0x0186
+    1e82:	08 c0       	rjmp	.+16     	; 0x1e94 <main+0x194>
+	    else if (address == 9) ch=wdtVect >> 8;
+    1e84:	c9 30       	cpi	r28, 0x09	; 9
+    1e86:	d1 05       	cpc	r29, r1
+    1e88:	19 f4       	brne	.+6      	; 0x1e90 <main+0x190>
+    1e8a:	80 91 87 01 	lds	r24, 0x0187
+    1e8e:	02 c0       	rjmp	.+4      	; 0x1e94 <main+0x194>
+	    else ch = pgm_read_byte_near(address);
+    1e90:	fe 01       	movw	r30, r28
+    1e92:	84 91       	lpm	r24, Z+
+	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-        // read a Flash byte and increment the address
-        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    // read a Flash byte and increment the address
+	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
-        putch(ch);
-    1eb0:	1a d0       	rcall	.+52     	; 0x1ee6 <putch>
-      } while (--length);
-    1eb2:	01 50       	subi	r16, 0x01	; 1
-    1eb4:	19 f7       	brne	.-58     	; 0x1e7c <main+0x17c>
-# define UART_SRL UBRR3L
-# define UART_UDR UDR3
-#endif
-
-/* main program starts here */
-int main(void) {
-    1eb6:	08 94       	sec
-    1eb8:	e1 1c       	adc	r14, r1
-    1eba:	f1 1c       	adc	r15, r1
-    1ebc:	11 50       	subi	r17, 0x01	; 1
-    1ebe:	e1 0e       	add	r14, r17
-    1ec0:	f1 1c       	adc	r15, r1
-    1ec2:	0e c0       	rjmp	.+28     	; 0x1ee0 <main+0x1e0>
-        putch(ch);
-      } while (--length);
+	    putch(ch);
+    1e94:	15 d0       	rcall	.+42     	; 0x1ec0 <putch>
+	} while (--length);
+    1e96:	01 50       	subi	r16, 0x01	; 1
+    1e98:	81 f0       	breq	.+32     	; 0x1eba <main+0x1ba>
+	    if (address == 0)       ch=rstVect & 0xff;
+	    else if (address == 1)  ch=rstVect >> 8;
+	    else if (address == 8)  ch=wdtVect & 0xff;
+	    else if (address == 9) ch=wdtVect >> 8;
+	    else ch = pgm_read_byte_near(address);
+	    address++;
+    1e9a:	21 96       	adiw	r28, 0x01	; 1
+    1e9c:	e2 cf       	rjmp	.-60     	; 0x1e62 <main+0x162>
+	  
+      read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    1ec4:	85 37       	cpi	r24, 0x75	; 117
-    1ec6:	39 f4       	brne	.+14     	; 0x1ed6 <main+0x1d6>
+    1e9e:	85 37       	cpi	r24, 0x75	; 117
+    1ea0:	39 f4       	brne	.+14     	; 0x1eb0 <main+0x1b0>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    1ec8:	34 d0       	rcall	.+104    	; 0x1f32 <verifySpace>
+    1ea2:	34 d0       	rcall	.+104    	; 0x1f0c <verifySpace>
       putch(SIGNATURE_0);
-    1eca:	8e e1       	ldi	r24, 0x1E	; 30
-    1ecc:	0c d0       	rcall	.+24     	; 0x1ee6 <putch>
+    1ea4:	8e e1       	ldi	r24, 0x1E	; 30
+    1ea6:	0c d0       	rcall	.+24     	; 0x1ec0 <putch>
       putch(SIGNATURE_1);
-    1ece:	83 e9       	ldi	r24, 0x93	; 147
-    1ed0:	0a d0       	rcall	.+20     	; 0x1ee6 <putch>
+    1ea8:	83 e9       	ldi	r24, 0x93	; 147
+    1eaa:	0a d0       	rcall	.+20     	; 0x1ec0 <putch>
       putch(SIGNATURE_2);
-    1ed2:	8c e0       	ldi	r24, 0x0C	; 12
-    1ed4:	46 cf       	rjmp	.-372    	; 0x1d62 <main+0x62>
+    1eac:	8c e0       	ldi	r24, 0x0C	; 12
+    1eae:	4e cf       	rjmp	.-356    	; 0x1d4c <main+0x4c>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    1ed6:	81 35       	cpi	r24, 0x51	; 81
-    1ed8:	11 f4       	brne	.+4      	; 0x1ede <main+0x1de>
+    1eb0:	81 35       	cpi	r24, 0x51	; 81
+    1eb2:	11 f4       	brne	.+4      	; 0x1eb8 <main+0x1b8>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    1eda:	88 e0       	ldi	r24, 0x08	; 8
-    1edc:	26 d0       	rcall	.+76     	; 0x1f2a <watchdogConfig>
+    1eb4:	88 e0       	ldi	r24, 0x08	; 8
+    1eb6:	26 d0       	rcall	.+76     	; 0x1f04 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    1ede:	29 d0       	rcall	.+82     	; 0x1f32 <verifySpace>
+    1eb8:	29 d0       	rcall	.+82     	; 0x1f0c <verifySpace>
     }
     putch(STK_OK);
-    1ee0:	80 e1       	ldi	r24, 0x10	; 16
-    1ee2:	01 d0       	rcall	.+2      	; 0x1ee6 <putch>
-    1ee4:	31 cf       	rjmp	.-414    	; 0x1d48 <main+0x48>
+    1eba:	80 e1       	ldi	r24, 0x10	; 16
+    1ebc:	01 d0       	rcall	.+2      	; 0x1ec0 <putch>
+    1ebe:	37 cf       	rjmp	.-402    	; 0x1d2e <main+0x2e>
 
-00001ee6 <putch>:
+00001ec0 <putch>:
 void putch(char ch) {
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
   UART_UDR = ch;
 #else
   __asm__ __volatile__ (
-    1ee6:	2a e0       	ldi	r18, 0x0A	; 10
-    1ee8:	30 e0       	ldi	r19, 0x00	; 0
-    1eea:	80 95       	com	r24
-    1eec:	08 94       	sec
-    1eee:	10 f4       	brcc	.+4      	; 0x1ef4 <putch+0xe>
-    1ef0:	da 98       	cbi	0x1b, 2	; 27
-    1ef2:	02 c0       	rjmp	.+4      	; 0x1ef8 <putch+0x12>
-    1ef4:	da 9a       	sbi	0x1b, 2	; 27
-    1ef6:	00 00       	nop
-    1ef8:	14 d0       	rcall	.+40     	; 0x1f22 <uartDelay>
-    1efa:	13 d0       	rcall	.+38     	; 0x1f22 <uartDelay>
-    1efc:	86 95       	lsr	r24
-    1efe:	2a 95       	dec	r18
-    1f00:	b1 f7       	brne	.-20     	; 0x1eee <putch+0x8>
+    1ec0:	2a e0       	ldi	r18, 0x0A	; 10
+    1ec2:	30 e0       	ldi	r19, 0x00	; 0
+    1ec4:	80 95       	com	r24
+    1ec6:	08 94       	sec
+    1ec8:	10 f4       	brcc	.+4      	; 0x1ece <putch+0xe>
+    1eca:	da 98       	cbi	0x1b, 2	; 27
+    1ecc:	02 c0       	rjmp	.+4      	; 0x1ed2 <putch+0x12>
+    1ece:	da 9a       	sbi	0x1b, 2	; 27
+    1ed0:	00 00       	nop
+    1ed2:	14 d0       	rcall	.+40     	; 0x1efc <uartDelay>
+    1ed4:	13 d0       	rcall	.+38     	; 0x1efc <uartDelay>
+    1ed6:	86 95       	lsr	r24
+    1ed8:	2a 95       	dec	r18
+    1eda:	b1 f7       	brne	.-20     	; 0x1ec8 <putch+0x8>
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    1f02:	08 95       	ret
+    1edc:	08 95       	ret
 
-00001f04 <getch>:
+00001ede <getch>:
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    1f04:	29 e0       	ldi	r18, 0x09	; 9
-    1f06:	30 e0       	ldi	r19, 0x00	; 0
-    1f08:	cb 99       	sbic	0x19, 3	; 25
-    1f0a:	fe cf       	rjmp	.-4      	; 0x1f08 <getch+0x4>
-    1f0c:	0a d0       	rcall	.+20     	; 0x1f22 <uartDelay>
-    1f0e:	09 d0       	rcall	.+18     	; 0x1f22 <uartDelay>
-    1f10:	08 d0       	rcall	.+16     	; 0x1f22 <uartDelay>
-    1f12:	88 94       	clc
-    1f14:	cb 99       	sbic	0x19, 3	; 25
-    1f16:	08 94       	sec
-    1f18:	2a 95       	dec	r18
-    1f1a:	11 f0       	breq	.+4      	; 0x1f20 <getch+0x1c>
-    1f1c:	87 95       	ror	r24
-    1f1e:	f7 cf       	rjmp	.-18     	; 0x1f0e <getch+0xa>
-    1f20:	08 95       	ret
-
-00001f22 <uartDelay>:
+    1ede:	29 e0       	ldi	r18, 0x09	; 9
+    1ee0:	30 e0       	ldi	r19, 0x00	; 0
+    1ee2:	cb 99       	sbic	0x19, 3	; 25
+    1ee4:	fe cf       	rjmp	.-4      	; 0x1ee2 <getch+0x4>
+    1ee6:	0a d0       	rcall	.+20     	; 0x1efc <uartDelay>
+    1ee8:	09 d0       	rcall	.+18     	; 0x1efc <uartDelay>
+    1eea:	08 d0       	rcall	.+16     	; 0x1efc <uartDelay>
+    1eec:	88 94       	clc
+    1eee:	cb 99       	sbic	0x19, 3	; 25
+    1ef0:	08 94       	sec
+    1ef2:	2a 95       	dec	r18
+    1ef4:	11 f0       	breq	.+4      	; 0x1efa <getch+0x1c>
+    1ef6:	87 95       	ror	r24
+    1ef8:	f7 cf       	rjmp	.-18     	; 0x1ee8 <getch+0xa>
+    1efa:	08 95       	ret
+
+00001efc <uartDelay>:
 #if UART_B_VALUE > 255
 #error Baud rate too slow for soft UART
 #endif
 
 void uartDelay() {
   __asm__ __volatile__ (
-    1f22:	9e e0       	ldi	r25, 0x0E	; 14
-    1f24:	9a 95       	dec	r25
-    1f26:	f1 f7       	brne	.-4      	; 0x1f24 <uartDelay+0x2>
-    1f28:	08 95       	ret
+    1efc:	9e e0       	ldi	r25, 0x0E	; 14
+    1efe:	9a 95       	dec	r25
+    1f00:	f1 f7       	brne	.-4      	; 0x1efe <uartDelay+0x2>
+    1f02:	08 95       	ret
 
-00001f2a <watchdogConfig>:
+00001f04 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    1f2a:	98 e1       	ldi	r25, 0x18	; 24
-    1f2c:	91 bd       	out	0x21, r25	; 33
+    1f04:	98 e1       	ldi	r25, 0x18	; 24
+    1f06:	91 bd       	out	0x21, r25	; 33
   WDTCSR = x;
-    1f2e:	81 bd       	out	0x21, r24	; 33
+    1f08:	81 bd       	out	0x21, r24	; 33
 }
-    1f30:	08 95       	ret
+    1f0a:	08 95       	ret
 
-00001f32 <verifySpace>:
+00001f0c <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    1f32:	e8 df       	rcall	.-48     	; 0x1f04 <getch>
-    1f34:	80 32       	cpi	r24, 0x20	; 32
-    1f36:	19 f0       	breq	.+6      	; 0x1f3e <verifySpace+0xc>
+    1f0c:	e8 df       	rcall	.-48     	; 0x1ede <getch>
+    1f0e:	80 32       	cpi	r24, 0x20	; 32
+    1f10:	19 f0       	breq	.+6      	; 0x1f18 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    1f38:	88 e0       	ldi	r24, 0x08	; 8
-    1f3a:	f7 df       	rcall	.-18     	; 0x1f2a <watchdogConfig>
-    1f3c:	ff cf       	rjmp	.-2      	; 0x1f3c <verifySpace+0xa>
+    1f12:	88 e0       	ldi	r24, 0x08	; 8
+    1f14:	f7 df       	rcall	.-18     	; 0x1f04 <watchdogConfig>
+    1f16:	ff cf       	rjmp	.-2      	; 0x1f16 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    1f3e:	84 e1       	ldi	r24, 0x14	; 20
+    1f18:	84 e1       	ldi	r24, 0x14	; 20
 }
-    1f40:	d2 cf       	rjmp	.-92     	; 0x1ee6 <putch>
-
-00001f42 <getNch>:
+    1f1a:	d2 cf       	rjmp	.-92     	; 0x1ec0 <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    1f42:	1f 93       	push	r17
-    1f44:	18 2f       	mov	r17, r24
+    1f1c:	1f 93       	push	r17
+
+00001f1e <getNch>:
+    1f1e:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    1f46:	de df       	rcall	.-68     	; 0x1f04 <getch>
-    1f48:	11 50       	subi	r17, 0x01	; 1
-    1f4a:	e9 f7       	brne	.-6      	; 0x1f46 <getNch+0x4>
+    1f20:	de df       	rcall	.-68     	; 0x1ede <getch>
+    1f22:	11 50       	subi	r17, 0x01	; 1
+    1f24:	e9 f7       	brne	.-6      	; 0x1f20 <getNch+0x2>
   verifySpace();
-    1f4c:	f2 df       	rcall	.-28     	; 0x1f32 <verifySpace>
+    1f26:	f2 df       	rcall	.-28     	; 0x1f0c <verifySpace>
 }
-    1f4e:	1f 91       	pop	r17
-    1f50:	08 95       	ret
+    1f28:	1f 91       	pop	r17
+    1f2a:	08 95       	ret
 
-00001f52 <appStart>:
+00001f2c <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    1f52:	28 2e       	mov	r2, r24
+    1f2c:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    1f54:	80 e0       	ldi	r24, 0x00	; 0
-    1f56:	e9 df       	rcall	.-46     	; 0x1f2a <watchdogConfig>
+    1f2e:	80 e0       	ldi	r24, 0x00	; 0
+    1f30:	e9 df       	rcall	.-46     	; 0x1f04 <watchdogConfig>
   __asm__ __volatile__ (
-    1f58:	e4 e0       	ldi	r30, 0x04	; 4
-    1f5a:	ff 27       	eor	r31, r31
-    1f5c:	09 94       	ijmp
+    1f32:	e4 e0       	ldi	r30, 0x04	; 4
+    1f34:	ff 27       	eor	r31, r31
+    1f36:	09 94       	ijmp

+ 28 - 30
optiboot/bootloaders/optiboot/optiboot_pro_16MHz.hex

@@ -1,35 +1,33 @@
-:103E0000112494B714BE892F8D7011F0892FEED034
+:103E0000112494B714BE892F8D7011F0892FDDD045
 :103E100085E08093810082E08093C00088E18093F8
 :103E2000C10086E08093C20080E18093C4008EE0F0
-:103E3000C7D0259A86E020E33CEF91E030938500DF
+:103E3000B6D0259A86E020E33CEF91E030938500F0
 :103E40002093840096BBB09BFECF1D9AA89581500D
-:103E5000A9F7AA24BB2433E0832E7724739425E0AA
-:103E6000922E91E1C92EA0D0813469F49DD0182FF3
-:103E7000ADD0123811F481E004C0113809F482C0C9
-:103E800083E08AD086C0823411F484E103C0853493
-:103E900019F485E0A3D07DC0853579F485D0E82E6E
-:103EA000FF2482D0082F10E0102F00270E291F2991
-:103EB000000F111F8BD058016CC0863521F484E0AF
-:103EC0008DD080E0DECF843609F041C06DD090E027
-:103ED000182F002769D090E0082B192B65D0D82E19
-:103EE000E801E12CF1E0FF2E5FD0F70181937F0123
-:103EF0002197D1F76BD0F5E4DF1609F4FFCFF50178
-:103F000087BEE89507B600FCFDCFB501A801A0E08B
-:103F1000B1E02C9130E011968C91119790E0982FA0
-:103F20008827822B932B1296FB010C0177BEE89514
-:103F300011246E5F7F4F4250504059F7F50197BEF4
-:103F4000E89507B600FCFDCFC7BEE89522C08437D0
-:103F500091F42AD090E0D82FCC2726D090E0C82B1F
-:103F6000D92B22D033D08501F80185918F0114D04F
-:103F70002197D1F70EC0853739F428D08EE10CD0C7
-:103F800084E90AD086E07DCF813511F488E018D02D
-:103F90001DD080E101D067CF982F8091C00085FFB0
-:103FA000FCCF9093C60008958091C00087FFFCCF9E
-:103FB0008091C00084FD01C0A8958091C60008953D
-:103FC000E0E6F0E098E1908380830895EDDF8032B1
-:103FD00019F088E0F5DFFFCF84E1DECF1F93182FC3
-:103FE000E3DF1150E9F7F2DF1F910895282E80E0FA
-:083FF000E7DFEE27FF2709942B
-:023FFE000106BA
+:103E5000A9F7EE24FF24B3E0AB2EBB24B394A5E076
+:103E6000DA2EF1E1CF2E8FD0813469F48CD0082F77
+:103E70009CD0023811F482E004C0013809F471C00A
+:103E800083E079D075C0823411F484E103C08534B5
+:103E900019F485E092D06CC0853579F474D0E82EA1
+:103EA000FF2471D0082F10E0102F00270E291F29A2
+:103EB000000F111F7AD078015BC0863521F484E0B1
+:103EC0007CD080E0DECF843609F035C05CD05BD09A
+:103ED000182F59D0082FC0E0D1E055D089931C1776
+:103EE000E1F763D0053409F4FFCFF701A7BEE895E9
+:103EF00007B600FCFDCFA701A0E0B1E02C9130E0B7
+:103F000011968C91119790E0982F8827822B932BF4
+:103F10001296FA010C01B7BEE89511244E5F5F4F6F
+:103F20001A1761F7F701D7BEE89507B600FCFDCF79
+:103F3000C7BEE8951DC0843769F425D024D0082F6A
+:103F400022D033D0E701FE018591EF0114D001505A
+:103F5000D1F70EC0853739F428D08EE10CD084E932
+:103F60000AD086E08ECF813511F488E018D01DD0BC
+:103F700080E101D078CF982F8091C00085FFFCCFE1
+:103F80009093C60008958091C00087FFFCCF809178
+:103F9000C00084FD01C0A8958091C6000895E0E6A8
+:103FA000F0E098E1908380830895EDDF803219F08E
+:103FB00088E0F5DFFFCF84E1DECF1F93182FE3DF2A
+:103FC0001150E9F7F2DF1F910895282E80E0E7DF16
+:063FD000EE27FF27099413
+:023FFE000206B9
 :0400000300003E00BB
 :00000001FF

+ 180 - 198
optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst

@@ -3,27 +3,27 @@ optiboot_atmega168.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f8  00003e00  00003e00  00000074  2**1
+  0 .text         000001d6  00003e00  00003e00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000026c  2**0
+  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000026e  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000296  2**0
+  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003e0  00000000  00000000  0000030a  2**0
+  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001f1  00000000  00000000  000006ea  2**0
+  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000433  00000000  00000000  000008db  2**0
+  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000d10  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000172  00000000  00000000  00000d90  2**0
+  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d7  00000000  00000000  00000f02  2**0
+  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011d9  2**0
+ 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -51,7 +51,7 @@ int main(void) {
     3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
       appStart(ch);
     3e0c:	89 2f       	mov	r24, r25
-    3e0e:	ee d0       	rcall	.+476    	; 0x3fec <appStart>
+    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -81,7 +81,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	c7 d0       	rcall	.+398    	; 0x3fc0 <watchdogConfig>
+    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
 
 #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
   /* Set LED pin as output */
@@ -131,68 +131,68 @@ void watchdogReset() {
   } while (--count);
     3e4e:	81 50       	subi	r24, 0x01	; 1
     3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	aa 24       	eor	r10, r10
-    3e54:	bb 24       	eor	r11, r11
+    3e52:	ee 24       	eor	r14, r14
+    3e54:	ff 24       	eor	r15, r15
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	33 e0       	ldi	r19, 0x03	; 3
-    3e58:	83 2e       	mov	r8, r19
+    3e56:	b3 e0       	ldi	r27, 0x03	; 3
+    3e58:	ab 2e       	mov	r10, r27
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	77 24       	eor	r7, r7
-    3e5c:	73 94       	inc	r7
+    3e5a:	bb 24       	eor	r11, r11
+    3e5c:	b3 94       	inc	r11
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	25 e0       	ldi	r18, 0x05	; 5
-    3e60:	92 2e       	mov	r9, r18
+    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
+    3e60:	da 2e       	mov	r13, r26
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3e62:	91 e1       	ldi	r25, 0x11	; 17
-    3e64:	c9 2e       	mov	r12, r25
+    3e62:	f1 e1       	ldi	r31, 0x11	; 17
+    3e64:	cf 2e       	mov	r12, r31
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e66:	a0 d0       	rcall	.+320    	; 0x3fa8 <getch>
+    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e68:	81 34       	cpi	r24, 0x41	; 65
     3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
       unsigned char which = getch();
-    3e6c:	9d d0       	rcall	.+314    	; 0x3fa8 <getch>
-    3e6e:	18 2f       	mov	r17, r24
+    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
+    3e6e:	08 2f       	mov	r16, r24
       verifySpace();
-    3e70:	ad d0       	rcall	.+346    	; 0x3fcc <verifySpace>
+    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
       if (which == 0x82) {
-    3e72:	12 38       	cpi	r17, 0x82	; 130
+    3e72:	02 38       	cpi	r16, 0x82	; 130
     3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(optiboot_version & 0xFF);
-    3e76:	81 e0       	ldi	r24, 0x01	; 1
+    3e76:	82 e0       	ldi	r24, 0x02	; 2
     3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
       } else if (which == 0x81) {
-    3e7a:	11 38       	cpi	r17, 0x81	; 129
+    3e7a:	01 38       	cpi	r16, 0x81	; 129
     3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	82 c0       	rjmp	.+260    	; 0x3f84 <main+0x184>
+    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
@@ -200,8 +200,8 @@ void watchdogReset() {
 	 */
 	putch(0x03);
     3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	8a d0       	rcall	.+276    	; 0x3f98 <putch>
-    3e84:	86 c0       	rjmp	.+268    	; 0x3f92 <main+0x192>
+    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
+    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
       }
     }
     else if(ch == STK_SET_DEVICE) {
@@ -218,8 +218,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	a3 d0       	rcall	.+326    	; 0x3fdc <getNch>
-    3e96:	7d c0       	rjmp	.+250    	; 0x3f92 <main+0x192>
+    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
+    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e98:	85 35       	cpi	r24, 0x55	; 85
@@ -227,11 +227,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e9c:	85 d0       	rcall	.+266    	; 0x3fa8 <getch>
+    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e9e:	e8 2e       	mov	r14, r24
     3ea0:	ff 24       	eor	r15, r15
-    3ea2:	82 d0       	rcall	.+260    	; 0x3fa8 <getch>
+    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
     3ea4:	08 2f       	mov	r16, r24
     3ea6:	10 e0       	ldi	r17, 0x00	; 0
     3ea8:	10 2f       	mov	r17, r16
@@ -247,9 +247,9 @@ void watchdogReset() {
     3eb2:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eb4:	8b d0       	rcall	.+278    	; 0x3fcc <verifySpace>
-    3eb6:	58 01       	movw	r10, r16
-    3eb8:	6c c0       	rjmp	.+216    	; 0x3f92 <main+0x192>
+    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
+    3eb6:	78 01       	movw	r14, r16
+    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_UNIVERSAL) {
     3eba:	86 35       	cpi	r24, 0x56	; 86
@@ -257,7 +257,7 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	8d d0       	rcall	.+282    	; 0x3fdc <getNch>
+    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
       putch(0x00);
     3ec2:	80 e0       	ldi	r24, 0x00	; 0
     3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
@@ -266,339 +266,321 @@ void watchdogReset() {
     else if(ch == STK_PROG_PAGE) {
     3ec6:	84 36       	cpi	r24, 0x64	; 100
     3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	41 c0       	rjmp	.+130    	; 0x3f4e <main+0x14e>
+    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
-    3ecc:	6d d0       	rcall	.+218    	; 0x3fa8 <getch>
-    3ece:	90 e0       	ldi	r25, 0x00	; 0
+      GETLENGTH(length);
+    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
+    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
     3ed0:	18 2f       	mov	r17, r24
-    3ed2:	00 27       	eor	r16, r16
-      length |= getch();
-    3ed4:	69 d0       	rcall	.+210    	; 0x3fa8 <getch>
-    3ed6:	90 e0       	ldi	r25, 0x00	; 0
-    3ed8:	08 2b       	or	r16, r24
-    3eda:	19 2b       	or	r17, r25
       savelength = length;
       desttype = getch();
-    3edc:	65 d0       	rcall	.+202    	; 0x3fa8 <getch>
-    3ede:	d8 2e       	mov	r13, r24
-    3ee0:	e8 01       	movw	r28, r16
-    3ee2:	e1 2c       	mov	r14, r1
-    3ee4:	f1 e0       	ldi	r31, 0x01	; 1
-    3ee6:	ff 2e       	mov	r15, r31
+    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
+    3ed4:	08 2f       	mov	r16, r24
+    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
 
       // read a page worth of contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee8:	5f d0       	rcall	.+190    	; 0x3fa8 <getch>
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	81 93       	st	Z+, r24
-    3eee:	7f 01       	movw	r14, r30
+    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
+    3edc:	89 93       	st	Y+, r24
       while (--length);
-    3ef0:	21 97       	sbiw	r28, 0x01	; 1
-    3ef2:	d1 f7       	brne	.-12     	; 0x3ee8 <main+0xe8>
+    3ede:	1c 17       	cp	r17, r28
+    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
 
       // Read command terminator, start reply
       verifySpace();
-    3ef4:	6b d0       	rcall	.+214    	; 0x3fcc <verifySpace>
+    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
-    3ef6:	f5 e4       	ldi	r31, 0x45	; 69
-    3ef8:	df 16       	cp	r13, r31
-    3efa:	09 f4       	brne	.+2      	; 0x3efe <main+0xfe>
-    3efc:	ff cf       	rjmp	.-2      	; 0x3efc <main+0xfc>
+    3ee4:	05 34       	cpi	r16, 0x45	; 69
+    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
+    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3efe:	f5 01       	movw	r30, r10
-    3f00:	87 be       	out	0x37, r8	; 55
-    3f02:	e8 95       	spm
+    3eea:	f7 01       	movw	r30, r14
+    3eec:	a7 be       	out	0x37, r10	; 55
+    3eee:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f04:	07 b6       	in	r0, 0x37	; 55
-    3f06:	00 fc       	sbrc	r0, 0
-    3f08:	fd cf       	rjmp	.-6      	; 0x3f04 <main+0x104>
-    3f0a:	b5 01       	movw	r22, r10
-    3f0c:	a8 01       	movw	r20, r16
-    3f0e:	a0 e0       	ldi	r26, 0x00	; 0
-    3f10:	b1 e0       	ldi	r27, 0x01	; 1
+    3ef0:	07 b6       	in	r0, 0x37	; 55
+    3ef2:	00 fc       	sbrc	r0, 0
+    3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
+    3ef6:	a7 01       	movw	r20, r14
+    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
+    3efa:	b1 e0       	ldi	r27, 0x01	; 1
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
-    3f12:	2c 91       	ld	r18, X
-    3f14:	30 e0       	ldi	r19, 0x00	; 0
+    3efc:	2c 91       	ld	r18, X
+    3efe:	30 e0       	ldi	r19, 0x00	; 0
 		a |= (*bufPtr++) << 8;
-    3f16:	11 96       	adiw	r26, 0x01	; 1
-    3f18:	8c 91       	ld	r24, X
-    3f1a:	11 97       	sbiw	r26, 0x01	; 1
-    3f1c:	90 e0       	ldi	r25, 0x00	; 0
-    3f1e:	98 2f       	mov	r25, r24
-    3f20:	88 27       	eor	r24, r24
-    3f22:	82 2b       	or	r24, r18
-    3f24:	93 2b       	or	r25, r19
+    3f00:	11 96       	adiw	r26, 0x01	; 1
+    3f02:	8c 91       	ld	r24, X
+    3f04:	11 97       	sbiw	r26, 0x01	; 1
+    3f06:	90 e0       	ldi	r25, 0x00	; 0
+    3f08:	98 2f       	mov	r25, r24
+    3f0a:	88 27       	eor	r24, r24
+    3f0c:	82 2b       	or	r24, r18
+    3f0e:	93 2b       	or	r25, r19
 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
 
 /* main program starts here */
 int main(void) {
-    3f26:	12 96       	adiw	r26, 0x02	; 2
+    3f10:	12 96       	adiw	r26, 0x02	; 2
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f28:	fb 01       	movw	r30, r22
-    3f2a:	0c 01       	movw	r0, r24
-    3f2c:	77 be       	out	0x37, r7	; 55
-    3f2e:	e8 95       	spm
-    3f30:	11 24       	eor	r1, r1
+    3f12:	fa 01       	movw	r30, r20
+    3f14:	0c 01       	movw	r0, r24
+    3f16:	b7 be       	out	0x37, r11	; 55
+    3f18:	e8 95       	spm
+    3f1a:	11 24       	eor	r1, r1
 		addrPtr += 2;
-    3f32:	6e 5f       	subi	r22, 0xFE	; 254
-    3f34:	7f 4f       	sbci	r23, 0xFF	; 255
+    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
+    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    3f36:	42 50       	subi	r20, 0x02	; 2
-    3f38:	50 40       	sbci	r21, 0x00	; 0
-    3f3a:	59 f7       	brne	.-42     	; 0x3f12 <main+0x112>
+    3f20:	1a 17       	cp	r17, r26
+    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3f3c:	f5 01       	movw	r30, r10
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
+    3f24:	f7 01       	movw	r30, r14
+    3f26:	d7 be       	out	0x37, r13	; 55
+    3f28:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f42:	07 b6       	in	r0, 0x37	; 55
-    3f44:	00 fc       	sbrc	r0, 0
-    3f46:	fd cf       	rjmp	.-6      	; 0x3f42 <main+0x142>
+    3f2a:	07 b6       	in	r0, 0x37	; 55
+    3f2c:	00 fc       	sbrc	r0, 0
+    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3f48:	c7 be       	out	0x37, r12	; 55
-    3f4a:	e8 95       	spm
-    3f4c:	22 c0       	rjmp	.+68     	; 0x3f92 <main+0x192>
+    3f30:	c7 be       	out	0x37, r12	; 55
+    3f32:	e8 95       	spm
+    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f4e:	84 37       	cpi	r24, 0x74	; 116
-    3f50:	91 f4       	brne	.+36     	; 0x3f76 <main+0x176>
+    3f36:	84 37       	cpi	r24, 0x74	; 116
+    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
-    3f52:	2a d0       	rcall	.+84     	; 0x3fa8 <getch>
-    3f54:	90 e0       	ldi	r25, 0x00	; 0
-    3f56:	d8 2f       	mov	r29, r24
-    3f58:	cc 27       	eor	r28, r28
-      length |= getch();
-    3f5a:	26 d0       	rcall	.+76     	; 0x3fa8 <getch>
-    3f5c:	90 e0       	ldi	r25, 0x00	; 0
-    3f5e:	c8 2b       	or	r28, r24
-    3f60:	d9 2b       	or	r29, r25
+      GETLENGTH(length);
+    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
+    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
+    3f3e:	08 2f       	mov	r16, r24
+
       desttype = getch();
-    3f62:	22 d0       	rcall	.+68     	; 0x3fa8 <getch>
+    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
 
       verifySpace();
-    3f64:	33 d0       	rcall	.+102    	; 0x3fcc <verifySpace>
-    3f66:	85 01       	movw	r16, r10
+    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
+    3f44:	e7 01       	movw	r28, r14
 	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
 	    // read a Flash byte and increment the address
 	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
 	    putch(ch);
-    3f68:	f8 01       	movw	r30, r16
-    3f6a:	85 91       	lpm	r24, Z+
-    3f6c:	8f 01       	movw	r16, r30
-    3f6e:	14 d0       	rcall	.+40     	; 0x3f98 <putch>
+    3f46:	fe 01       	movw	r30, r28
+    3f48:	85 91       	lpm	r24, Z+
+    3f4a:	ef 01       	movw	r28, r30
+    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
 	} while (--length);
-    3f70:	21 97       	sbiw	r28, 0x01	; 1
-    3f72:	d1 f7       	brne	.-12     	; 0x3f68 <main+0x168>
-    3f74:	0e c0       	rjmp	.+28     	; 0x3f92 <main+0x192>
+    3f4e:	01 50       	subi	r16, 0x01	; 1
+    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
+    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
 	  
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f76:	85 37       	cpi	r24, 0x75	; 117
-    3f78:	39 f4       	brne	.+14     	; 0x3f88 <main+0x188>
+    3f54:	85 37       	cpi	r24, 0x75	; 117
+    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f7a:	28 d0       	rcall	.+80     	; 0x3fcc <verifySpace>
+    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
       putch(SIGNATURE_0);
-    3f7c:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7e:	0c d0       	rcall	.+24     	; 0x3f98 <putch>
+    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
+    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
       putch(SIGNATURE_1);
-    3f80:	84 e9       	ldi	r24, 0x94	; 148
-    3f82:	0a d0       	rcall	.+20     	; 0x3f98 <putch>
+    3f5e:	84 e9       	ldi	r24, 0x94	; 148
+    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
       putch(SIGNATURE_2);
-    3f84:	86 e0       	ldi	r24, 0x06	; 6
-    3f86:	7d cf       	rjmp	.-262    	; 0x3e82 <main+0x82>
+    3f62:	86 e0       	ldi	r24, 0x06	; 6
+    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f88:	81 35       	cpi	r24, 0x51	; 81
-    3f8a:	11 f4       	brne	.+4      	; 0x3f90 <main+0x190>
+    3f66:	81 35       	cpi	r24, 0x51	; 81
+    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8c:	88 e0       	ldi	r24, 0x08	; 8
-    3f8e:	18 d0       	rcall	.+48     	; 0x3fc0 <watchdogConfig>
+    3f6a:	88 e0       	ldi	r24, 0x08	; 8
+    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f90:	1d d0       	rcall	.+58     	; 0x3fcc <verifySpace>
+    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
     }
     putch(STK_OK);
-    3f92:	80 e1       	ldi	r24, 0x10	; 16
-    3f94:	01 d0       	rcall	.+2      	; 0x3f98 <putch>
-    3f96:	67 cf       	rjmp	.-306    	; 0x3e66 <main+0x66>
+    3f70:	80 e1       	ldi	r24, 0x10	; 16
+    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
+    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
 
-00003f98 <putch>:
+00003f76 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f98:	98 2f       	mov	r25, r24
+    3f76:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    3f9a:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9e:	85 ff       	sbrs	r24, 5
-    3fa0:	fc cf       	rjmp	.-8      	; 0x3f9a <putch+0x2>
+    3f78:	80 91 c0 00 	lds	r24, 0x00C0
+    3f7c:	85 ff       	sbrs	r24, 5
+    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
   UART_UDR = ch;
-    3fa2:	90 93 c6 00 	sts	0x00C6, r25
+    3f80:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa6:	08 95       	ret
+    3f84:	08 95       	ret
 
-00003fa8 <getch>:
+00003f86 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    3fa8:	80 91 c0 00 	lds	r24, 0x00C0
-    3fac:	87 ff       	sbrs	r24, 7
-    3fae:	fc cf       	rjmp	.-8      	; 0x3fa8 <getch>
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	87 ff       	sbrs	r24, 7
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb4:	84 fd       	sbrc	r24, 4
-    3fb6:	01 c0       	rjmp	.+2      	; 0x3fba <getch+0x12>
+    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
+    3f92:	84 fd       	sbrc	r24, 4
+    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb8:	a8 95       	wdr
+    3f96:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
   ch = UART_UDR;
-    3fba:	80 91 c6 00 	lds	r24, 0x00C6
+    3f98:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbe:	08 95       	ret
+    3f9c:	08 95       	ret
 
-00003fc0 <watchdogConfig>:
+00003f9e <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fc0:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc2:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc4:	98 e1       	ldi	r25, 0x18	; 24
-    3fc6:	90 83       	st	Z, r25
+    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
+    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
+    3fa2:	98 e1       	ldi	r25, 0x18	; 24
+    3fa4:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc8:	80 83       	st	Z, r24
+    3fa6:	80 83       	st	Z, r24
 }
-    3fca:	08 95       	ret
+    3fa8:	08 95       	ret
 
-00003fcc <verifySpace>:
+00003faa <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fcc:	ed df       	rcall	.-38     	; 0x3fa8 <getch>
-    3fce:	80 32       	cpi	r24, 0x20	; 32
-    3fd0:	19 f0       	breq	.+6      	; 0x3fd8 <verifySpace+0xc>
+    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
+    3fac:	80 32       	cpi	r24, 0x20	; 32
+    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd2:	88 e0       	ldi	r24, 0x08	; 8
-    3fd4:	f5 df       	rcall	.-22     	; 0x3fc0 <watchdogConfig>
-    3fd6:	ff cf       	rjmp	.-2      	; 0x3fd6 <verifySpace+0xa>
+    3fb0:	88 e0       	ldi	r24, 0x08	; 8
+    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
+    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd8:	84 e1       	ldi	r24, 0x14	; 20
+    3fb6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fda:	de cf       	rjmp	.-68     	; 0x3f98 <putch>
+    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
 
-00003fdc <getNch>:
+00003fba <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fdc:	1f 93       	push	r17
-    3fde:	18 2f       	mov	r17, r24
+    3fba:	1f 93       	push	r17
+    3fbc:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fe0:	e3 df       	rcall	.-58     	; 0x3fa8 <getch>
-    3fe2:	11 50       	subi	r17, 0x01	; 1
-    3fe4:	e9 f7       	brne	.-6      	; 0x3fe0 <getNch+0x4>
+    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
+    3fc0:	11 50       	subi	r17, 0x01	; 1
+    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
   verifySpace();
-    3fe6:	f2 df       	rcall	.-28     	; 0x3fcc <verifySpace>
+    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
 }
-    3fe8:	1f 91       	pop	r17
-    3fea:	08 95       	ret
+    3fc6:	1f 91       	pop	r17
+    3fc8:	08 95       	ret
 
-00003fec <appStart>:
+00003fca <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fec:	28 2e       	mov	r2, r24
+    3fca:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    3fee:	80 e0       	ldi	r24, 0x00	; 0
-    3ff0:	e7 df       	rcall	.-50     	; 0x3fc0 <watchdogConfig>
+    3fcc:	80 e0       	ldi	r24, 0x00	; 0
+    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
   __asm__ __volatile__ (
-    3ff2:	ee 27       	eor	r30, r30
-    3ff4:	ff 27       	eor	r31, r31
-    3ff6:	09 94       	ijmp
+    3fd0:	ee 27       	eor	r30, r30
+    3fd2:	ff 27       	eor	r31, r31
+    3fd4:	09 94       	ijmp

+ 28 - 30
optiboot/bootloaders/optiboot/optiboot_pro_20mhz.hex

@@ -1,35 +1,33 @@
-:103E0000112494B714BE892F8D7011F0892FEED034
+:103E0000112494B714BE892F8D7011F0892FDDD045
 :103E100085E08093810082E08093C00088E18093F8
 :103E2000C10086E08093C20085E18093C4008EE0EB
-:103E3000C7D0259A86E02CE33BEF91E030938500D4
+:103E3000B6D0259A86E02CE33BEF91E030938500E5
 :103E40002093840096BBB09BFECF1D9AA89581500D
-:103E5000A9F7AA24BB2433E0832E7724739425E0AA
-:103E6000922E91E1C92EA0D0813469F49DD0182FF3
-:103E7000ADD0123811F481E004C0113809F482C0C9
-:103E800083E08AD086C0823411F484E103C0853493
-:103E900019F485E0A3D07DC0853579F485D0E82E6E
-:103EA000FF2482D0082F10E0102F00270E291F2991
-:103EB000000F111F8BD058016CC0863521F484E0AF
-:103EC0008DD080E0DECF843609F041C06DD090E027
-:103ED000182F002769D090E0082B192B65D0D82E19
-:103EE000E801E12CF1E0FF2E5FD0F70181937F0123
-:103EF0002197D1F76BD0F5E4DF1609F4FFCFF50178
-:103F000087BEE89507B600FCFDCFB501A801A0E08B
-:103F1000B1E02C9130E011968C91119790E0982FA0
-:103F20008827822B932B1296FB010C0177BEE89514
-:103F300011246E5F7F4F4250504059F7F50197BEF4
-:103F4000E89507B600FCFDCFC7BEE89522C08437D0
-:103F500091F42AD090E0D82FCC2726D090E0C82B1F
-:103F6000D92B22D033D08501F80185918F0114D04F
-:103F70002197D1F70EC0853739F428D08EE10CD0C7
-:103F800084E90AD086E07DCF813511F488E018D02D
-:103F90001DD080E101D067CF982F8091C00085FFB0
-:103FA000FCCF9093C60008958091C00087FFFCCF9E
-:103FB0008091C00084FD01C0A8958091C60008953D
-:103FC000E0E6F0E098E1908380830895EDDF8032B1
-:103FD00019F088E0F5DFFFCF84E1DECF1F93182FC3
-:103FE000E3DF1150E9F7F2DF1F910895282E80E0FA
-:083FF000E7DFEE27FF2709942B
-:023FFE000106BA
+:103E5000A9F7EE24FF24B3E0AB2EBB24B394A5E076
+:103E6000DA2EF1E1CF2E8FD0813469F48CD0082F77
+:103E70009CD0023811F482E004C0013809F471C00A
+:103E800083E079D075C0823411F484E103C08534B5
+:103E900019F485E092D06CC0853579F474D0E82EA1
+:103EA000FF2471D0082F10E0102F00270E291F29A2
+:103EB000000F111F7AD078015BC0863521F484E0B1
+:103EC0007CD080E0DECF843609F035C05CD05BD09A
+:103ED000182F59D0082FC0E0D1E055D089931C1776
+:103EE000E1F763D0053409F4FFCFF701A7BEE895E9
+:103EF00007B600FCFDCFA701A0E0B1E02C9130E0B7
+:103F000011968C91119790E0982F8827822B932BF4
+:103F10001296FA010C01B7BEE89511244E5F5F4F6F
+:103F20001A1761F7F701D7BEE89507B600FCFDCF79
+:103F3000C7BEE8951DC0843769F425D024D0082F6A
+:103F400022D033D0E701FE018591EF0114D001505A
+:103F5000D1F70EC0853739F428D08EE10CD084E932
+:103F60000AD086E08ECF813511F488E018D01DD0BC
+:103F700080E101D078CF982F8091C00085FFFCCFE1
+:103F80009093C60008958091C00087FFFCCF809178
+:103F9000C00084FD01C0A8958091C6000895E0E6A8
+:103FA000F0E098E1908380830895EDDF803219F08E
+:103FB00088E0F5DFFFCF84E1DECF1F93182FE3DF2A
+:103FC0001150E9F7F2DF1F910895282E80E0E7DF16
+:063FD000EE27FF27099413
+:023FFE000206B9
 :0400000300003E00BB
 :00000001FF

+ 180 - 198
optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst

@@ -3,27 +3,27 @@ optiboot_atmega168.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f8  00003e00  00003e00  00000074  2**1
+  0 .text         000001d6  00003e00  00003e00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000026c  2**0
+  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000026e  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000296  2**0
+  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003e0  00000000  00000000  0000030a  2**0
+  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001f1  00000000  00000000  000006ea  2**0
+  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000433  00000000  00000000  000008db  2**0
+  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000d10  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000172  00000000  00000000  00000d90  2**0
+  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d7  00000000  00000000  00000f02  2**0
+  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011d9  2**0
+ 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -51,7 +51,7 @@ int main(void) {
     3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
       appStart(ch);
     3e0c:	89 2f       	mov	r24, r25
-    3e0e:	ee d0       	rcall	.+476    	; 0x3fec <appStart>
+    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -81,7 +81,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	c7 d0       	rcall	.+398    	; 0x3fc0 <watchdogConfig>
+    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
 
 #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
   /* Set LED pin as output */
@@ -131,68 +131,68 @@ void watchdogReset() {
   } while (--count);
     3e4e:	81 50       	subi	r24, 0x01	; 1
     3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	aa 24       	eor	r10, r10
-    3e54:	bb 24       	eor	r11, r11
+    3e52:	ee 24       	eor	r14, r14
+    3e54:	ff 24       	eor	r15, r15
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	33 e0       	ldi	r19, 0x03	; 3
-    3e58:	83 2e       	mov	r8, r19
+    3e56:	b3 e0       	ldi	r27, 0x03	; 3
+    3e58:	ab 2e       	mov	r10, r27
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	77 24       	eor	r7, r7
-    3e5c:	73 94       	inc	r7
+    3e5a:	bb 24       	eor	r11, r11
+    3e5c:	b3 94       	inc	r11
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	25 e0       	ldi	r18, 0x05	; 5
-    3e60:	92 2e       	mov	r9, r18
+    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
+    3e60:	da 2e       	mov	r13, r26
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3e62:	91 e1       	ldi	r25, 0x11	; 17
-    3e64:	c9 2e       	mov	r12, r25
+    3e62:	f1 e1       	ldi	r31, 0x11	; 17
+    3e64:	cf 2e       	mov	r12, r31
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e66:	a0 d0       	rcall	.+320    	; 0x3fa8 <getch>
+    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e68:	81 34       	cpi	r24, 0x41	; 65
     3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
       unsigned char which = getch();
-    3e6c:	9d d0       	rcall	.+314    	; 0x3fa8 <getch>
-    3e6e:	18 2f       	mov	r17, r24
+    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
+    3e6e:	08 2f       	mov	r16, r24
       verifySpace();
-    3e70:	ad d0       	rcall	.+346    	; 0x3fcc <verifySpace>
+    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
       if (which == 0x82) {
-    3e72:	12 38       	cpi	r17, 0x82	; 130
+    3e72:	02 38       	cpi	r16, 0x82	; 130
     3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(optiboot_version & 0xFF);
-    3e76:	81 e0       	ldi	r24, 0x01	; 1
+    3e76:	82 e0       	ldi	r24, 0x02	; 2
     3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
       } else if (which == 0x81) {
-    3e7a:	11 38       	cpi	r17, 0x81	; 129
+    3e7a:	01 38       	cpi	r16, 0x81	; 129
     3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	82 c0       	rjmp	.+260    	; 0x3f84 <main+0x184>
+    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
@@ -200,8 +200,8 @@ void watchdogReset() {
 	 */
 	putch(0x03);
     3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	8a d0       	rcall	.+276    	; 0x3f98 <putch>
-    3e84:	86 c0       	rjmp	.+268    	; 0x3f92 <main+0x192>
+    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
+    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
       }
     }
     else if(ch == STK_SET_DEVICE) {
@@ -218,8 +218,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	a3 d0       	rcall	.+326    	; 0x3fdc <getNch>
-    3e96:	7d c0       	rjmp	.+250    	; 0x3f92 <main+0x192>
+    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
+    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e98:	85 35       	cpi	r24, 0x55	; 85
@@ -227,11 +227,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e9c:	85 d0       	rcall	.+266    	; 0x3fa8 <getch>
+    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e9e:	e8 2e       	mov	r14, r24
     3ea0:	ff 24       	eor	r15, r15
-    3ea2:	82 d0       	rcall	.+260    	; 0x3fa8 <getch>
+    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
     3ea4:	08 2f       	mov	r16, r24
     3ea6:	10 e0       	ldi	r17, 0x00	; 0
     3ea8:	10 2f       	mov	r17, r16
@@ -247,9 +247,9 @@ void watchdogReset() {
     3eb2:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eb4:	8b d0       	rcall	.+278    	; 0x3fcc <verifySpace>
-    3eb6:	58 01       	movw	r10, r16
-    3eb8:	6c c0       	rjmp	.+216    	; 0x3f92 <main+0x192>
+    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
+    3eb6:	78 01       	movw	r14, r16
+    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_UNIVERSAL) {
     3eba:	86 35       	cpi	r24, 0x56	; 86
@@ -257,7 +257,7 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	8d d0       	rcall	.+282    	; 0x3fdc <getNch>
+    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
       putch(0x00);
     3ec2:	80 e0       	ldi	r24, 0x00	; 0
     3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
@@ -266,339 +266,321 @@ void watchdogReset() {
     else if(ch == STK_PROG_PAGE) {
     3ec6:	84 36       	cpi	r24, 0x64	; 100
     3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	41 c0       	rjmp	.+130    	; 0x3f4e <main+0x14e>
+    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
-    3ecc:	6d d0       	rcall	.+218    	; 0x3fa8 <getch>
-    3ece:	90 e0       	ldi	r25, 0x00	; 0
+      GETLENGTH(length);
+    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
+    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
     3ed0:	18 2f       	mov	r17, r24
-    3ed2:	00 27       	eor	r16, r16
-      length |= getch();
-    3ed4:	69 d0       	rcall	.+210    	; 0x3fa8 <getch>
-    3ed6:	90 e0       	ldi	r25, 0x00	; 0
-    3ed8:	08 2b       	or	r16, r24
-    3eda:	19 2b       	or	r17, r25
       savelength = length;
       desttype = getch();
-    3edc:	65 d0       	rcall	.+202    	; 0x3fa8 <getch>
-    3ede:	d8 2e       	mov	r13, r24
-    3ee0:	e8 01       	movw	r28, r16
-    3ee2:	e1 2c       	mov	r14, r1
-    3ee4:	f1 e0       	ldi	r31, 0x01	; 1
-    3ee6:	ff 2e       	mov	r15, r31
+    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
+    3ed4:	08 2f       	mov	r16, r24
+    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
 
       // read a page worth of contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee8:	5f d0       	rcall	.+190    	; 0x3fa8 <getch>
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	81 93       	st	Z+, r24
-    3eee:	7f 01       	movw	r14, r30
+    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
+    3edc:	89 93       	st	Y+, r24
       while (--length);
-    3ef0:	21 97       	sbiw	r28, 0x01	; 1
-    3ef2:	d1 f7       	brne	.-12     	; 0x3ee8 <main+0xe8>
+    3ede:	1c 17       	cp	r17, r28
+    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
 
       // Read command terminator, start reply
       verifySpace();
-    3ef4:	6b d0       	rcall	.+214    	; 0x3fcc <verifySpace>
+    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
-    3ef6:	f5 e4       	ldi	r31, 0x45	; 69
-    3ef8:	df 16       	cp	r13, r31
-    3efa:	09 f4       	brne	.+2      	; 0x3efe <main+0xfe>
-    3efc:	ff cf       	rjmp	.-2      	; 0x3efc <main+0xfc>
+    3ee4:	05 34       	cpi	r16, 0x45	; 69
+    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
+    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3efe:	f5 01       	movw	r30, r10
-    3f00:	87 be       	out	0x37, r8	; 55
-    3f02:	e8 95       	spm
+    3eea:	f7 01       	movw	r30, r14
+    3eec:	a7 be       	out	0x37, r10	; 55
+    3eee:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f04:	07 b6       	in	r0, 0x37	; 55
-    3f06:	00 fc       	sbrc	r0, 0
-    3f08:	fd cf       	rjmp	.-6      	; 0x3f04 <main+0x104>
-    3f0a:	b5 01       	movw	r22, r10
-    3f0c:	a8 01       	movw	r20, r16
-    3f0e:	a0 e0       	ldi	r26, 0x00	; 0
-    3f10:	b1 e0       	ldi	r27, 0x01	; 1
+    3ef0:	07 b6       	in	r0, 0x37	; 55
+    3ef2:	00 fc       	sbrc	r0, 0
+    3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
+    3ef6:	a7 01       	movw	r20, r14
+    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
+    3efa:	b1 e0       	ldi	r27, 0x01	; 1
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
-    3f12:	2c 91       	ld	r18, X
-    3f14:	30 e0       	ldi	r19, 0x00	; 0
+    3efc:	2c 91       	ld	r18, X
+    3efe:	30 e0       	ldi	r19, 0x00	; 0
 		a |= (*bufPtr++) << 8;
-    3f16:	11 96       	adiw	r26, 0x01	; 1
-    3f18:	8c 91       	ld	r24, X
-    3f1a:	11 97       	sbiw	r26, 0x01	; 1
-    3f1c:	90 e0       	ldi	r25, 0x00	; 0
-    3f1e:	98 2f       	mov	r25, r24
-    3f20:	88 27       	eor	r24, r24
-    3f22:	82 2b       	or	r24, r18
-    3f24:	93 2b       	or	r25, r19
+    3f00:	11 96       	adiw	r26, 0x01	; 1
+    3f02:	8c 91       	ld	r24, X
+    3f04:	11 97       	sbiw	r26, 0x01	; 1
+    3f06:	90 e0       	ldi	r25, 0x00	; 0
+    3f08:	98 2f       	mov	r25, r24
+    3f0a:	88 27       	eor	r24, r24
+    3f0c:	82 2b       	or	r24, r18
+    3f0e:	93 2b       	or	r25, r19
 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
 
 /* main program starts here */
 int main(void) {
-    3f26:	12 96       	adiw	r26, 0x02	; 2
+    3f10:	12 96       	adiw	r26, 0x02	; 2
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f28:	fb 01       	movw	r30, r22
-    3f2a:	0c 01       	movw	r0, r24
-    3f2c:	77 be       	out	0x37, r7	; 55
-    3f2e:	e8 95       	spm
-    3f30:	11 24       	eor	r1, r1
+    3f12:	fa 01       	movw	r30, r20
+    3f14:	0c 01       	movw	r0, r24
+    3f16:	b7 be       	out	0x37, r11	; 55
+    3f18:	e8 95       	spm
+    3f1a:	11 24       	eor	r1, r1
 		addrPtr += 2;
-    3f32:	6e 5f       	subi	r22, 0xFE	; 254
-    3f34:	7f 4f       	sbci	r23, 0xFF	; 255
+    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
+    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    3f36:	42 50       	subi	r20, 0x02	; 2
-    3f38:	50 40       	sbci	r21, 0x00	; 0
-    3f3a:	59 f7       	brne	.-42     	; 0x3f12 <main+0x112>
+    3f20:	1a 17       	cp	r17, r26
+    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3f3c:	f5 01       	movw	r30, r10
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
+    3f24:	f7 01       	movw	r30, r14
+    3f26:	d7 be       	out	0x37, r13	; 55
+    3f28:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f42:	07 b6       	in	r0, 0x37	; 55
-    3f44:	00 fc       	sbrc	r0, 0
-    3f46:	fd cf       	rjmp	.-6      	; 0x3f42 <main+0x142>
+    3f2a:	07 b6       	in	r0, 0x37	; 55
+    3f2c:	00 fc       	sbrc	r0, 0
+    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3f48:	c7 be       	out	0x37, r12	; 55
-    3f4a:	e8 95       	spm
-    3f4c:	22 c0       	rjmp	.+68     	; 0x3f92 <main+0x192>
+    3f30:	c7 be       	out	0x37, r12	; 55
+    3f32:	e8 95       	spm
+    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f4e:	84 37       	cpi	r24, 0x74	; 116
-    3f50:	91 f4       	brne	.+36     	; 0x3f76 <main+0x176>
+    3f36:	84 37       	cpi	r24, 0x74	; 116
+    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
-    3f52:	2a d0       	rcall	.+84     	; 0x3fa8 <getch>
-    3f54:	90 e0       	ldi	r25, 0x00	; 0
-    3f56:	d8 2f       	mov	r29, r24
-    3f58:	cc 27       	eor	r28, r28
-      length |= getch();
-    3f5a:	26 d0       	rcall	.+76     	; 0x3fa8 <getch>
-    3f5c:	90 e0       	ldi	r25, 0x00	; 0
-    3f5e:	c8 2b       	or	r28, r24
-    3f60:	d9 2b       	or	r29, r25
+      GETLENGTH(length);
+    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
+    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
+    3f3e:	08 2f       	mov	r16, r24
+
       desttype = getch();
-    3f62:	22 d0       	rcall	.+68     	; 0x3fa8 <getch>
+    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
 
       verifySpace();
-    3f64:	33 d0       	rcall	.+102    	; 0x3fcc <verifySpace>
-    3f66:	85 01       	movw	r16, r10
+    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
+    3f44:	e7 01       	movw	r28, r14
 	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
 	    // read a Flash byte and increment the address
 	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
 	    putch(ch);
-    3f68:	f8 01       	movw	r30, r16
-    3f6a:	85 91       	lpm	r24, Z+
-    3f6c:	8f 01       	movw	r16, r30
-    3f6e:	14 d0       	rcall	.+40     	; 0x3f98 <putch>
+    3f46:	fe 01       	movw	r30, r28
+    3f48:	85 91       	lpm	r24, Z+
+    3f4a:	ef 01       	movw	r28, r30
+    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
 	} while (--length);
-    3f70:	21 97       	sbiw	r28, 0x01	; 1
-    3f72:	d1 f7       	brne	.-12     	; 0x3f68 <main+0x168>
-    3f74:	0e c0       	rjmp	.+28     	; 0x3f92 <main+0x192>
+    3f4e:	01 50       	subi	r16, 0x01	; 1
+    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
+    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
 	  
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f76:	85 37       	cpi	r24, 0x75	; 117
-    3f78:	39 f4       	brne	.+14     	; 0x3f88 <main+0x188>
+    3f54:	85 37       	cpi	r24, 0x75	; 117
+    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f7a:	28 d0       	rcall	.+80     	; 0x3fcc <verifySpace>
+    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
       putch(SIGNATURE_0);
-    3f7c:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7e:	0c d0       	rcall	.+24     	; 0x3f98 <putch>
+    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
+    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
       putch(SIGNATURE_1);
-    3f80:	84 e9       	ldi	r24, 0x94	; 148
-    3f82:	0a d0       	rcall	.+20     	; 0x3f98 <putch>
+    3f5e:	84 e9       	ldi	r24, 0x94	; 148
+    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
       putch(SIGNATURE_2);
-    3f84:	86 e0       	ldi	r24, 0x06	; 6
-    3f86:	7d cf       	rjmp	.-262    	; 0x3e82 <main+0x82>
+    3f62:	86 e0       	ldi	r24, 0x06	; 6
+    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f88:	81 35       	cpi	r24, 0x51	; 81
-    3f8a:	11 f4       	brne	.+4      	; 0x3f90 <main+0x190>
+    3f66:	81 35       	cpi	r24, 0x51	; 81
+    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8c:	88 e0       	ldi	r24, 0x08	; 8
-    3f8e:	18 d0       	rcall	.+48     	; 0x3fc0 <watchdogConfig>
+    3f6a:	88 e0       	ldi	r24, 0x08	; 8
+    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f90:	1d d0       	rcall	.+58     	; 0x3fcc <verifySpace>
+    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
     }
     putch(STK_OK);
-    3f92:	80 e1       	ldi	r24, 0x10	; 16
-    3f94:	01 d0       	rcall	.+2      	; 0x3f98 <putch>
-    3f96:	67 cf       	rjmp	.-306    	; 0x3e66 <main+0x66>
+    3f70:	80 e1       	ldi	r24, 0x10	; 16
+    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
+    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
 
-00003f98 <putch>:
+00003f76 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f98:	98 2f       	mov	r25, r24
+    3f76:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    3f9a:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9e:	85 ff       	sbrs	r24, 5
-    3fa0:	fc cf       	rjmp	.-8      	; 0x3f9a <putch+0x2>
+    3f78:	80 91 c0 00 	lds	r24, 0x00C0
+    3f7c:	85 ff       	sbrs	r24, 5
+    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
   UART_UDR = ch;
-    3fa2:	90 93 c6 00 	sts	0x00C6, r25
+    3f80:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa6:	08 95       	ret
+    3f84:	08 95       	ret
 
-00003fa8 <getch>:
+00003f86 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    3fa8:	80 91 c0 00 	lds	r24, 0x00C0
-    3fac:	87 ff       	sbrs	r24, 7
-    3fae:	fc cf       	rjmp	.-8      	; 0x3fa8 <getch>
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	87 ff       	sbrs	r24, 7
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb4:	84 fd       	sbrc	r24, 4
-    3fb6:	01 c0       	rjmp	.+2      	; 0x3fba <getch+0x12>
+    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
+    3f92:	84 fd       	sbrc	r24, 4
+    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb8:	a8 95       	wdr
+    3f96:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
   ch = UART_UDR;
-    3fba:	80 91 c6 00 	lds	r24, 0x00C6
+    3f98:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbe:	08 95       	ret
+    3f9c:	08 95       	ret
 
-00003fc0 <watchdogConfig>:
+00003f9e <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fc0:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc2:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc4:	98 e1       	ldi	r25, 0x18	; 24
-    3fc6:	90 83       	st	Z, r25
+    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
+    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
+    3fa2:	98 e1       	ldi	r25, 0x18	; 24
+    3fa4:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc8:	80 83       	st	Z, r24
+    3fa6:	80 83       	st	Z, r24
 }
-    3fca:	08 95       	ret
+    3fa8:	08 95       	ret
 
-00003fcc <verifySpace>:
+00003faa <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fcc:	ed df       	rcall	.-38     	; 0x3fa8 <getch>
-    3fce:	80 32       	cpi	r24, 0x20	; 32
-    3fd0:	19 f0       	breq	.+6      	; 0x3fd8 <verifySpace+0xc>
+    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
+    3fac:	80 32       	cpi	r24, 0x20	; 32
+    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd2:	88 e0       	ldi	r24, 0x08	; 8
-    3fd4:	f5 df       	rcall	.-22     	; 0x3fc0 <watchdogConfig>
-    3fd6:	ff cf       	rjmp	.-2      	; 0x3fd6 <verifySpace+0xa>
+    3fb0:	88 e0       	ldi	r24, 0x08	; 8
+    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
+    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd8:	84 e1       	ldi	r24, 0x14	; 20
+    3fb6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fda:	de cf       	rjmp	.-68     	; 0x3f98 <putch>
+    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
 
-00003fdc <getNch>:
+00003fba <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fdc:	1f 93       	push	r17
-    3fde:	18 2f       	mov	r17, r24
+    3fba:	1f 93       	push	r17
+    3fbc:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fe0:	e3 df       	rcall	.-58     	; 0x3fa8 <getch>
-    3fe2:	11 50       	subi	r17, 0x01	; 1
-    3fe4:	e9 f7       	brne	.-6      	; 0x3fe0 <getNch+0x4>
+    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
+    3fc0:	11 50       	subi	r17, 0x01	; 1
+    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
   verifySpace();
-    3fe6:	f2 df       	rcall	.-28     	; 0x3fcc <verifySpace>
+    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
 }
-    3fe8:	1f 91       	pop	r17
-    3fea:	08 95       	ret
+    3fc6:	1f 91       	pop	r17
+    3fc8:	08 95       	ret
 
-00003fec <appStart>:
+00003fca <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fec:	28 2e       	mov	r2, r24
+    3fca:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    3fee:	80 e0       	ldi	r24, 0x00	; 0
-    3ff0:	e7 df       	rcall	.-50     	; 0x3fc0 <watchdogConfig>
+    3fcc:	80 e0       	ldi	r24, 0x00	; 0
+    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
   __asm__ __volatile__ (
-    3ff2:	ee 27       	eor	r30, r30
-    3ff4:	ff 27       	eor	r31, r31
-    3ff6:	09 94       	ijmp
+    3fd0:	ee 27       	eor	r30, r30
+    3fd2:	ff 27       	eor	r31, r31
+    3fd4:	09 94       	ijmp

+ 28 - 30
optiboot/bootloaders/optiboot/optiboot_pro_8MHz.hex

@@ -1,35 +1,33 @@
-:103E0000112494B714BE892F8D7011F0892FEED034
+:103E0000112494B714BE892F8D7011F0892FDDD045
 :103E100085E08093810082E08093C00088E18093F8
 :103E2000C10086E08093C20088E08093C4008EE0E9
-:103E3000C7D0259A86E028E13EEF91E030938500D7
+:103E3000B6D0259A86E028E13EEF91E030938500E8
 :103E40002093840096BBB09BFECF1D9AA89581500D
-:103E5000A9F7AA24BB2433E0832E7724739425E0AA
-:103E6000922E91E1C92EA0D0813469F49DD0182FF3
-:103E7000ADD0123811F481E004C0113809F482C0C9
-:103E800083E08AD086C0823411F484E103C0853493
-:103E900019F485E0A3D07DC0853579F485D0E82E6E
-:103EA000FF2482D0082F10E0102F00270E291F2991
-:103EB000000F111F8BD058016CC0863521F484E0AF
-:103EC0008DD080E0DECF843609F041C06DD090E027
-:103ED000182F002769D090E0082B192B65D0D82E19
-:103EE000E801E12CF1E0FF2E5FD0F70181937F0123
-:103EF0002197D1F76BD0F5E4DF1609F4FFCFF50178
-:103F000087BEE89507B600FCFDCFB501A801A0E08B
-:103F1000B1E02C9130E011968C91119790E0982FA0
-:103F20008827822B932B1296FB010C0177BEE89514
-:103F300011246E5F7F4F4250504059F7F50197BEF4
-:103F4000E89507B600FCFDCFC7BEE89522C08437D0
-:103F500091F42AD090E0D82FCC2726D090E0C82B1F
-:103F6000D92B22D033D08501F80185918F0114D04F
-:103F70002197D1F70EC0853739F428D08EE10CD0C7
-:103F800084E90AD086E07DCF813511F488E018D02D
-:103F90001DD080E101D067CF982F8091C00085FFB0
-:103FA000FCCF9093C60008958091C00087FFFCCF9E
-:103FB0008091C00084FD01C0A8958091C60008953D
-:103FC000E0E6F0E098E1908380830895EDDF8032B1
-:103FD00019F088E0F5DFFFCF84E1DECF1F93182FC3
-:103FE000E3DF1150E9F7F2DF1F910895282E80E0FA
-:083FF000E7DFEE27FF2709942B
-:023FFE000106BA
+:103E5000A9F7EE24FF24B3E0AB2EBB24B394A5E076
+:103E6000DA2EF1E1CF2E8FD0813469F48CD0082F77
+:103E70009CD0023811F482E004C0013809F471C00A
+:103E800083E079D075C0823411F484E103C08534B5
+:103E900019F485E092D06CC0853579F474D0E82EA1
+:103EA000FF2471D0082F10E0102F00270E291F29A2
+:103EB000000F111F7AD078015BC0863521F484E0B1
+:103EC0007CD080E0DECF843609F035C05CD05BD09A
+:103ED000182F59D0082FC0E0D1E055D089931C1776
+:103EE000E1F763D0053409F4FFCFF701A7BEE895E9
+:103EF00007B600FCFDCFA701A0E0B1E02C9130E0B7
+:103F000011968C91119790E0982F8827822B932BF4
+:103F10001296FA010C01B7BEE89511244E5F5F4F6F
+:103F20001A1761F7F701D7BEE89507B600FCFDCF79
+:103F3000C7BEE8951DC0843769F425D024D0082F6A
+:103F400022D033D0E701FE018591EF0114D001505A
+:103F5000D1F70EC0853739F428D08EE10CD084E932
+:103F60000AD086E08ECF813511F488E018D01DD0BC
+:103F700080E101D078CF982F8091C00085FFFCCFE1
+:103F80009093C60008958091C00087FFFCCF809178
+:103F9000C00084FD01C0A8958091C6000895E0E6A8
+:103FA000F0E098E1908380830895EDDF803219F08E
+:103FB00088E0F5DFFFCF84E1DECF1F93182FE3DF2A
+:103FC0001150E9F7F2DF1F910895282E80E0E7DF16
+:063FD000EE27FF27099413
+:023FFE000206B9
 :0400000300003E00BB
 :00000001FF

+ 180 - 198
optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst

@@ -3,27 +3,27 @@ optiboot_atmega168.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f8  00003e00  00003e00  00000074  2**1
+  0 .text         000001d6  00003e00  00003e00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000026c  2**0
+  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000026e  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000296  2**0
+  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003e0  00000000  00000000  0000030a  2**0
+  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001f1  00000000  00000000  000006ea  2**0
+  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000433  00000000  00000000  000008db  2**0
+  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000d10  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000172  00000000  00000000  00000d90  2**0
+  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d7  00000000  00000000  00000f02  2**0
+  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011d9  2**0
+ 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -51,7 +51,7 @@ int main(void) {
     3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
       appStart(ch);
     3e0c:	89 2f       	mov	r24, r25
-    3e0e:	ee d0       	rcall	.+476    	; 0x3fec <appStart>
+    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -81,7 +81,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	c7 d0       	rcall	.+398    	; 0x3fc0 <watchdogConfig>
+    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
 
 #if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
   /* Set LED pin as output */
@@ -131,68 +131,68 @@ void watchdogReset() {
   } while (--count);
     3e4e:	81 50       	subi	r24, 0x01	; 1
     3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	aa 24       	eor	r10, r10
-    3e54:	bb 24       	eor	r11, r11
+    3e52:	ee 24       	eor	r14, r14
+    3e54:	ff 24       	eor	r15, r15
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	33 e0       	ldi	r19, 0x03	; 3
-    3e58:	83 2e       	mov	r8, r19
+    3e56:	b3 e0       	ldi	r27, 0x03	; 3
+    3e58:	ab 2e       	mov	r10, r27
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	77 24       	eor	r7, r7
-    3e5c:	73 94       	inc	r7
+    3e5a:	bb 24       	eor	r11, r11
+    3e5c:	b3 94       	inc	r11
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	25 e0       	ldi	r18, 0x05	; 5
-    3e60:	92 2e       	mov	r9, r18
+    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
+    3e60:	da 2e       	mov	r13, r26
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3e62:	91 e1       	ldi	r25, 0x11	; 17
-    3e64:	c9 2e       	mov	r12, r25
+    3e62:	f1 e1       	ldi	r31, 0x11	; 17
+    3e64:	cf 2e       	mov	r12, r31
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e66:	a0 d0       	rcall	.+320    	; 0x3fa8 <getch>
+    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e68:	81 34       	cpi	r24, 0x41	; 65
     3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
       unsigned char which = getch();
-    3e6c:	9d d0       	rcall	.+314    	; 0x3fa8 <getch>
-    3e6e:	18 2f       	mov	r17, r24
+    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
+    3e6e:	08 2f       	mov	r16, r24
       verifySpace();
-    3e70:	ad d0       	rcall	.+346    	; 0x3fcc <verifySpace>
+    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
       if (which == 0x82) {
-    3e72:	12 38       	cpi	r17, 0x82	; 130
+    3e72:	02 38       	cpi	r16, 0x82	; 130
     3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(optiboot_version & 0xFF);
-    3e76:	81 e0       	ldi	r24, 0x01	; 1
+    3e76:	82 e0       	ldi	r24, 0x02	; 2
     3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
       } else if (which == 0x81) {
-    3e7a:	11 38       	cpi	r17, 0x81	; 129
+    3e7a:	01 38       	cpi	r16, 0x81	; 129
     3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	82 c0       	rjmp	.+260    	; 0x3f84 <main+0x184>
+    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
@@ -200,8 +200,8 @@ void watchdogReset() {
 	 */
 	putch(0x03);
     3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	8a d0       	rcall	.+276    	; 0x3f98 <putch>
-    3e84:	86 c0       	rjmp	.+268    	; 0x3f92 <main+0x192>
+    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
+    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
       }
     }
     else if(ch == STK_SET_DEVICE) {
@@ -218,8 +218,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	a3 d0       	rcall	.+326    	; 0x3fdc <getNch>
-    3e96:	7d c0       	rjmp	.+250    	; 0x3f92 <main+0x192>
+    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
+    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e98:	85 35       	cpi	r24, 0x55	; 85
@@ -227,11 +227,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e9c:	85 d0       	rcall	.+266    	; 0x3fa8 <getch>
+    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e9e:	e8 2e       	mov	r14, r24
     3ea0:	ff 24       	eor	r15, r15
-    3ea2:	82 d0       	rcall	.+260    	; 0x3fa8 <getch>
+    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
     3ea4:	08 2f       	mov	r16, r24
     3ea6:	10 e0       	ldi	r17, 0x00	; 0
     3ea8:	10 2f       	mov	r17, r16
@@ -247,9 +247,9 @@ void watchdogReset() {
     3eb2:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eb4:	8b d0       	rcall	.+278    	; 0x3fcc <verifySpace>
-    3eb6:	58 01       	movw	r10, r16
-    3eb8:	6c c0       	rjmp	.+216    	; 0x3f92 <main+0x192>
+    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
+    3eb6:	78 01       	movw	r14, r16
+    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_UNIVERSAL) {
     3eba:	86 35       	cpi	r24, 0x56	; 86
@@ -257,7 +257,7 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	8d d0       	rcall	.+282    	; 0x3fdc <getNch>
+    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
       putch(0x00);
     3ec2:	80 e0       	ldi	r24, 0x00	; 0
     3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
@@ -266,339 +266,321 @@ void watchdogReset() {
     else if(ch == STK_PROG_PAGE) {
     3ec6:	84 36       	cpi	r24, 0x64	; 100
     3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	41 c0       	rjmp	.+130    	; 0x3f4e <main+0x14e>
+    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t savelength;
+      pagelen_t savelength;
 
-      length = getch()<<8;			/* getlen() */
-    3ecc:	6d d0       	rcall	.+218    	; 0x3fa8 <getch>
-    3ece:	90 e0       	ldi	r25, 0x00	; 0
+      GETLENGTH(length);
+    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
+    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
     3ed0:	18 2f       	mov	r17, r24
-    3ed2:	00 27       	eor	r16, r16
-      length |= getch();
-    3ed4:	69 d0       	rcall	.+210    	; 0x3fa8 <getch>
-    3ed6:	90 e0       	ldi	r25, 0x00	; 0
-    3ed8:	08 2b       	or	r16, r24
-    3eda:	19 2b       	or	r17, r25
       savelength = length;
       desttype = getch();
-    3edc:	65 d0       	rcall	.+202    	; 0x3fa8 <getch>
-    3ede:	d8 2e       	mov	r13, r24
-    3ee0:	e8 01       	movw	r28, r16
-    3ee2:	e1 2c       	mov	r14, r1
-    3ee4:	f1 e0       	ldi	r31, 0x01	; 1
-    3ee6:	ff 2e       	mov	r15, r31
+    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
+    3ed4:	08 2f       	mov	r16, r24
+    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
 
       // read a page worth of contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee8:	5f d0       	rcall	.+190    	; 0x3fa8 <getch>
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	81 93       	st	Z+, r24
-    3eee:	7f 01       	movw	r14, r30
+    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
+    3edc:	89 93       	st	Y+, r24
       while (--length);
-    3ef0:	21 97       	sbiw	r28, 0x01	; 1
-    3ef2:	d1 f7       	brne	.-12     	; 0x3ee8 <main+0xe8>
+    3ede:	1c 17       	cp	r17, r28
+    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
 
       // Read command terminator, start reply
       verifySpace();
-    3ef4:	6b d0       	rcall	.+214    	; 0x3fcc <verifySpace>
+    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
  * void writebuffer(memtype, buffer, address, length)
  */
 static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, uint16_t len)
+			       uint16_t address, pagelen_t len)
 {
     switch (memtype) {
-    3ef6:	f5 e4       	ldi	r31, 0x45	; 69
-    3ef8:	df 16       	cp	r13, r31
-    3efa:	09 f4       	brne	.+2      	; 0x3efe <main+0xfe>
-    3efc:	ff cf       	rjmp	.-2      	; 0x3efc <main+0xfc>
+    3ee4:	05 34       	cpi	r16, 0x45	; 69
+    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
+    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
 	    __boot_page_erase_short((uint16_t)(void*)address);
-    3efe:	f5 01       	movw	r30, r10
-    3f00:	87 be       	out	0x37, r8	; 55
-    3f02:	e8 95       	spm
+    3eea:	f7 01       	movw	r30, r14
+    3eec:	a7 be       	out	0x37, r10	; 55
+    3eee:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f04:	07 b6       	in	r0, 0x37	; 55
-    3f06:	00 fc       	sbrc	r0, 0
-    3f08:	fd cf       	rjmp	.-6      	; 0x3f04 <main+0x104>
-    3f0a:	b5 01       	movw	r22, r10
-    3f0c:	a8 01       	movw	r20, r16
-    3f0e:	a0 e0       	ldi	r26, 0x00	; 0
-    3f10:	b1 e0       	ldi	r27, 0x01	; 1
+    3ef0:	07 b6       	in	r0, 0x37	; 55
+    3ef2:	00 fc       	sbrc	r0, 0
+    3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
+    3ef6:	a7 01       	movw	r20, r14
+    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
+    3efa:	b1 e0       	ldi	r27, 0x01	; 1
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
-    3f12:	2c 91       	ld	r18, X
-    3f14:	30 e0       	ldi	r19, 0x00	; 0
+    3efc:	2c 91       	ld	r18, X
+    3efe:	30 e0       	ldi	r19, 0x00	; 0
 		a |= (*bufPtr++) << 8;
-    3f16:	11 96       	adiw	r26, 0x01	; 1
-    3f18:	8c 91       	ld	r24, X
-    3f1a:	11 97       	sbiw	r26, 0x01	; 1
-    3f1c:	90 e0       	ldi	r25, 0x00	; 0
-    3f1e:	98 2f       	mov	r25, r24
-    3f20:	88 27       	eor	r24, r24
-    3f22:	82 2b       	or	r24, r18
-    3f24:	93 2b       	or	r25, r19
+    3f00:	11 96       	adiw	r26, 0x01	; 1
+    3f02:	8c 91       	ld	r24, X
+    3f04:	11 97       	sbiw	r26, 0x01	; 1
+    3f06:	90 e0       	ldi	r25, 0x00	; 0
+    3f08:	98 2f       	mov	r25, r24
+    3f0a:	88 27       	eor	r24, r24
+    3f0c:	82 2b       	or	r24, r18
+    3f0e:	93 2b       	or	r25, r19
 #define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
 #endif
 
 
 /* main program starts here */
 int main(void) {
-    3f26:	12 96       	adiw	r26, 0x02	; 2
+    3f10:	12 96       	adiw	r26, 0x02	; 2
 	     */
 	    do {
 		uint16_t a;
 		a = *bufPtr++;
 		a |= (*bufPtr++) << 8;
 		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f28:	fb 01       	movw	r30, r22
-    3f2a:	0c 01       	movw	r0, r24
-    3f2c:	77 be       	out	0x37, r7	; 55
-    3f2e:	e8 95       	spm
-    3f30:	11 24       	eor	r1, r1
+    3f12:	fa 01       	movw	r30, r20
+    3f14:	0c 01       	movw	r0, r24
+    3f16:	b7 be       	out	0x37, r11	; 55
+    3f18:	e8 95       	spm
+    3f1a:	11 24       	eor	r1, r1
 		addrPtr += 2;
-    3f32:	6e 5f       	subi	r22, 0xFE	; 254
-    3f34:	7f 4f       	sbci	r23, 0xFF	; 255
+    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
+    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    3f36:	42 50       	subi	r20, 0x02	; 2
-    3f38:	50 40       	sbci	r21, 0x00	; 0
-    3f3a:	59 f7       	brne	.-42     	; 0x3f12 <main+0x112>
+    3f20:	1a 17       	cp	r17, r26
+    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
 	    __boot_page_write_short((uint16_t)(void*)address);
-    3f3c:	f5 01       	movw	r30, r10
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
+    3f24:	f7 01       	movw	r30, r14
+    3f26:	d7 be       	out	0x37, r13	; 55
+    3f28:	e8 95       	spm
 	    boot_spm_busy_wait();
-    3f42:	07 b6       	in	r0, 0x37	; 55
-    3f44:	00 fc       	sbrc	r0, 0
-    3f46:	fd cf       	rjmp	.-6      	; 0x3f42 <main+0x142>
+    3f2a:	07 b6       	in	r0, 0x37	; 55
+    3f2c:	00 fc       	sbrc	r0, 0
+    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
 #if defined(RWWSRE)
 	    // Reenable read access to flash
 	    boot_rww_enable();
-    3f48:	c7 be       	out	0x37, r12	; 55
-    3f4a:	e8 95       	spm
-    3f4c:	22 c0       	rjmp	.+68     	; 0x3f92 <main+0x192>
+    3f30:	c7 be       	out	0x37, r12	; 55
+    3f32:	e8 95       	spm
+    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f4e:	84 37       	cpi	r24, 0x74	; 116
-    3f50:	91 f4       	brne	.+36     	; 0x3f76 <main+0x176>
+    3f36:	84 37       	cpi	r24, 0x74	; 116
+    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
       uint8_t desttype;
-      length = getch()<<8;			/* getlen() */
-    3f52:	2a d0       	rcall	.+84     	; 0x3fa8 <getch>
-    3f54:	90 e0       	ldi	r25, 0x00	; 0
-    3f56:	d8 2f       	mov	r29, r24
-    3f58:	cc 27       	eor	r28, r28
-      length |= getch();
-    3f5a:	26 d0       	rcall	.+76     	; 0x3fa8 <getch>
-    3f5c:	90 e0       	ldi	r25, 0x00	; 0
-    3f5e:	c8 2b       	or	r28, r24
-    3f60:	d9 2b       	or	r29, r25
+      GETLENGTH(length);
+    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
+    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
+    3f3e:	08 2f       	mov	r16, r24
+
       desttype = getch();
-    3f62:	22 d0       	rcall	.+68     	; 0x3fa8 <getch>
+    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
 
       verifySpace();
-    3f64:	33 d0       	rcall	.+102    	; 0x3fcc <verifySpace>
-    3f66:	85 01       	movw	r16, r10
+    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
+    3f44:	e7 01       	movw	r28, r14
 	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
 	    // read a Flash byte and increment the address
 	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
 	    putch(ch);
-    3f68:	f8 01       	movw	r30, r16
-    3f6a:	85 91       	lpm	r24, Z+
-    3f6c:	8f 01       	movw	r16, r30
-    3f6e:	14 d0       	rcall	.+40     	; 0x3f98 <putch>
+    3f46:	fe 01       	movw	r30, r28
+    3f48:	85 91       	lpm	r24, Z+
+    3f4a:	ef 01       	movw	r28, r30
+    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
 	} while (--length);
-    3f70:	21 97       	sbiw	r28, 0x01	; 1
-    3f72:	d1 f7       	brne	.-12     	; 0x3f68 <main+0x168>
-    3f74:	0e c0       	rjmp	.+28     	; 0x3f92 <main+0x192>
+    3f4e:	01 50       	subi	r16, 0x01	; 1
+    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
+    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
 	  
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f76:	85 37       	cpi	r24, 0x75	; 117
-    3f78:	39 f4       	brne	.+14     	; 0x3f88 <main+0x188>
+    3f54:	85 37       	cpi	r24, 0x75	; 117
+    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f7a:	28 d0       	rcall	.+80     	; 0x3fcc <verifySpace>
+    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
       putch(SIGNATURE_0);
-    3f7c:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7e:	0c d0       	rcall	.+24     	; 0x3f98 <putch>
+    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
+    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
       putch(SIGNATURE_1);
-    3f80:	84 e9       	ldi	r24, 0x94	; 148
-    3f82:	0a d0       	rcall	.+20     	; 0x3f98 <putch>
+    3f5e:	84 e9       	ldi	r24, 0x94	; 148
+    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
       putch(SIGNATURE_2);
-    3f84:	86 e0       	ldi	r24, 0x06	; 6
-    3f86:	7d cf       	rjmp	.-262    	; 0x3e82 <main+0x82>
+    3f62:	86 e0       	ldi	r24, 0x06	; 6
+    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f88:	81 35       	cpi	r24, 0x51	; 81
-    3f8a:	11 f4       	brne	.+4      	; 0x3f90 <main+0x190>
+    3f66:	81 35       	cpi	r24, 0x51	; 81
+    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8c:	88 e0       	ldi	r24, 0x08	; 8
-    3f8e:	18 d0       	rcall	.+48     	; 0x3fc0 <watchdogConfig>
+    3f6a:	88 e0       	ldi	r24, 0x08	; 8
+    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f90:	1d d0       	rcall	.+58     	; 0x3fcc <verifySpace>
+    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
     }
     putch(STK_OK);
-    3f92:	80 e1       	ldi	r24, 0x10	; 16
-    3f94:	01 d0       	rcall	.+2      	; 0x3f98 <putch>
-    3f96:	67 cf       	rjmp	.-306    	; 0x3e66 <main+0x66>
+    3f70:	80 e1       	ldi	r24, 0x10	; 16
+    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
+    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
 
-00003f98 <putch>:
+00003f76 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f98:	98 2f       	mov	r25, r24
+    3f76:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    3f9a:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9e:	85 ff       	sbrs	r24, 5
-    3fa0:	fc cf       	rjmp	.-8      	; 0x3f9a <putch+0x2>
+    3f78:	80 91 c0 00 	lds	r24, 0x00C0
+    3f7c:	85 ff       	sbrs	r24, 5
+    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
   UART_UDR = ch;
-    3fa2:	90 93 c6 00 	sts	0x00C6, r25
+    3f80:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa6:	08 95       	ret
+    3f84:	08 95       	ret
 
-00003fa8 <getch>:
+00003f86 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    3fa8:	80 91 c0 00 	lds	r24, 0x00C0
-    3fac:	87 ff       	sbrs	r24, 7
-    3fae:	fc cf       	rjmp	.-8      	; 0x3fa8 <getch>
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	87 ff       	sbrs	r24, 7
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb4:	84 fd       	sbrc	r24, 4
-    3fb6:	01 c0       	rjmp	.+2      	; 0x3fba <getch+0x12>
+    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
+    3f92:	84 fd       	sbrc	r24, 4
+    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb8:	a8 95       	wdr
+    3f96:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
   ch = UART_UDR;
-    3fba:	80 91 c6 00 	lds	r24, 0x00C6
+    3f98:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbe:	08 95       	ret
+    3f9c:	08 95       	ret
 
-00003fc0 <watchdogConfig>:
+00003f9e <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fc0:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc2:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc4:	98 e1       	ldi	r25, 0x18	; 24
-    3fc6:	90 83       	st	Z, r25
+    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
+    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
+    3fa2:	98 e1       	ldi	r25, 0x18	; 24
+    3fa4:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc8:	80 83       	st	Z, r24
+    3fa6:	80 83       	st	Z, r24
 }
-    3fca:	08 95       	ret
+    3fa8:	08 95       	ret
 
-00003fcc <verifySpace>:
+00003faa <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fcc:	ed df       	rcall	.-38     	; 0x3fa8 <getch>
-    3fce:	80 32       	cpi	r24, 0x20	; 32
-    3fd0:	19 f0       	breq	.+6      	; 0x3fd8 <verifySpace+0xc>
+    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
+    3fac:	80 32       	cpi	r24, 0x20	; 32
+    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd2:	88 e0       	ldi	r24, 0x08	; 8
-    3fd4:	f5 df       	rcall	.-22     	; 0x3fc0 <watchdogConfig>
-    3fd6:	ff cf       	rjmp	.-2      	; 0x3fd6 <verifySpace+0xa>
+    3fb0:	88 e0       	ldi	r24, 0x08	; 8
+    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
+    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd8:	84 e1       	ldi	r24, 0x14	; 20
+    3fb6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fda:	de cf       	rjmp	.-68     	; 0x3f98 <putch>
+    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
 
-00003fdc <getNch>:
+00003fba <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fdc:	1f 93       	push	r17
-    3fde:	18 2f       	mov	r17, r24
+    3fba:	1f 93       	push	r17
+    3fbc:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fe0:	e3 df       	rcall	.-58     	; 0x3fa8 <getch>
-    3fe2:	11 50       	subi	r17, 0x01	; 1
-    3fe4:	e9 f7       	brne	.-6      	; 0x3fe0 <getNch+0x4>
+    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
+    3fc0:	11 50       	subi	r17, 0x01	; 1
+    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
   verifySpace();
-    3fe6:	f2 df       	rcall	.-28     	; 0x3fcc <verifySpace>
+    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
 }
-    3fe8:	1f 91       	pop	r17
-    3fea:	08 95       	ret
+    3fc6:	1f 91       	pop	r17
+    3fc8:	08 95       	ret
 
-00003fec <appStart>:
+00003fca <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fec:	28 2e       	mov	r2, r24
+    3fca:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    3fee:	80 e0       	ldi	r24, 0x00	; 0
-    3ff0:	e7 df       	rcall	.-50     	; 0x3fc0 <watchdogConfig>
+    3fcc:	80 e0       	ldi	r24, 0x00	; 0
+    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
   __asm__ __volatile__ (
-    3ff2:	ee 27       	eor	r30, r30
-    3ff4:	ff 27       	eor	r31, r31
-    3ff6:	09 94       	ijmp
+    3fd0:	ee 27       	eor	r30, r30
+    3fd2:	ff 27       	eor	r31, r31
+    3fd4:	09 94       	ijmp