Browse Source

Save code space by using autoincrement lpm/elpm. Bump version to 4.6
http://code.google.com/p/optiboot/issues/detail?id=73

westfw 12 years ago
parent
commit
f6b4e6c976

+ 15 - 19
optiboot/bootloaders/optiboot/omake

@@ -144,6 +144,8 @@
 /**********************************************************/
 /* Edit History:					  */
 /*							  */
+/* Jan 2013						  */
+/* 4.6 WestfW/dkinzer: use autoincrement lpm for read     */
 /* Mar 2012                                               */
 /* 4.5 WestfW: add infrastructure for non-zero UARTS.     */
 /* 4.5 WestfW: fix SIGNATURE_2 for m644 (bad in avr-libc) */
@@ -176,7 +178,7 @@
 /**********************************************************/
 
 #define OPTIBOOT_MAJVER 4
-#define OPTIBOOT_MINVER 5
+#define OPTIBOOT_MINVER 6
 
 #define MAKESTR(a) #a
 #define MAKEVER(a, b) MAKESTR(a*256+b)
@@ -553,8 +555,8 @@ int main(void) {
       getch();
 
       verifySpace();
-#ifdef VIRTUAL_BOOT_PARTITION
       do {
+#ifdef VIRTUAL_BOOT_PARTITION
         // Undo vector patch in bottom page so verify passes
         if (address == 0)       ch=rstVect & 0xff;
         else if (address == 1)  ch=rstVect >> 8;
@@ -562,25 +564,19 @@ int main(void) {
         else if (address == 9) ch=wdtVect >> 8;
         else ch = pgm_read_byte_near(address);
         address++;
-        putch(ch);
-      } while (--length);
-#else
-#ifdef RAMPZ
-// Since RAMPZ should already be set, we need to use EPLM directly.
-//      do putch(pgm_read_byte_near(address++));
-//      while (--length);
-      do {
-        uint8_t result;
-        __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address));
-        putch(result);
-        address++;
-      }
-      while (--length);
+#elif defined(RAMPZ)
+        // Since RAMPZ should already be set, we need to use EPLM directly.
+        // Also, we can use the autoincrement version of lpm to update "address"
+        //      do putch(pgm_read_byte_near(address++));
+        //      while (--length);
+        // read a Flash and increment the address (may increment RAMPZ)
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-      while (--length);
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+      } while (--length);
     }
 
     /* Get device signature bytes  */

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

@@ -1,35 +1,34 @@
-:107E0000112484B714BE81FFF0D085E080938100F7
+:107E0000112484B714BE81FFE8D085E080938100FF
 :107E100082E08093C00088E18093C10086E0809377
-:107E2000C20080E18093C4008EE0C9D0259A86E02C
+:107E2000C20080E18093C4008EE0C1D0259A86E034
 :107E300020E33CEF91E0309385002093840096BBD3
-:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
-:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
-:107E6000A2D0813461F49FD0082FAFD0023811F036
-:107E7000013811F484E001C083E08DD089C08234E0
-:107E800011F484E103C0853419F485E0A6D080C0E4
-:107E9000853579F488D0E82EFF2485D0082F10E0AE
-:107EA000102F00270E291F29000F111F8ED06801E7
-:107EB0006FC0863521F484E090D080E0DECF843638
-:107EC00009F040C070D06FD0082F6DD080E0C81688
-:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
-:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
-:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
-:107F0000A601A0E0B1E02C9130E011968C91119780
-:107F100090E0982F8827822B932B1296FA010C0160
-:107F200087BEE89511244E5F5F4FF1E0A038BF0790
-:107F300051F7F601A7BEE89507B600FCFDCF97BE46
-:107F4000E89526C08437B1F42ED02DD0F82E2BD052
-:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
-:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
-:107F7000D11C0EC0853739F428D08EE10CD085E9AC
-:107F80000AD08FE07ACF813511F488E018D01DD067
-:107F900080E101D065CF982F8091C00085FFFCCF94
-:107FA0009093C60008958091C00087FFFCCF809118
-:107FB000C00084FD01C0A8958091C6000895E0E648
-:107FC000F0E098E1908380830895EDDF803219F02E
-:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
-:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
-:047FF000FF270994CA
-:027FFE00040479
+:107E4000B09BFECF1D9AA8958150A9F7EE24FF2480
+:107E5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2E45
+:107E60009AD0813471F497D0082FA7D0023811F43A
+:107E700086E005C0013811F484E001C083E083D0BE
+:107E80007FC0823411F484E103C0853419F485E0A5
+:107E90009CD076C0853579F47ED0E82EFF247BD047
+:107EA000082F10E0102F00270E291F29000F111F87
+:107EB00084D0780165C0863521F484E086D080E0E6
+:107EC000DECF843609F040C066D065D0082F63D07D
+:107ED00080E0E81680E7F80618F4F701D7BEE895C9
+:107EE000C0E0D1E058D089930C17E1F7F0E0EF162D
+:107EF000F0E7FF0618F0F701D7BEE8955ED007B6A9
+:107F000000FCFDCFA701A0E0B1E02C9130E011967C
+:107F10008C91119790E0982F8827822B932B1296A3
+:107F2000FA010C01A7BEE89511244E5F5F4FF1E006
+:107F3000A038BF0751F7F701C7BEE89507B600FCA8
+:107F4000FDCFB7BEE8951CC0843761F424D023D0A0
+:107F5000082F21D032D0F70185917F0114D0015034
+:107F6000D1F70EC0853739F428D08EE10CD085E9E1
+:107F70000AD08FE084CF813511F488E018D01DD06D
+:107F800080E101D06DCF982F8091C00085FFFCCF9C
+:107F90009093C60008958091C00087FFFCCF809128
+:107FA000C00084FD01C0A8958091C6000895E0E658
+:107FB000F0E098E1908380830895EDDF803219F03E
+:107FC00088E0F5DFFFCF84E1DECF1F93182FE3DFDA
+:107FD0001150E9F7F2DF1F91089580E0E8DFEE2706
+:047FE000FF270994DA
+:027FFE00060477
 :0400000300007E007B
 :00000001FF

+ 231 - 247
optiboot/bootloaders/optiboot/optiboot_atmega328.lst

@@ -3,34 +3,34 @@ optiboot_atmega328.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f4  00007e00  00007e00  00000054  2**1
+  0 .text         000001e4  00007e00  00007e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00007ffe  00007ffe  00000248  2**0
+  1 .version      00000002  00007ffe  00007ffe  00000238  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  0000024a  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000023a  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000005f  00000000  00000000  00000272  2**0
+  3 .debug_pubnames 0000005f  00000000  00000000  00000262  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002a8  00000000  00000000  000002d1  2**0
+  4 .debug_info   0000027e  00000000  00000000  000002c1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000178  00000000  00000000  00000579  2**0
+  5 .debug_abbrev 0000016b  00000000  00000000  0000053f  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000046b  00000000  00000000  000006f1  2**0
+  6 .debug_line   00000468  00000000  00000000  000006aa  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000b5c  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000b14  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000143  00000000  00000000  00000bdc  2**0
+  8 .debug_str    00000128  00000000  00000000  00000b94  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d8  00000000  00000000  00000d1f  2**0
+  9 .debug_loc    00000253  00000000  00000000  00000cbc  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000078  00000000  00000000  00000ff7  2**0
+ 10 .debug_ranges 00000078  00000000  00000000  00000f0f  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00007e00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,7 +47,7 @@ int main(void) {
     7e04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     7e06:	81 ff       	sbrs	r24, 1
-    7e08:	f0 d0       	rcall	.+480    	; 0x7fea <appStart>
+    7e08:	e8 d0       	rcall	.+464    	; 0x7fda <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -59,16 +59,16 @@ int main(void) {
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
-  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UART_SRA = _BV(U2X0); //Double speed mode USART0
     7e10:	82 e0       	ldi	r24, 0x02	; 2
     7e12:	80 93 c0 00 	sts	0x00C0, r24
-  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
     7e16:	88 e1       	ldi	r24, 0x18	; 24
     7e18:	80 93 c1 00 	sts	0x00C1, r24
-  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
     7e1c:	86 e0       	ldi	r24, 0x06	; 6
     7e1e:	80 93 c2 00 	sts	0x00C2, r24
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
     7e22:	80 e1       	ldi	r24, 0x10	; 16
     7e24:	80 93 c4 00 	sts	0x00C4, r24
 #endif
@@ -77,7 +77,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     7e28:	8e e0       	ldi	r24, 0x0E	; 14
-    7e2a:	c9 d0       	rcall	.+402    	; 0x7fbe <watchdogConfig>
+    7e2a:	c1 d0       	rcall	.+386    	; 0x7fae <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -126,30 +126,30 @@ void watchdogReset() {
   } while (--count);
     7e48:	81 50       	subi	r24, 0x01	; 1
     7e4a:	a9 f7       	brne	.-22     	; 0x7e36 <main+0x36>
-    7e4c:	cc 24       	eor	r12, r12
-    7e4e:	dd 24       	eor	r13, r13
+    7e4c:	ee 24       	eor	r14, r14
+    7e4e:	ff 24       	eor	r15, r15
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7e50:	88 24       	eor	r8, r8
-    7e52:	83 94       	inc	r8
+    7e50:	aa 24       	eor	r10, r10
+    7e52:	a3 94       	inc	r10
         addrPtr += 2;
       } while (--ch);
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     7e54:	b5 e0       	ldi	r27, 0x05	; 5
-    7e56:	ab 2e       	mov	r10, r27
+    7e56:	cb 2e       	mov	r12, r27
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     7e58:	a1 e1       	ldi	r26, 0x11	; 17
-    7e5a:	9a 2e       	mov	r9, r26
+    7e5a:	ba 2e       	mov	r11, r26
       do *bufPtr++ = getch();
       while (--length);
 
@@ -157,442 +157,426 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     7e5c:	f3 e0       	ldi	r31, 0x03	; 3
-    7e5e:	bf 2e       	mov	r11, r31
+    7e5e:	df 2e       	mov	r13, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    7e60:	a2 d0       	rcall	.+324    	; 0x7fa6 <getch>
+    7e60:	9a d0       	rcall	.+308    	; 0x7f96 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     7e62:	81 34       	cpi	r24, 0x41	; 65
-    7e64:	61 f4       	brne	.+24     	; 0x7e7e <main+0x7e>
+    7e64:	71 f4       	brne	.+28     	; 0x7e82 <main+0x82>
       unsigned char which = getch();
-    7e66:	9f d0       	rcall	.+318    	; 0x7fa6 <getch>
+    7e66:	97 d0       	rcall	.+302    	; 0x7f96 <getch>
     7e68:	08 2f       	mov	r16, r24
       verifySpace();
-    7e6a:	af d0       	rcall	.+350    	; 0x7fca <verifySpace>
+    7e6a:	a7 d0       	rcall	.+334    	; 0x7fba <verifySpace>
       if (which == 0x82) {
     7e6c:	02 38       	cpi	r16, 0x82	; 130
-    7e6e:	11 f0       	breq	.+4      	; 0x7e74 <main+0x74>
+    7e6e:	11 f4       	brne	.+4      	; 0x7e74 <main+0x74>
 	/*
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
+    7e70:	86 e0       	ldi	r24, 0x06	; 6
+    7e72:	05 c0       	rjmp	.+10     	; 0x7e7e <main+0x7e>
       } else if (which == 0x81) {
-    7e70:	01 38       	cpi	r16, 0x81	; 129
-    7e72:	11 f4       	brne	.+4      	; 0x7e78 <main+0x78>
+    7e74:	01 38       	cpi	r16, 0x81	; 129
+    7e76:	11 f4       	brne	.+4      	; 0x7e7c <main+0x7c>
 	  putch(OPTIBOOT_MAJVER);
-    7e74:	84 e0       	ldi	r24, 0x04	; 4
-    7e76:	01 c0       	rjmp	.+2      	; 0x7e7a <main+0x7a>
+    7e78:	84 e0       	ldi	r24, 0x04	; 4
+    7e7a:	01 c0       	rjmp	.+2      	; 0x7e7e <main+0x7e>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    7e78:	83 e0       	ldi	r24, 0x03	; 3
-    7e7a:	8d d0       	rcall	.+282    	; 0x7f96 <putch>
-    7e7c:	89 c0       	rjmp	.+274    	; 0x7f90 <main+0x190>
+    7e7c:	83 e0       	ldi	r24, 0x03	; 3
+    7e7e:	83 d0       	rcall	.+262    	; 0x7f86 <putch>
+    7e80:	7f c0       	rjmp	.+254    	; 0x7f80 <main+0x180>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    7e7e:	82 34       	cpi	r24, 0x42	; 66
-    7e80:	11 f4       	brne	.+4      	; 0x7e86 <main+0x86>
+    7e82:	82 34       	cpi	r24, 0x42	; 66
+    7e84:	11 f4       	brne	.+4      	; 0x7e8a <main+0x8a>
       // SET DEVICE is ignored
       getNch(20);
-    7e82:	84 e1       	ldi	r24, 0x14	; 20
-    7e84:	03 c0       	rjmp	.+6      	; 0x7e8c <main+0x8c>
+    7e86:	84 e1       	ldi	r24, 0x14	; 20
+    7e88:	03 c0       	rjmp	.+6      	; 0x7e90 <main+0x90>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    7e86:	85 34       	cpi	r24, 0x45	; 69
-    7e88:	19 f4       	brne	.+6      	; 0x7e90 <main+0x90>
+    7e8a:	85 34       	cpi	r24, 0x45	; 69
+    7e8c:	19 f4       	brne	.+6      	; 0x7e94 <main+0x94>
       // SET DEVICE EXT is ignored
       getNch(5);
-    7e8a:	85 e0       	ldi	r24, 0x05	; 5
-    7e8c:	a6 d0       	rcall	.+332    	; 0x7fda <getNch>
-    7e8e:	80 c0       	rjmp	.+256    	; 0x7f90 <main+0x190>
+    7e8e:	85 e0       	ldi	r24, 0x05	; 5
+    7e90:	9c d0       	rcall	.+312    	; 0x7fca <getNch>
+    7e92:	76 c0       	rjmp	.+236    	; 0x7f80 <main+0x180>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    7e90:	85 35       	cpi	r24, 0x55	; 85
-    7e92:	79 f4       	brne	.+30     	; 0x7eb2 <main+0xb2>
+    7e94:	85 35       	cpi	r24, 0x55	; 85
+    7e96:	79 f4       	brne	.+30     	; 0x7eb6 <main+0xb6>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    7e94:	88 d0       	rcall	.+272    	; 0x7fa6 <getch>
+    7e98:	7e d0       	rcall	.+252    	; 0x7f96 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
-    7e96:	e8 2e       	mov	r14, r24
-    7e98:	ff 24       	eor	r15, r15
-    7e9a:	85 d0       	rcall	.+266    	; 0x7fa6 <getch>
-    7e9c:	08 2f       	mov	r16, r24
-    7e9e:	10 e0       	ldi	r17, 0x00	; 0
-    7ea0:	10 2f       	mov	r17, r16
-    7ea2:	00 27       	eor	r16, r16
-    7ea4:	0e 29       	or	r16, r14
-    7ea6:	1f 29       	or	r17, r15
+    7e9a:	e8 2e       	mov	r14, r24
+    7e9c:	ff 24       	eor	r15, r15
+    7e9e:	7b d0       	rcall	.+246    	; 0x7f96 <getch>
+    7ea0:	08 2f       	mov	r16, r24
+    7ea2:	10 e0       	ldi	r17, 0x00	; 0
+    7ea4:	10 2f       	mov	r17, r16
+    7ea6:	00 27       	eor	r16, r16
+    7ea8:	0e 29       	or	r16, r14
+    7eaa:	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
-    7ea8:	00 0f       	add	r16, r16
-    7eaa:	11 1f       	adc	r17, r17
+    7eac:	00 0f       	add	r16, r16
+    7eae:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    7eac:	8e d0       	rcall	.+284    	; 0x7fca <verifySpace>
-    7eae:	68 01       	movw	r12, r16
-    7eb0:	6f c0       	rjmp	.+222    	; 0x7f90 <main+0x190>
+    7eb0:	84 d0       	rcall	.+264    	; 0x7fba <verifySpace>
+    7eb2:	78 01       	movw	r14, r16
+    7eb4:	65 c0       	rjmp	.+202    	; 0x7f80 <main+0x180>
     }
     else if(ch == STK_UNIVERSAL) {
-    7eb2:	86 35       	cpi	r24, 0x56	; 86
-    7eb4:	21 f4       	brne	.+8      	; 0x7ebe <main+0xbe>
+    7eb6:	86 35       	cpi	r24, 0x56	; 86
+    7eb8:	21 f4       	brne	.+8      	; 0x7ec2 <main+0xc2>
       // UNIVERSAL command is ignored
       getNch(4);
-    7eb6:	84 e0       	ldi	r24, 0x04	; 4
-    7eb8:	90 d0       	rcall	.+288    	; 0x7fda <getNch>
+    7eba:	84 e0       	ldi	r24, 0x04	; 4
+    7ebc:	86 d0       	rcall	.+268    	; 0x7fca <getNch>
       putch(0x00);
-    7eba:	80 e0       	ldi	r24, 0x00	; 0
-    7ebc:	de cf       	rjmp	.-68     	; 0x7e7a <main+0x7a>
+    7ebe:	80 e0       	ldi	r24, 0x00	; 0
+    7ec0:	de cf       	rjmp	.-68     	; 0x7e7e <main+0x7e>
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    7ebe:	84 36       	cpi	r24, 0x64	; 100
-    7ec0:	09 f0       	breq	.+2      	; 0x7ec4 <main+0xc4>
-    7ec2:	40 c0       	rjmp	.+128    	; 0x7f44 <main+0x144>
+    7ec2:	84 36       	cpi	r24, 0x64	; 100
+    7ec4:	09 f0       	breq	.+2      	; 0x7ec8 <main+0xc8>
+    7ec6:	40 c0       	rjmp	.+128    	; 0x7f48 <main+0x148>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    7ec4:	70 d0       	rcall	.+224    	; 0x7fa6 <getch>
+    7ec8:	66 d0       	rcall	.+204    	; 0x7f96 <getch>
       length = getch();
-    7ec6:	6f d0       	rcall	.+222    	; 0x7fa6 <getch>
-    7ec8:	08 2f       	mov	r16, r24
+    7eca:	65 d0       	rcall	.+202    	; 0x7f96 <getch>
+    7ecc:	08 2f       	mov	r16, r24
       getch();
-    7eca:	6d d0       	rcall	.+218    	; 0x7fa6 <getch>
+    7ece:	63 d0       	rcall	.+198    	; 0x7f96 <getch>
 
       // If we are in RWW section, immediately start page erase
       if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    7ecc:	80 e0       	ldi	r24, 0x00	; 0
-    7ece:	c8 16       	cp	r12, r24
-    7ed0:	80 e7       	ldi	r24, 0x70	; 112
-    7ed2:	d8 06       	cpc	r13, r24
-    7ed4:	18 f4       	brcc	.+6      	; 0x7edc <main+0xdc>
-    7ed6:	f6 01       	movw	r30, r12
-    7ed8:	b7 be       	out	0x37, r11	; 55
-    7eda:	e8 95       	spm
-    7edc:	c0 e0       	ldi	r28, 0x00	; 0
-    7ede:	d1 e0       	ldi	r29, 0x01	; 1
+    7ed0:	80 e0       	ldi	r24, 0x00	; 0
+    7ed2:	e8 16       	cp	r14, r24
+    7ed4:	80 e7       	ldi	r24, 0x70	; 112
+    7ed6:	f8 06       	cpc	r15, r24
+    7ed8:	18 f4       	brcc	.+6      	; 0x7ee0 <main+0xe0>
+    7eda:	f7 01       	movw	r30, r14
+    7edc:	d7 be       	out	0x37, r13	; 55
+    7ede:	e8 95       	spm
+    7ee0:	c0 e0       	ldi	r28, 0x00	; 0
+    7ee2:	d1 e0       	ldi	r29, 0x01	; 1
 
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    7ee0:	62 d0       	rcall	.+196    	; 0x7fa6 <getch>
-    7ee2:	89 93       	st	Y+, r24
+    7ee4:	58 d0       	rcall	.+176    	; 0x7f96 <getch>
+    7ee6:	89 93       	st	Y+, r24
       while (--length);
-    7ee4:	0c 17       	cp	r16, r28
-    7ee6:	e1 f7       	brne	.-8      	; 0x7ee0 <main+0xe0>
+    7ee8:	0c 17       	cp	r16, r28
+    7eea:	e1 f7       	brne	.-8      	; 0x7ee4 <main+0xe4>
 
       // If we are in NRWW section, page erase has to be delayed until now.
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    7ee8:	f0 e0       	ldi	r31, 0x00	; 0
-    7eea:	cf 16       	cp	r12, r31
-    7eec:	f0 e7       	ldi	r31, 0x70	; 112
-    7eee:	df 06       	cpc	r13, r31
-    7ef0:	18 f0       	brcs	.+6      	; 0x7ef8 <main+0xf8>
-    7ef2:	f6 01       	movw	r30, r12
-    7ef4:	b7 be       	out	0x37, r11	; 55
-    7ef6:	e8 95       	spm
+    7eec:	f0 e0       	ldi	r31, 0x00	; 0
+    7eee:	ef 16       	cp	r14, r31
+    7ef0:	f0 e7       	ldi	r31, 0x70	; 112
+    7ef2:	ff 06       	cpc	r15, r31
+    7ef4:	18 f0       	brcs	.+6      	; 0x7efc <main+0xfc>
+    7ef6:	f7 01       	movw	r30, r14
+    7ef8:	d7 be       	out	0x37, r13	; 55
+    7efa:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    7ef8:	68 d0       	rcall	.+208    	; 0x7fca <verifySpace>
+    7efc:	5e d0       	rcall	.+188    	; 0x7fba <verifySpace>
 
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    7efa:	07 b6       	in	r0, 0x37	; 55
-    7efc:	00 fc       	sbrc	r0, 0
-    7efe:	fd cf       	rjmp	.-6      	; 0x7efa <main+0xfa>
-    7f00:	a6 01       	movw	r20, r12
-    7f02:	a0 e0       	ldi	r26, 0x00	; 0
-    7f04:	b1 e0       	ldi	r27, 0x01	; 1
+    7efe:	07 b6       	in	r0, 0x37	; 55
+    7f00:	00 fc       	sbrc	r0, 0
+    7f02:	fd cf       	rjmp	.-6      	; 0x7efe <main+0xfe>
+    7f04:	a7 01       	movw	r20, r14
+    7f06:	a0 e0       	ldi	r26, 0x00	; 0
+    7f08:	b1 e0       	ldi	r27, 0x01	; 1
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    7f06:	2c 91       	ld	r18, X
-    7f08:	30 e0       	ldi	r19, 0x00	; 0
+    7f0a:	2c 91       	ld	r18, X
+    7f0c:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    7f0a:	11 96       	adiw	r26, 0x01	; 1
-    7f0c:	8c 91       	ld	r24, X
-    7f0e:	11 97       	sbiw	r26, 0x01	; 1
-    7f10:	90 e0       	ldi	r25, 0x00	; 0
-    7f12:	98 2f       	mov	r25, r24
-    7f14:	88 27       	eor	r24, r24
-    7f16:	82 2b       	or	r24, r18
-    7f18:	93 2b       	or	r25, r19
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    7f0e:	11 96       	adiw	r26, 0x01	; 1
+    7f10:	8c 91       	ld	r24, X
+    7f12:	11 97       	sbiw	r26, 0x01	; 1
+    7f14:	90 e0       	ldi	r25, 0x00	; 0
+    7f16:	98 2f       	mov	r25, r24
+    7f18:	88 27       	eor	r24, r24
+    7f1a:	82 2b       	or	r24, r18
+    7f1c:	93 2b       	or	r25, r19
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
 int main(void) {
-    7f1a:	12 96       	adiw	r26, 0x02	; 2
+    7f1e:	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);
-    7f1c:	fa 01       	movw	r30, r20
-    7f1e:	0c 01       	movw	r0, r24
-    7f20:	87 be       	out	0x37, r8	; 55
-    7f22:	e8 95       	spm
-    7f24:	11 24       	eor	r1, r1
+    7f20:	fa 01       	movw	r30, r20
+    7f22:	0c 01       	movw	r0, r24
+    7f24:	a7 be       	out	0x37, r10	; 55
+    7f26:	e8 95       	spm
+    7f28:	11 24       	eor	r1, r1
         addrPtr += 2;
-    7f26:	4e 5f       	subi	r20, 0xFE	; 254
-    7f28:	5f 4f       	sbci	r21, 0xFF	; 255
+    7f2a:	4e 5f       	subi	r20, 0xFE	; 254
+    7f2c:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    7f2a:	f1 e0       	ldi	r31, 0x01	; 1
-    7f2c:	a0 38       	cpi	r26, 0x80	; 128
-    7f2e:	bf 07       	cpc	r27, r31
-    7f30:	51 f7       	brne	.-44     	; 0x7f06 <main+0x106>
+    7f2e:	f1 e0       	ldi	r31, 0x01	; 1
+    7f30:	a0 38       	cpi	r26, 0x80	; 128
+    7f32:	bf 07       	cpc	r27, r31
+    7f34:	51 f7       	brne	.-44     	; 0x7f0a <main+0x10a>
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    7f32:	f6 01       	movw	r30, r12
-    7f34:	a7 be       	out	0x37, r10	; 55
-    7f36:	e8 95       	spm
+    7f36:	f7 01       	movw	r30, r14
+    7f38:	c7 be       	out	0x37, r12	; 55
+    7f3a:	e8 95       	spm
       boot_spm_busy_wait();
-    7f38:	07 b6       	in	r0, 0x37	; 55
-    7f3a:	00 fc       	sbrc	r0, 0
-    7f3c:	fd cf       	rjmp	.-6      	; 0x7f38 <main+0x138>
+    7f3c:	07 b6       	in	r0, 0x37	; 55
+    7f3e:	00 fc       	sbrc	r0, 0
+    7f40:	fd cf       	rjmp	.-6      	; 0x7f3c <main+0x13c>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    7f3e:	97 be       	out	0x37, r9	; 55
-    7f40:	e8 95       	spm
-    7f42:	26 c0       	rjmp	.+76     	; 0x7f90 <main+0x190>
+    7f42:	b7 be       	out	0x37, r11	; 55
+    7f44:	e8 95       	spm
+    7f46:	1c c0       	rjmp	.+56     	; 0x7f80 <main+0x180>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    7f44:	84 37       	cpi	r24, 0x74	; 116
-    7f46:	b1 f4       	brne	.+44     	; 0x7f74 <main+0x174>
+    7f48:	84 37       	cpi	r24, 0x74	; 116
+    7f4a:	61 f4       	brne	.+24     	; 0x7f64 <main+0x164>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    7f48:	2e d0       	rcall	.+92     	; 0x7fa6 <getch>
+    7f4c:	24 d0       	rcall	.+72     	; 0x7f96 <getch>
       length = getch();
-    7f4a:	2d d0       	rcall	.+90     	; 0x7fa6 <getch>
-    7f4c:	f8 2e       	mov	r15, r24
+    7f4e:	23 d0       	rcall	.+70     	; 0x7f96 <getch>
+    7f50:	08 2f       	mov	r16, r24
       getch();
-    7f4e:	2b d0       	rcall	.+86     	; 0x7fa6 <getch>
+    7f52:	21 d0       	rcall	.+66     	; 0x7f96 <getch>
 
       verifySpace();
-    7f50:	3c d0       	rcall	.+120    	; 0x7fca <verifySpace>
-    7f52:	f6 01       	movw	r30, r12
-    7f54:	ef 2c       	mov	r14, r15
-        putch(result);
-        address++;
-      }
-      while (--length);
+    7f54:	32 d0       	rcall	.+100    	; 0x7fba <verifySpace>
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-    7f56:	8f 01       	movw	r16, r30
-    7f58:	0f 5f       	subi	r16, 0xFF	; 255
-    7f5a:	1f 4f       	sbci	r17, 0xFF	; 255
-    7f5c:	84 91       	lpm	r24, Z+
-    7f5e:	1b d0       	rcall	.+54     	; 0x7f96 <putch>
-      while (--length);
-    7f60:	ea 94       	dec	r14
-    7f62:	f8 01       	movw	r30, r16
-    7f64:	c1 f7       	brne	.-16     	; 0x7f56 <main+0x156>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-/* main program starts here */
-int main(void) {
-    7f66:	08 94       	sec
-    7f68:	c1 1c       	adc	r12, r1
-    7f6a:	d1 1c       	adc	r13, r1
-    7f6c:	fa 94       	dec	r15
-    7f6e:	cf 0c       	add	r12, r15
-    7f70:	d1 1c       	adc	r13, r1
-    7f72:	0e c0       	rjmp	.+28     	; 0x7f90 <main+0x190>
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+    7f56:	f7 01       	movw	r30, r14
+    7f58:	85 91       	lpm	r24, Z+
+    7f5a:	7f 01       	movw	r14, r30
+    7f5c:	14 d0       	rcall	.+40     	; 0x7f86 <putch>
+      } while (--length);
+    7f5e:	01 50       	subi	r16, 0x01	; 1
+    7f60:	d1 f7       	brne	.-12     	; 0x7f56 <main+0x156>
+    7f62:	0e c0       	rjmp	.+28     	; 0x7f80 <main+0x180>
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    7f74:	85 37       	cpi	r24, 0x75	; 117
-    7f76:	39 f4       	brne	.+14     	; 0x7f86 <main+0x186>
+    7f64:	85 37       	cpi	r24, 0x75	; 117
+    7f66:	39 f4       	brne	.+14     	; 0x7f76 <main+0x176>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    7f78:	28 d0       	rcall	.+80     	; 0x7fca <verifySpace>
+    7f68:	28 d0       	rcall	.+80     	; 0x7fba <verifySpace>
       putch(SIGNATURE_0);
-    7f7a:	8e e1       	ldi	r24, 0x1E	; 30
-    7f7c:	0c d0       	rcall	.+24     	; 0x7f96 <putch>
+    7f6a:	8e e1       	ldi	r24, 0x1E	; 30
+    7f6c:	0c d0       	rcall	.+24     	; 0x7f86 <putch>
       putch(SIGNATURE_1);
-    7f7e:	85 e9       	ldi	r24, 0x95	; 149
-    7f80:	0a d0       	rcall	.+20     	; 0x7f96 <putch>
+    7f6e:	85 e9       	ldi	r24, 0x95	; 149
+    7f70:	0a d0       	rcall	.+20     	; 0x7f86 <putch>
       putch(SIGNATURE_2);
-    7f82:	8f e0       	ldi	r24, 0x0F	; 15
-    7f84:	7a cf       	rjmp	.-268    	; 0x7e7a <main+0x7a>
+    7f72:	8f e0       	ldi	r24, 0x0F	; 15
+    7f74:	84 cf       	rjmp	.-248    	; 0x7e7e <main+0x7e>
     }
-    else if (ch == 'Q') {
-    7f86:	81 35       	cpi	r24, 0x51	; 81
-    7f88:	11 f4       	brne	.+4      	; 0x7f8e <main+0x18e>
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+    7f76:	81 35       	cpi	r24, 0x51	; 81
+    7f78:	11 f4       	brne	.+4      	; 0x7f7e <main+0x17e>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    7f8a:	88 e0       	ldi	r24, 0x08	; 8
-    7f8c:	18 d0       	rcall	.+48     	; 0x7fbe <watchdogConfig>
+    7f7a:	88 e0       	ldi	r24, 0x08	; 8
+    7f7c:	18 d0       	rcall	.+48     	; 0x7fae <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    7f8e:	1d d0       	rcall	.+58     	; 0x7fca <verifySpace>
+    7f7e:	1d d0       	rcall	.+58     	; 0x7fba <verifySpace>
     }
     putch(STK_OK);
-    7f90:	80 e1       	ldi	r24, 0x10	; 16
-    7f92:	01 d0       	rcall	.+2      	; 0x7f96 <putch>
-    7f94:	65 cf       	rjmp	.-310    	; 0x7e60 <main+0x60>
+    7f80:	80 e1       	ldi	r24, 0x10	; 16
+    7f82:	01 d0       	rcall	.+2      	; 0x7f86 <putch>
+    7f84:	6d cf       	rjmp	.-294    	; 0x7e60 <main+0x60>
 
-00007f96 <putch>:
+00007f86 <putch>:
   }
 }
 
 void putch(char ch) {
-    7f96:	98 2f       	mov	r25, r24
+    7f86:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-    7f98:	80 91 c0 00 	lds	r24, 0x00C0
-    7f9c:	85 ff       	sbrs	r24, 5
-    7f9e:	fc cf       	rjmp	.-8      	; 0x7f98 <putch+0x2>
-  UDR0 = ch;
-    7fa0:	90 93 c6 00 	sts	0x00C6, r25
+  while (!(UART_SRA & _BV(UDRE0)));
+    7f88:	80 91 c0 00 	lds	r24, 0x00C0
+    7f8c:	85 ff       	sbrs	r24, 5
+    7f8e:	fc cf       	rjmp	.-8      	; 0x7f88 <putch+0x2>
+  UART_UDR = ch;
+    7f90:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    7fa4:	08 95       	ret
+    7f94:	08 95       	ret
 
-00007fa6 <getch>:
+00007f96 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
-  while(!(UCSR0A & _BV(RXC0)))
-    7fa6:	80 91 c0 00 	lds	r24, 0x00C0
-    7faa:	87 ff       	sbrs	r24, 7
-    7fac:	fc cf       	rjmp	.-8      	; 0x7fa6 <getch>
+  while(!(UART_SRA & _BV(RXC0)))
+    7f96:	80 91 c0 00 	lds	r24, 0x00C0
+    7f9a:	87 ff       	sbrs	r24, 7
+    7f9c:	fc cf       	rjmp	.-8      	; 0x7f96 <getch>
     ;
-  if (!(UCSR0A & _BV(FE0))) {
-    7fae:	80 91 c0 00 	lds	r24, 0x00C0
-    7fb2:	84 fd       	sbrc	r24, 4
-    7fb4:	01 c0       	rjmp	.+2      	; 0x7fb8 <getch+0x12>
+  if (!(UART_SRA & _BV(FE0))) {
+    7f9e:	80 91 c0 00 	lds	r24, 0x00C0
+    7fa2:	84 fd       	sbrc	r24, 4
+    7fa4:	01 c0       	rjmp	.+2      	; 0x7fa8 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    7fb6:	a8 95       	wdr
+    7fa6:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
-  ch = UDR0;
-    7fb8:	80 91 c6 00 	lds	r24, 0x00C6
+  ch = UART_UDR;
+    7fa8:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    7fbc:	08 95       	ret
+    7fac:	08 95       	ret
 
-00007fbe <watchdogConfig>:
+00007fae <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7fbe:	e0 e6       	ldi	r30, 0x60	; 96
-    7fc0:	f0 e0       	ldi	r31, 0x00	; 0
-    7fc2:	98 e1       	ldi	r25, 0x18	; 24
-    7fc4:	90 83       	st	Z, r25
+    7fae:	e0 e6       	ldi	r30, 0x60	; 96
+    7fb0:	f0 e0       	ldi	r31, 0x00	; 0
+    7fb2:	98 e1       	ldi	r25, 0x18	; 24
+    7fb4:	90 83       	st	Z, r25
   WDTCSR = x;
-    7fc6:	80 83       	st	Z, r24
+    7fb6:	80 83       	st	Z, r24
 }
-    7fc8:	08 95       	ret
+    7fb8:	08 95       	ret
 
-00007fca <verifySpace>:
+00007fba <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    7fca:	ed df       	rcall	.-38     	; 0x7fa6 <getch>
-    7fcc:	80 32       	cpi	r24, 0x20	; 32
-    7fce:	19 f0       	breq	.+6      	; 0x7fd6 <verifySpace+0xc>
+    7fba:	ed df       	rcall	.-38     	; 0x7f96 <getch>
+    7fbc:	80 32       	cpi	r24, 0x20	; 32
+    7fbe:	19 f0       	breq	.+6      	; 0x7fc6 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    7fd0:	88 e0       	ldi	r24, 0x08	; 8
-    7fd2:	f5 df       	rcall	.-22     	; 0x7fbe <watchdogConfig>
-    7fd4:	ff cf       	rjmp	.-2      	; 0x7fd4 <verifySpace+0xa>
+    7fc0:	88 e0       	ldi	r24, 0x08	; 8
+    7fc2:	f5 df       	rcall	.-22     	; 0x7fae <watchdogConfig>
+    7fc4:	ff cf       	rjmp	.-2      	; 0x7fc4 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    7fd6:	84 e1       	ldi	r24, 0x14	; 20
+    7fc6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    7fd8:	de cf       	rjmp	.-68     	; 0x7f96 <putch>
+    7fc8:	de cf       	rjmp	.-68     	; 0x7f86 <putch>
 
-00007fda <getNch>:
+00007fca <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    7fda:	1f 93       	push	r17
-    7fdc:	18 2f       	mov	r17, r24
+    7fca:	1f 93       	push	r17
+    7fcc:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    7fde:	e3 df       	rcall	.-58     	; 0x7fa6 <getch>
-    7fe0:	11 50       	subi	r17, 0x01	; 1
-    7fe2:	e9 f7       	brne	.-6      	; 0x7fde <getNch+0x4>
+    7fce:	e3 df       	rcall	.-58     	; 0x7f96 <getch>
+    7fd0:	11 50       	subi	r17, 0x01	; 1
+    7fd2:	e9 f7       	brne	.-6      	; 0x7fce <getNch+0x4>
   verifySpace();
-    7fe4:	f2 df       	rcall	.-28     	; 0x7fca <verifySpace>
+    7fd4:	f2 df       	rcall	.-28     	; 0x7fba <verifySpace>
 }
-    7fe6:	1f 91       	pop	r17
-    7fe8:	08 95       	ret
+    7fd6:	1f 91       	pop	r17
+    7fd8:	08 95       	ret
 
-00007fea <appStart>:
+00007fda <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    7fea:	80 e0       	ldi	r24, 0x00	; 0
-    7fec:	e8 df       	rcall	.-48     	; 0x7fbe <watchdogConfig>
+    7fda:	80 e0       	ldi	r24, 0x00	; 0
+    7fdc:	e8 df       	rcall	.-48     	; 0x7fae <watchdogConfig>
   __asm__ __volatile__ (
-    7fee:	ee 27       	eor	r30, r30
-    7ff0:	ff 27       	eor	r31, r31
-    7ff2:	09 94       	ijmp
+    7fde:	ee 27       	eor	r30, r30
+    7fe0:	ff 27       	eor	r31, r31
+    7fe2:	09 94       	ijmp

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

@@ -1,35 +1,34 @@
-:107E0000112484B714BE81FFF0D085E080938100F7
+:107E0000112484B714BE81FFE8D085E080938100FF
 :107E100082E08093C00088E18093C10086E0809377
-:107E2000C20088E08093C4008EE0C9D0259A86E025
+:107E2000C20088E08093C4008EE0C1D0259A86E02D
 :107E300028E13EEF91E0309385002093840096BBCB
-:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
-:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
-:107E6000A2D0813461F49FD0082FAFD0023811F036
-:107E7000013811F484E001C083E08DD089C08234E0
-:107E800011F484E103C0853419F485E0A6D080C0E4
-:107E9000853579F488D0E82EFF2485D0082F10E0AE
-:107EA000102F00270E291F29000F111F8ED06801E7
-:107EB0006FC0863521F484E090D080E0DECF843638
-:107EC00009F040C070D06FD0082F6DD080E0C81688
-:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
-:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
-:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
-:107F0000A601A0E0B1E02C9130E011968C91119780
-:107F100090E0982F8827822B932B1296FA010C0160
-:107F200087BEE89511244E5F5F4FF1E0A038BF0790
-:107F300051F7F601A7BEE89507B600FCFDCF97BE46
-:107F4000E89526C08437B1F42ED02DD0F82E2BD052
-:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
-:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
-:107F7000D11C0EC0853739F428D08EE10CD085E9AC
-:107F80000AD08FE07ACF813511F488E018D01DD067
-:107F900080E101D065CF982F8091C00085FFFCCF94
-:107FA0009093C60008958091C00087FFFCCF809118
-:107FB000C00084FD01C0A8958091C6000895E0E648
-:107FC000F0E098E1908380830895EDDF803219F02E
-:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
-:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
-:047FF000FF270994CA
-:027FFE00040479
+:107E4000B09BFECF1D9AA8958150A9F7EE24FF2480
+:107E5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2E45
+:107E60009AD0813471F497D0082FA7D0023811F43A
+:107E700086E005C0013811F484E001C083E083D0BE
+:107E80007FC0823411F484E103C0853419F485E0A5
+:107E90009CD076C0853579F47ED0E82EFF247BD047
+:107EA000082F10E0102F00270E291F29000F111F87
+:107EB00084D0780165C0863521F484E086D080E0E6
+:107EC000DECF843609F040C066D065D0082F63D07D
+:107ED00080E0E81680E7F80618F4F701D7BEE895C9
+:107EE000C0E0D1E058D089930C17E1F7F0E0EF162D
+:107EF000F0E7FF0618F0F701D7BEE8955ED007B6A9
+:107F000000FCFDCFA701A0E0B1E02C9130E011967C
+:107F10008C91119790E0982F8827822B932B1296A3
+:107F2000FA010C01A7BEE89511244E5F5F4FF1E006
+:107F3000A038BF0751F7F701C7BEE89507B600FCA8
+:107F4000FDCFB7BEE8951CC0843761F424D023D0A0
+:107F5000082F21D032D0F70185917F0114D0015034
+:107F6000D1F70EC0853739F428D08EE10CD085E9E1
+:107F70000AD08FE084CF813511F488E018D01DD06D
+:107F800080E101D06DCF982F8091C00085FFFCCF9C
+:107F90009093C60008958091C00087FFFCCF809128
+:107FA000C00084FD01C0A8958091C6000895E0E658
+:107FB000F0E098E1908380830895EDDF803219F03E
+:107FC00088E0F5DFFFCF84E1DECF1F93182FE3DFDA
+:107FD0001150E9F7F2DF1F91089580E0E8DFEE2706
+:047FE000FF270994DA
+:027FFE00060477
 :0400000300007E007B
 :00000001FF

+ 231 - 247
optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst

@@ -3,34 +3,34 @@ optiboot_atmega328_pro_8MHz.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f4  00007e00  00007e00  00000054  2**1
+  0 .text         000001e4  00007e00  00007e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00007ffe  00007ffe  00000248  2**0
+  1 .version      00000002  00007ffe  00007ffe  00000238  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  0000024a  2**0
+  2 .debug_aranges 00000028  00000000  00000000  0000023a  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000005f  00000000  00000000  00000272  2**0
+  3 .debug_pubnames 0000005f  00000000  00000000  00000262  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002a8  00000000  00000000  000002d1  2**0
+  4 .debug_info   0000027e  00000000  00000000  000002c1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000178  00000000  00000000  00000579  2**0
+  5 .debug_abbrev 0000016b  00000000  00000000  0000053f  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000046b  00000000  00000000  000006f1  2**0
+  6 .debug_line   00000468  00000000  00000000  000006aa  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000b5c  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000b14  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000143  00000000  00000000  00000bdc  2**0
+  8 .debug_str    00000128  00000000  00000000  00000b94  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d8  00000000  00000000  00000d1f  2**0
+  9 .debug_loc    00000253  00000000  00000000  00000cbc  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000078  00000000  00000000  00000ff7  2**0
+ 10 .debug_ranges 00000078  00000000  00000000  00000f0f  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00007e00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,7 +47,7 @@ int main(void) {
     7e04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     7e06:	81 ff       	sbrs	r24, 1
-    7e08:	f0 d0       	rcall	.+480    	; 0x7fea <appStart>
+    7e08:	e8 d0       	rcall	.+464    	; 0x7fda <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -59,16 +59,16 @@ int main(void) {
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
-  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UART_SRA = _BV(U2X0); //Double speed mode USART0
     7e10:	82 e0       	ldi	r24, 0x02	; 2
     7e12:	80 93 c0 00 	sts	0x00C0, r24
-  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
     7e16:	88 e1       	ldi	r24, 0x18	; 24
     7e18:	80 93 c1 00 	sts	0x00C1, r24
-  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
     7e1c:	86 e0       	ldi	r24, 0x06	; 6
     7e1e:	80 93 c2 00 	sts	0x00C2, r24
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
     7e22:	88 e0       	ldi	r24, 0x08	; 8
     7e24:	80 93 c4 00 	sts	0x00C4, r24
 #endif
@@ -77,7 +77,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     7e28:	8e e0       	ldi	r24, 0x0E	; 14
-    7e2a:	c9 d0       	rcall	.+402    	; 0x7fbe <watchdogConfig>
+    7e2a:	c1 d0       	rcall	.+386    	; 0x7fae <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -126,30 +126,30 @@ void watchdogReset() {
   } while (--count);
     7e48:	81 50       	subi	r24, 0x01	; 1
     7e4a:	a9 f7       	brne	.-22     	; 0x7e36 <main+0x36>
-    7e4c:	cc 24       	eor	r12, r12
-    7e4e:	dd 24       	eor	r13, r13
+    7e4c:	ee 24       	eor	r14, r14
+    7e4e:	ff 24       	eor	r15, r15
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7e50:	88 24       	eor	r8, r8
-    7e52:	83 94       	inc	r8
+    7e50:	aa 24       	eor	r10, r10
+    7e52:	a3 94       	inc	r10
         addrPtr += 2;
       } while (--ch);
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     7e54:	b5 e0       	ldi	r27, 0x05	; 5
-    7e56:	ab 2e       	mov	r10, r27
+    7e56:	cb 2e       	mov	r12, r27
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     7e58:	a1 e1       	ldi	r26, 0x11	; 17
-    7e5a:	9a 2e       	mov	r9, r26
+    7e5a:	ba 2e       	mov	r11, r26
       do *bufPtr++ = getch();
       while (--length);
 
@@ -157,442 +157,426 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     7e5c:	f3 e0       	ldi	r31, 0x03	; 3
-    7e5e:	bf 2e       	mov	r11, r31
+    7e5e:	df 2e       	mov	r13, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    7e60:	a2 d0       	rcall	.+324    	; 0x7fa6 <getch>
+    7e60:	9a d0       	rcall	.+308    	; 0x7f96 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     7e62:	81 34       	cpi	r24, 0x41	; 65
-    7e64:	61 f4       	brne	.+24     	; 0x7e7e <main+0x7e>
+    7e64:	71 f4       	brne	.+28     	; 0x7e82 <main+0x82>
       unsigned char which = getch();
-    7e66:	9f d0       	rcall	.+318    	; 0x7fa6 <getch>
+    7e66:	97 d0       	rcall	.+302    	; 0x7f96 <getch>
     7e68:	08 2f       	mov	r16, r24
       verifySpace();
-    7e6a:	af d0       	rcall	.+350    	; 0x7fca <verifySpace>
+    7e6a:	a7 d0       	rcall	.+334    	; 0x7fba <verifySpace>
       if (which == 0x82) {
     7e6c:	02 38       	cpi	r16, 0x82	; 130
-    7e6e:	11 f0       	breq	.+4      	; 0x7e74 <main+0x74>
+    7e6e:	11 f4       	brne	.+4      	; 0x7e74 <main+0x74>
 	/*
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
+    7e70:	86 e0       	ldi	r24, 0x06	; 6
+    7e72:	05 c0       	rjmp	.+10     	; 0x7e7e <main+0x7e>
       } else if (which == 0x81) {
-    7e70:	01 38       	cpi	r16, 0x81	; 129
-    7e72:	11 f4       	brne	.+4      	; 0x7e78 <main+0x78>
+    7e74:	01 38       	cpi	r16, 0x81	; 129
+    7e76:	11 f4       	brne	.+4      	; 0x7e7c <main+0x7c>
 	  putch(OPTIBOOT_MAJVER);
-    7e74:	84 e0       	ldi	r24, 0x04	; 4
-    7e76:	01 c0       	rjmp	.+2      	; 0x7e7a <main+0x7a>
+    7e78:	84 e0       	ldi	r24, 0x04	; 4
+    7e7a:	01 c0       	rjmp	.+2      	; 0x7e7e <main+0x7e>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    7e78:	83 e0       	ldi	r24, 0x03	; 3
-    7e7a:	8d d0       	rcall	.+282    	; 0x7f96 <putch>
-    7e7c:	89 c0       	rjmp	.+274    	; 0x7f90 <main+0x190>
+    7e7c:	83 e0       	ldi	r24, 0x03	; 3
+    7e7e:	83 d0       	rcall	.+262    	; 0x7f86 <putch>
+    7e80:	7f c0       	rjmp	.+254    	; 0x7f80 <main+0x180>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    7e7e:	82 34       	cpi	r24, 0x42	; 66
-    7e80:	11 f4       	brne	.+4      	; 0x7e86 <main+0x86>
+    7e82:	82 34       	cpi	r24, 0x42	; 66
+    7e84:	11 f4       	brne	.+4      	; 0x7e8a <main+0x8a>
       // SET DEVICE is ignored
       getNch(20);
-    7e82:	84 e1       	ldi	r24, 0x14	; 20
-    7e84:	03 c0       	rjmp	.+6      	; 0x7e8c <main+0x8c>
+    7e86:	84 e1       	ldi	r24, 0x14	; 20
+    7e88:	03 c0       	rjmp	.+6      	; 0x7e90 <main+0x90>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    7e86:	85 34       	cpi	r24, 0x45	; 69
-    7e88:	19 f4       	brne	.+6      	; 0x7e90 <main+0x90>
+    7e8a:	85 34       	cpi	r24, 0x45	; 69
+    7e8c:	19 f4       	brne	.+6      	; 0x7e94 <main+0x94>
       // SET DEVICE EXT is ignored
       getNch(5);
-    7e8a:	85 e0       	ldi	r24, 0x05	; 5
-    7e8c:	a6 d0       	rcall	.+332    	; 0x7fda <getNch>
-    7e8e:	80 c0       	rjmp	.+256    	; 0x7f90 <main+0x190>
+    7e8e:	85 e0       	ldi	r24, 0x05	; 5
+    7e90:	9c d0       	rcall	.+312    	; 0x7fca <getNch>
+    7e92:	76 c0       	rjmp	.+236    	; 0x7f80 <main+0x180>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    7e90:	85 35       	cpi	r24, 0x55	; 85
-    7e92:	79 f4       	brne	.+30     	; 0x7eb2 <main+0xb2>
+    7e94:	85 35       	cpi	r24, 0x55	; 85
+    7e96:	79 f4       	brne	.+30     	; 0x7eb6 <main+0xb6>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    7e94:	88 d0       	rcall	.+272    	; 0x7fa6 <getch>
+    7e98:	7e d0       	rcall	.+252    	; 0x7f96 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
-    7e96:	e8 2e       	mov	r14, r24
-    7e98:	ff 24       	eor	r15, r15
-    7e9a:	85 d0       	rcall	.+266    	; 0x7fa6 <getch>
-    7e9c:	08 2f       	mov	r16, r24
-    7e9e:	10 e0       	ldi	r17, 0x00	; 0
-    7ea0:	10 2f       	mov	r17, r16
-    7ea2:	00 27       	eor	r16, r16
-    7ea4:	0e 29       	or	r16, r14
-    7ea6:	1f 29       	or	r17, r15
+    7e9a:	e8 2e       	mov	r14, r24
+    7e9c:	ff 24       	eor	r15, r15
+    7e9e:	7b d0       	rcall	.+246    	; 0x7f96 <getch>
+    7ea0:	08 2f       	mov	r16, r24
+    7ea2:	10 e0       	ldi	r17, 0x00	; 0
+    7ea4:	10 2f       	mov	r17, r16
+    7ea6:	00 27       	eor	r16, r16
+    7ea8:	0e 29       	or	r16, r14
+    7eaa:	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
-    7ea8:	00 0f       	add	r16, r16
-    7eaa:	11 1f       	adc	r17, r17
+    7eac:	00 0f       	add	r16, r16
+    7eae:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    7eac:	8e d0       	rcall	.+284    	; 0x7fca <verifySpace>
-    7eae:	68 01       	movw	r12, r16
-    7eb0:	6f c0       	rjmp	.+222    	; 0x7f90 <main+0x190>
+    7eb0:	84 d0       	rcall	.+264    	; 0x7fba <verifySpace>
+    7eb2:	78 01       	movw	r14, r16
+    7eb4:	65 c0       	rjmp	.+202    	; 0x7f80 <main+0x180>
     }
     else if(ch == STK_UNIVERSAL) {
-    7eb2:	86 35       	cpi	r24, 0x56	; 86
-    7eb4:	21 f4       	brne	.+8      	; 0x7ebe <main+0xbe>
+    7eb6:	86 35       	cpi	r24, 0x56	; 86
+    7eb8:	21 f4       	brne	.+8      	; 0x7ec2 <main+0xc2>
       // UNIVERSAL command is ignored
       getNch(4);
-    7eb6:	84 e0       	ldi	r24, 0x04	; 4
-    7eb8:	90 d0       	rcall	.+288    	; 0x7fda <getNch>
+    7eba:	84 e0       	ldi	r24, 0x04	; 4
+    7ebc:	86 d0       	rcall	.+268    	; 0x7fca <getNch>
       putch(0x00);
-    7eba:	80 e0       	ldi	r24, 0x00	; 0
-    7ebc:	de cf       	rjmp	.-68     	; 0x7e7a <main+0x7a>
+    7ebe:	80 e0       	ldi	r24, 0x00	; 0
+    7ec0:	de cf       	rjmp	.-68     	; 0x7e7e <main+0x7e>
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    7ebe:	84 36       	cpi	r24, 0x64	; 100
-    7ec0:	09 f0       	breq	.+2      	; 0x7ec4 <main+0xc4>
-    7ec2:	40 c0       	rjmp	.+128    	; 0x7f44 <main+0x144>
+    7ec2:	84 36       	cpi	r24, 0x64	; 100
+    7ec4:	09 f0       	breq	.+2      	; 0x7ec8 <main+0xc8>
+    7ec6:	40 c0       	rjmp	.+128    	; 0x7f48 <main+0x148>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    7ec4:	70 d0       	rcall	.+224    	; 0x7fa6 <getch>
+    7ec8:	66 d0       	rcall	.+204    	; 0x7f96 <getch>
       length = getch();
-    7ec6:	6f d0       	rcall	.+222    	; 0x7fa6 <getch>
-    7ec8:	08 2f       	mov	r16, r24
+    7eca:	65 d0       	rcall	.+202    	; 0x7f96 <getch>
+    7ecc:	08 2f       	mov	r16, r24
       getch();
-    7eca:	6d d0       	rcall	.+218    	; 0x7fa6 <getch>
+    7ece:	63 d0       	rcall	.+198    	; 0x7f96 <getch>
 
       // If we are in RWW section, immediately start page erase
       if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    7ecc:	80 e0       	ldi	r24, 0x00	; 0
-    7ece:	c8 16       	cp	r12, r24
-    7ed0:	80 e7       	ldi	r24, 0x70	; 112
-    7ed2:	d8 06       	cpc	r13, r24
-    7ed4:	18 f4       	brcc	.+6      	; 0x7edc <main+0xdc>
-    7ed6:	f6 01       	movw	r30, r12
-    7ed8:	b7 be       	out	0x37, r11	; 55
-    7eda:	e8 95       	spm
-    7edc:	c0 e0       	ldi	r28, 0x00	; 0
-    7ede:	d1 e0       	ldi	r29, 0x01	; 1
+    7ed0:	80 e0       	ldi	r24, 0x00	; 0
+    7ed2:	e8 16       	cp	r14, r24
+    7ed4:	80 e7       	ldi	r24, 0x70	; 112
+    7ed6:	f8 06       	cpc	r15, r24
+    7ed8:	18 f4       	brcc	.+6      	; 0x7ee0 <main+0xe0>
+    7eda:	f7 01       	movw	r30, r14
+    7edc:	d7 be       	out	0x37, r13	; 55
+    7ede:	e8 95       	spm
+    7ee0:	c0 e0       	ldi	r28, 0x00	; 0
+    7ee2:	d1 e0       	ldi	r29, 0x01	; 1
 
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    7ee0:	62 d0       	rcall	.+196    	; 0x7fa6 <getch>
-    7ee2:	89 93       	st	Y+, r24
+    7ee4:	58 d0       	rcall	.+176    	; 0x7f96 <getch>
+    7ee6:	89 93       	st	Y+, r24
       while (--length);
-    7ee4:	0c 17       	cp	r16, r28
-    7ee6:	e1 f7       	brne	.-8      	; 0x7ee0 <main+0xe0>
+    7ee8:	0c 17       	cp	r16, r28
+    7eea:	e1 f7       	brne	.-8      	; 0x7ee4 <main+0xe4>
 
       // If we are in NRWW section, page erase has to be delayed until now.
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    7ee8:	f0 e0       	ldi	r31, 0x00	; 0
-    7eea:	cf 16       	cp	r12, r31
-    7eec:	f0 e7       	ldi	r31, 0x70	; 112
-    7eee:	df 06       	cpc	r13, r31
-    7ef0:	18 f0       	brcs	.+6      	; 0x7ef8 <main+0xf8>
-    7ef2:	f6 01       	movw	r30, r12
-    7ef4:	b7 be       	out	0x37, r11	; 55
-    7ef6:	e8 95       	spm
+    7eec:	f0 e0       	ldi	r31, 0x00	; 0
+    7eee:	ef 16       	cp	r14, r31
+    7ef0:	f0 e7       	ldi	r31, 0x70	; 112
+    7ef2:	ff 06       	cpc	r15, r31
+    7ef4:	18 f0       	brcs	.+6      	; 0x7efc <main+0xfc>
+    7ef6:	f7 01       	movw	r30, r14
+    7ef8:	d7 be       	out	0x37, r13	; 55
+    7efa:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    7ef8:	68 d0       	rcall	.+208    	; 0x7fca <verifySpace>
+    7efc:	5e d0       	rcall	.+188    	; 0x7fba <verifySpace>
 
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    7efa:	07 b6       	in	r0, 0x37	; 55
-    7efc:	00 fc       	sbrc	r0, 0
-    7efe:	fd cf       	rjmp	.-6      	; 0x7efa <main+0xfa>
-    7f00:	a6 01       	movw	r20, r12
-    7f02:	a0 e0       	ldi	r26, 0x00	; 0
-    7f04:	b1 e0       	ldi	r27, 0x01	; 1
+    7efe:	07 b6       	in	r0, 0x37	; 55
+    7f00:	00 fc       	sbrc	r0, 0
+    7f02:	fd cf       	rjmp	.-6      	; 0x7efe <main+0xfe>
+    7f04:	a7 01       	movw	r20, r14
+    7f06:	a0 e0       	ldi	r26, 0x00	; 0
+    7f08:	b1 e0       	ldi	r27, 0x01	; 1
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    7f06:	2c 91       	ld	r18, X
-    7f08:	30 e0       	ldi	r19, 0x00	; 0
+    7f0a:	2c 91       	ld	r18, X
+    7f0c:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    7f0a:	11 96       	adiw	r26, 0x01	; 1
-    7f0c:	8c 91       	ld	r24, X
-    7f0e:	11 97       	sbiw	r26, 0x01	; 1
-    7f10:	90 e0       	ldi	r25, 0x00	; 0
-    7f12:	98 2f       	mov	r25, r24
-    7f14:	88 27       	eor	r24, r24
-    7f16:	82 2b       	or	r24, r18
-    7f18:	93 2b       	or	r25, r19
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    7f0e:	11 96       	adiw	r26, 0x01	; 1
+    7f10:	8c 91       	ld	r24, X
+    7f12:	11 97       	sbiw	r26, 0x01	; 1
+    7f14:	90 e0       	ldi	r25, 0x00	; 0
+    7f16:	98 2f       	mov	r25, r24
+    7f18:	88 27       	eor	r24, r24
+    7f1a:	82 2b       	or	r24, r18
+    7f1c:	93 2b       	or	r25, r19
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
 int main(void) {
-    7f1a:	12 96       	adiw	r26, 0x02	; 2
+    7f1e:	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);
-    7f1c:	fa 01       	movw	r30, r20
-    7f1e:	0c 01       	movw	r0, r24
-    7f20:	87 be       	out	0x37, r8	; 55
-    7f22:	e8 95       	spm
-    7f24:	11 24       	eor	r1, r1
+    7f20:	fa 01       	movw	r30, r20
+    7f22:	0c 01       	movw	r0, r24
+    7f24:	a7 be       	out	0x37, r10	; 55
+    7f26:	e8 95       	spm
+    7f28:	11 24       	eor	r1, r1
         addrPtr += 2;
-    7f26:	4e 5f       	subi	r20, 0xFE	; 254
-    7f28:	5f 4f       	sbci	r21, 0xFF	; 255
+    7f2a:	4e 5f       	subi	r20, 0xFE	; 254
+    7f2c:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    7f2a:	f1 e0       	ldi	r31, 0x01	; 1
-    7f2c:	a0 38       	cpi	r26, 0x80	; 128
-    7f2e:	bf 07       	cpc	r27, r31
-    7f30:	51 f7       	brne	.-44     	; 0x7f06 <main+0x106>
+    7f2e:	f1 e0       	ldi	r31, 0x01	; 1
+    7f30:	a0 38       	cpi	r26, 0x80	; 128
+    7f32:	bf 07       	cpc	r27, r31
+    7f34:	51 f7       	brne	.-44     	; 0x7f0a <main+0x10a>
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    7f32:	f6 01       	movw	r30, r12
-    7f34:	a7 be       	out	0x37, r10	; 55
-    7f36:	e8 95       	spm
+    7f36:	f7 01       	movw	r30, r14
+    7f38:	c7 be       	out	0x37, r12	; 55
+    7f3a:	e8 95       	spm
       boot_spm_busy_wait();
-    7f38:	07 b6       	in	r0, 0x37	; 55
-    7f3a:	00 fc       	sbrc	r0, 0
-    7f3c:	fd cf       	rjmp	.-6      	; 0x7f38 <main+0x138>
+    7f3c:	07 b6       	in	r0, 0x37	; 55
+    7f3e:	00 fc       	sbrc	r0, 0
+    7f40:	fd cf       	rjmp	.-6      	; 0x7f3c <main+0x13c>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    7f3e:	97 be       	out	0x37, r9	; 55
-    7f40:	e8 95       	spm
-    7f42:	26 c0       	rjmp	.+76     	; 0x7f90 <main+0x190>
+    7f42:	b7 be       	out	0x37, r11	; 55
+    7f44:	e8 95       	spm
+    7f46:	1c c0       	rjmp	.+56     	; 0x7f80 <main+0x180>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    7f44:	84 37       	cpi	r24, 0x74	; 116
-    7f46:	b1 f4       	brne	.+44     	; 0x7f74 <main+0x174>
+    7f48:	84 37       	cpi	r24, 0x74	; 116
+    7f4a:	61 f4       	brne	.+24     	; 0x7f64 <main+0x164>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    7f48:	2e d0       	rcall	.+92     	; 0x7fa6 <getch>
+    7f4c:	24 d0       	rcall	.+72     	; 0x7f96 <getch>
       length = getch();
-    7f4a:	2d d0       	rcall	.+90     	; 0x7fa6 <getch>
-    7f4c:	f8 2e       	mov	r15, r24
+    7f4e:	23 d0       	rcall	.+70     	; 0x7f96 <getch>
+    7f50:	08 2f       	mov	r16, r24
       getch();
-    7f4e:	2b d0       	rcall	.+86     	; 0x7fa6 <getch>
+    7f52:	21 d0       	rcall	.+66     	; 0x7f96 <getch>
 
       verifySpace();
-    7f50:	3c d0       	rcall	.+120    	; 0x7fca <verifySpace>
-    7f52:	f6 01       	movw	r30, r12
-    7f54:	ef 2c       	mov	r14, r15
-        putch(result);
-        address++;
-      }
-      while (--length);
+    7f54:	32 d0       	rcall	.+100    	; 0x7fba <verifySpace>
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-    7f56:	8f 01       	movw	r16, r30
-    7f58:	0f 5f       	subi	r16, 0xFF	; 255
-    7f5a:	1f 4f       	sbci	r17, 0xFF	; 255
-    7f5c:	84 91       	lpm	r24, Z+
-    7f5e:	1b d0       	rcall	.+54     	; 0x7f96 <putch>
-      while (--length);
-    7f60:	ea 94       	dec	r14
-    7f62:	f8 01       	movw	r30, r16
-    7f64:	c1 f7       	brne	.-16     	; 0x7f56 <main+0x156>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-/* main program starts here */
-int main(void) {
-    7f66:	08 94       	sec
-    7f68:	c1 1c       	adc	r12, r1
-    7f6a:	d1 1c       	adc	r13, r1
-    7f6c:	fa 94       	dec	r15
-    7f6e:	cf 0c       	add	r12, r15
-    7f70:	d1 1c       	adc	r13, r1
-    7f72:	0e c0       	rjmp	.+28     	; 0x7f90 <main+0x190>
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+    7f56:	f7 01       	movw	r30, r14
+    7f58:	85 91       	lpm	r24, Z+
+    7f5a:	7f 01       	movw	r14, r30
+    7f5c:	14 d0       	rcall	.+40     	; 0x7f86 <putch>
+      } while (--length);
+    7f5e:	01 50       	subi	r16, 0x01	; 1
+    7f60:	d1 f7       	brne	.-12     	; 0x7f56 <main+0x156>
+    7f62:	0e c0       	rjmp	.+28     	; 0x7f80 <main+0x180>
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    7f74:	85 37       	cpi	r24, 0x75	; 117
-    7f76:	39 f4       	brne	.+14     	; 0x7f86 <main+0x186>
+    7f64:	85 37       	cpi	r24, 0x75	; 117
+    7f66:	39 f4       	brne	.+14     	; 0x7f76 <main+0x176>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    7f78:	28 d0       	rcall	.+80     	; 0x7fca <verifySpace>
+    7f68:	28 d0       	rcall	.+80     	; 0x7fba <verifySpace>
       putch(SIGNATURE_0);
-    7f7a:	8e e1       	ldi	r24, 0x1E	; 30
-    7f7c:	0c d0       	rcall	.+24     	; 0x7f96 <putch>
+    7f6a:	8e e1       	ldi	r24, 0x1E	; 30
+    7f6c:	0c d0       	rcall	.+24     	; 0x7f86 <putch>
       putch(SIGNATURE_1);
-    7f7e:	85 e9       	ldi	r24, 0x95	; 149
-    7f80:	0a d0       	rcall	.+20     	; 0x7f96 <putch>
+    7f6e:	85 e9       	ldi	r24, 0x95	; 149
+    7f70:	0a d0       	rcall	.+20     	; 0x7f86 <putch>
       putch(SIGNATURE_2);
-    7f82:	8f e0       	ldi	r24, 0x0F	; 15
-    7f84:	7a cf       	rjmp	.-268    	; 0x7e7a <main+0x7a>
+    7f72:	8f e0       	ldi	r24, 0x0F	; 15
+    7f74:	84 cf       	rjmp	.-248    	; 0x7e7e <main+0x7e>
     }
-    else if (ch == 'Q') {
-    7f86:	81 35       	cpi	r24, 0x51	; 81
-    7f88:	11 f4       	brne	.+4      	; 0x7f8e <main+0x18e>
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+    7f76:	81 35       	cpi	r24, 0x51	; 81
+    7f78:	11 f4       	brne	.+4      	; 0x7f7e <main+0x17e>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    7f8a:	88 e0       	ldi	r24, 0x08	; 8
-    7f8c:	18 d0       	rcall	.+48     	; 0x7fbe <watchdogConfig>
+    7f7a:	88 e0       	ldi	r24, 0x08	; 8
+    7f7c:	18 d0       	rcall	.+48     	; 0x7fae <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    7f8e:	1d d0       	rcall	.+58     	; 0x7fca <verifySpace>
+    7f7e:	1d d0       	rcall	.+58     	; 0x7fba <verifySpace>
     }
     putch(STK_OK);
-    7f90:	80 e1       	ldi	r24, 0x10	; 16
-    7f92:	01 d0       	rcall	.+2      	; 0x7f96 <putch>
-    7f94:	65 cf       	rjmp	.-310    	; 0x7e60 <main+0x60>
+    7f80:	80 e1       	ldi	r24, 0x10	; 16
+    7f82:	01 d0       	rcall	.+2      	; 0x7f86 <putch>
+    7f84:	6d cf       	rjmp	.-294    	; 0x7e60 <main+0x60>
 
-00007f96 <putch>:
+00007f86 <putch>:
   }
 }
 
 void putch(char ch) {
-    7f96:	98 2f       	mov	r25, r24
+    7f86:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-    7f98:	80 91 c0 00 	lds	r24, 0x00C0
-    7f9c:	85 ff       	sbrs	r24, 5
-    7f9e:	fc cf       	rjmp	.-8      	; 0x7f98 <putch+0x2>
-  UDR0 = ch;
-    7fa0:	90 93 c6 00 	sts	0x00C6, r25
+  while (!(UART_SRA & _BV(UDRE0)));
+    7f88:	80 91 c0 00 	lds	r24, 0x00C0
+    7f8c:	85 ff       	sbrs	r24, 5
+    7f8e:	fc cf       	rjmp	.-8      	; 0x7f88 <putch+0x2>
+  UART_UDR = ch;
+    7f90:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    7fa4:	08 95       	ret
+    7f94:	08 95       	ret
 
-00007fa6 <getch>:
+00007f96 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
-  while(!(UCSR0A & _BV(RXC0)))
-    7fa6:	80 91 c0 00 	lds	r24, 0x00C0
-    7faa:	87 ff       	sbrs	r24, 7
-    7fac:	fc cf       	rjmp	.-8      	; 0x7fa6 <getch>
+  while(!(UART_SRA & _BV(RXC0)))
+    7f96:	80 91 c0 00 	lds	r24, 0x00C0
+    7f9a:	87 ff       	sbrs	r24, 7
+    7f9c:	fc cf       	rjmp	.-8      	; 0x7f96 <getch>
     ;
-  if (!(UCSR0A & _BV(FE0))) {
-    7fae:	80 91 c0 00 	lds	r24, 0x00C0
-    7fb2:	84 fd       	sbrc	r24, 4
-    7fb4:	01 c0       	rjmp	.+2      	; 0x7fb8 <getch+0x12>
+  if (!(UART_SRA & _BV(FE0))) {
+    7f9e:	80 91 c0 00 	lds	r24, 0x00C0
+    7fa2:	84 fd       	sbrc	r24, 4
+    7fa4:	01 c0       	rjmp	.+2      	; 0x7fa8 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    7fb6:	a8 95       	wdr
+    7fa6:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
-  ch = UDR0;
-    7fb8:	80 91 c6 00 	lds	r24, 0x00C6
+  ch = UART_UDR;
+    7fa8:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    7fbc:	08 95       	ret
+    7fac:	08 95       	ret
 
-00007fbe <watchdogConfig>:
+00007fae <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7fbe:	e0 e6       	ldi	r30, 0x60	; 96
-    7fc0:	f0 e0       	ldi	r31, 0x00	; 0
-    7fc2:	98 e1       	ldi	r25, 0x18	; 24
-    7fc4:	90 83       	st	Z, r25
+    7fae:	e0 e6       	ldi	r30, 0x60	; 96
+    7fb0:	f0 e0       	ldi	r31, 0x00	; 0
+    7fb2:	98 e1       	ldi	r25, 0x18	; 24
+    7fb4:	90 83       	st	Z, r25
   WDTCSR = x;
-    7fc6:	80 83       	st	Z, r24
+    7fb6:	80 83       	st	Z, r24
 }
-    7fc8:	08 95       	ret
+    7fb8:	08 95       	ret
 
-00007fca <verifySpace>:
+00007fba <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    7fca:	ed df       	rcall	.-38     	; 0x7fa6 <getch>
-    7fcc:	80 32       	cpi	r24, 0x20	; 32
-    7fce:	19 f0       	breq	.+6      	; 0x7fd6 <verifySpace+0xc>
+    7fba:	ed df       	rcall	.-38     	; 0x7f96 <getch>
+    7fbc:	80 32       	cpi	r24, 0x20	; 32
+    7fbe:	19 f0       	breq	.+6      	; 0x7fc6 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    7fd0:	88 e0       	ldi	r24, 0x08	; 8
-    7fd2:	f5 df       	rcall	.-22     	; 0x7fbe <watchdogConfig>
-    7fd4:	ff cf       	rjmp	.-2      	; 0x7fd4 <verifySpace+0xa>
+    7fc0:	88 e0       	ldi	r24, 0x08	; 8
+    7fc2:	f5 df       	rcall	.-22     	; 0x7fae <watchdogConfig>
+    7fc4:	ff cf       	rjmp	.-2      	; 0x7fc4 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    7fd6:	84 e1       	ldi	r24, 0x14	; 20
+    7fc6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    7fd8:	de cf       	rjmp	.-68     	; 0x7f96 <putch>
+    7fc8:	de cf       	rjmp	.-68     	; 0x7f86 <putch>
 
-00007fda <getNch>:
+00007fca <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    7fda:	1f 93       	push	r17
-    7fdc:	18 2f       	mov	r17, r24
+    7fca:	1f 93       	push	r17
+    7fcc:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    7fde:	e3 df       	rcall	.-58     	; 0x7fa6 <getch>
-    7fe0:	11 50       	subi	r17, 0x01	; 1
-    7fe2:	e9 f7       	brne	.-6      	; 0x7fde <getNch+0x4>
+    7fce:	e3 df       	rcall	.-58     	; 0x7f96 <getch>
+    7fd0:	11 50       	subi	r17, 0x01	; 1
+    7fd2:	e9 f7       	brne	.-6      	; 0x7fce <getNch+0x4>
   verifySpace();
-    7fe4:	f2 df       	rcall	.-28     	; 0x7fca <verifySpace>
+    7fd4:	f2 df       	rcall	.-28     	; 0x7fba <verifySpace>
 }
-    7fe6:	1f 91       	pop	r17
-    7fe8:	08 95       	ret
+    7fd6:	1f 91       	pop	r17
+    7fd8:	08 95       	ret
 
-00007fea <appStart>:
+00007fda <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    7fea:	80 e0       	ldi	r24, 0x00	; 0
-    7fec:	e8 df       	rcall	.-48     	; 0x7fbe <watchdogConfig>
+    7fda:	80 e0       	ldi	r24, 0x00	; 0
+    7fdc:	e8 df       	rcall	.-48     	; 0x7fae <watchdogConfig>
   __asm__ __volatile__ (
-    7fee:	ee 27       	eor	r30, r30
-    7ff0:	ff 27       	eor	r31, r31
-    7ff2:	09 94       	ijmp
+    7fde:	ee 27       	eor	r30, r30
+    7fe0:	ff 27       	eor	r31, r31
+    7fe2:	09 94       	ijmp

+ 28 - 29
optiboot/bootloaders/optiboot/optiboot_atmega644p.hex

@@ -1,35 +1,34 @@
-:020000000504F5
-:10FC0000112484B714BE81FFF2D085E08093810077
+:10FC0000112484B714BE81FFE8D085E08093810081
 :10FC100082E08093C00088E18093C10086E08093F9
-:10FC2000C20080E18093C4008EE0CBD0209A86E0B1
+:10FC2000C20080E18093C4008EE0C1D0209A86E0BB
 :10FC300020E33CEF91E0309385002093840096BB55
-:10FC4000B09BFECF189AA8958150A9F7CC24DD244B
-:10FC500088248394B5E0AB2EA1E19A2EF3E0BF2E69
-:10FC6000A4D0813471F4A1D0082FB1D0023811F49E
-:10FC700085E005C0013811F484E001C083E08DD037
-:10FC800089C0823411F484E103C0853419F485E01D
-:10FC9000A6D080C0853579F488D0E82EFF2485D0A1
+:10FC4000B09BFECF189AA8958150A9F7EE24FF2407
+:10FC5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2EC7
+:10FC60009AD0813471F497D0082FA7D0023811F4BC
+:10FC700086E005C0013811F484E001C083E083D040
+:10FC80007FC0823411F484E103C0853419F485E027
+:10FC90009CD076C0853579F47ED0E82EFF247BD0C9
 :10FCA000082F10E0102F00270E291F29000F111F09
-:10FCB0008ED068016FC0863521F484E090D080E05A
-:10FCC000DECF843609F040C070D06FD0082F6DD0E1
-:10FCD00080E0C81680EED80618F4F601B7BEE895A5
-:10FCE000C0E0D1E062D089930C17E1F7F0E0CF16C5
-:10FCF000F0EEDF0618F0F601B7BEE89568D007B65B
-:10FD000000FCFDCFA601A0E0B1E02C9130E01196FF
+:10FCB00084D0780165C0863521F484E086D080E068
+:10FCC000DECF843609F040C066D065D0082F63D0FF
+:10FCD00080E0E81680EEF80618F4F701D7BEE89544
+:10FCE000C0E0D1E058D089930C17E1F7F0E0EF16AF
+:10FCF000F0EEFF0618F0F701D7BEE8955ED007B624
+:10FD000000FCFDCFA701A0E0B1E02C9130E01196FE
 :10FD10008C91119790E0982F8827822B932B129625
-:10FD2000FA010C0187BEE89511244E5F5F4FF2E0A7
-:10FD3000A030BF0751F7F601A7BEE89507B600FC53
-:10FD4000FDCF97BEE89526C08437B1F42ED02DD0D4
-:10FD5000F82E2BD03CD0F601EF2C8F010F5F1F4FF8
-:10FD600084911BD0EA94F801C1F70894C11CD11CFE
-:10FD7000FA94CF0CD11C0EC0853739F428D08EE10F
-:10FD80000CD086E90AD08AE07ACF813511F488E078
-:10FD900018D01DD080E101D063CF982F8091C00092
-:10FDA00085FFFCCF9093C60008958091C00087FF27
-:10FDB000FCCF8091C00084FD01C0A8958091C60051
-:10FDC0000895E0E6F0E098E1908380830895EDDF08
-:10FDD000803219F088E0F5DFFFCF84E1DECF1F939A
-:10FDE000182FE3DF1150E9F7F2DF1F91089580E04B
-:08FDF000E8DFEE27FF2709946C
+:10FD2000FA010C01A7BEE89511244E5F5F4FF2E087
+:10FD3000A030BF0751F7F701C7BEE89507B600FC32
+:10FD4000FDCFB7BEE8951CC0843761F424D023D022
+:10FD5000082F21D032D0F70185917F0114D00150B6
+:10FD6000D1F70EC0853739F428D08EE10CD086E962
+:10FD70000AD08AE084CF813511F488E018D01DD0F4
+:10FD800080E101D06DCF982F8091C00085FFFCCF1E
+:10FD90009093C60008958091C00087FFFCCF8091AA
+:10FDA000C00084FD01C0A8958091C6000895E0E6DA
+:10FDB000F0E098E1908380830895EDDF803219F0C0
+:10FDC00088E0F5DFFFCF84E1DECF1F93182FE3DF5C
+:10FDD0001150E9F7F2DF1F91089580E0E8DFEE2788
+:04FDE000FF2709945C
+:02FFFE000604F7
 :040000030000FC00FD
 :00000001FF

+ 150 - 168
optiboot/bootloaders/optiboot/optiboot_atmega644p.lst

@@ -3,34 +3,34 @@ optiboot_atmega644p.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f8  0000fc00  0000fc00  00000054  2**1
+  0 .text         000001e4  0000fc00  0000fc00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
+  1 .version      00000002  0000fffe  0000fffe  00000238  2**0
+                  CONTENTS, READONLY
+  2 .debug_aranges 00000028  00000000  00000000  0000023a  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000005f  00000000  00000000  00000274  2**0
+  3 .debug_pubnames 0000005f  00000000  00000000  00000262  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   000002a8  00000000  00000000  000002d3  2**0
+  4 .debug_info   0000027e  00000000  00000000  000002c1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 00000178  00000000  00000000  0000057b  2**0
+  5 .debug_abbrev 0000016b  00000000  00000000  0000053f  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   00000473  00000000  00000000  000006f3  2**0
+  6 .debug_line   00000468  00000000  00000000  000006aa  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000080  00000000  00000000  00000b68  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000b14  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    0000013b  00000000  00000000  00000be8  2**0
+  8 .debug_str    00000128  00000000  00000000  00000b94  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000002d8  00000000  00000000  00000d23  2**0
+  9 .debug_loc    00000253  00000000  00000000  00000cbc  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .version      00000002  00000000  00000000  00000ffb  2**0
-                  CONTENTS, READONLY
- 10 .debug_ranges 00000078  00000000  00000000  00000ffd  2**0
+ 10 .debug_ranges 00000078  00000000  00000000  00000f0f  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 0000fc00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,7 +47,7 @@ int main(void) {
     fc04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     fc06:	81 ff       	sbrs	r24, 1
-    fc08:	f2 d0       	rcall	.+484    	; 0xfdee <appStart>
+    fc08:	e8 d0       	rcall	.+464    	; 0xfdda <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -59,16 +59,16 @@ int main(void) {
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
-  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UART_SRA = _BV(U2X0); //Double speed mode USART0
     fc10:	82 e0       	ldi	r24, 0x02	; 2
     fc12:	80 93 c0 00 	sts	0x00C0, r24
-  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
     fc16:	88 e1       	ldi	r24, 0x18	; 24
     fc18:	80 93 c1 00 	sts	0x00C1, r24
-  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
     fc1c:	86 e0       	ldi	r24, 0x06	; 6
     fc1e:	80 93 c2 00 	sts	0x00C2, r24
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
     fc22:	80 e1       	ldi	r24, 0x10	; 16
     fc24:	80 93 c4 00 	sts	0x00C4, r24
 #endif
@@ -77,7 +77,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     fc28:	8e e0       	ldi	r24, 0x0E	; 14
-    fc2a:	cb d0       	rcall	.+406    	; 0xfdc2 <watchdogConfig>
+    fc2a:	c1 d0       	rcall	.+386    	; 0xfdae <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -126,30 +126,30 @@ void watchdogReset() {
   } while (--count);
     fc48:	81 50       	subi	r24, 0x01	; 1
     fc4a:	a9 f7       	brne	.-22     	; 0xfc36 <main+0x36>
-    fc4c:	cc 24       	eor	r12, r12
-    fc4e:	dd 24       	eor	r13, r13
+    fc4c:	ee 24       	eor	r14, r14
+    fc4e:	ff 24       	eor	r15, r15
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    fc50:	88 24       	eor	r8, r8
-    fc52:	83 94       	inc	r8
+    fc50:	aa 24       	eor	r10, r10
+    fc52:	a3 94       	inc	r10
         addrPtr += 2;
       } while (--ch);
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     fc54:	b5 e0       	ldi	r27, 0x05	; 5
-    fc56:	ab 2e       	mov	r10, r27
+    fc56:	cb 2e       	mov	r12, r27
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     fc58:	a1 e1       	ldi	r26, 0x11	; 17
-    fc5a:	9a 2e       	mov	r9, r26
+    fc5a:	ba 2e       	mov	r11, r26
       do *bufPtr++ = getch();
       while (--length);
 
@@ -157,23 +157,23 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     fc5c:	f3 e0       	ldi	r31, 0x03	; 3
-    fc5e:	bf 2e       	mov	r11, r31
+    fc5e:	df 2e       	mov	r13, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    fc60:	a4 d0       	rcall	.+328    	; 0xfdaa <getch>
+    fc60:	9a d0       	rcall	.+308    	; 0xfd96 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     fc62:	81 34       	cpi	r24, 0x41	; 65
     fc64:	71 f4       	brne	.+28     	; 0xfc82 <main+0x82>
       unsigned char which = getch();
-    fc66:	a1 d0       	rcall	.+322    	; 0xfdaa <getch>
+    fc66:	97 d0       	rcall	.+302    	; 0xfd96 <getch>
     fc68:	08 2f       	mov	r16, r24
       verifySpace();
-    fc6a:	b1 d0       	rcall	.+354    	; 0xfdce <verifySpace>
+    fc6a:	a7 d0       	rcall	.+334    	; 0xfdba <verifySpace>
       if (which == 0x82) {
     fc6c:	02 38       	cpi	r16, 0x82	; 130
     fc6e:	11 f4       	brne	.+4      	; 0xfc74 <main+0x74>
@@ -181,7 +181,7 @@ void watchdogReset() {
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
-    fc70:	85 e0       	ldi	r24, 0x05	; 5
+    fc70:	86 e0       	ldi	r24, 0x06	; 6
     fc72:	05 c0       	rjmp	.+10     	; 0xfc7e <main+0x7e>
       } else if (which == 0x81) {
     fc74:	01 38       	cpi	r16, 0x81	; 129
@@ -196,8 +196,8 @@ void watchdogReset() {
 	 */
 	putch(0x03);
     fc7c:	83 e0       	ldi	r24, 0x03	; 3
-    fc7e:	8d d0       	rcall	.+282    	; 0xfd9a <putch>
-    fc80:	89 c0       	rjmp	.+274    	; 0xfd94 <main+0x194>
+    fc7e:	83 d0       	rcall	.+262    	; 0xfd86 <putch>
+    fc80:	7f c0       	rjmp	.+254    	; 0xfd80 <main+0x180>
       }
     }
     else if(ch == STK_SET_DEVICE) {
@@ -214,8 +214,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     fc8e:	85 e0       	ldi	r24, 0x05	; 5
-    fc90:	a6 d0       	rcall	.+332    	; 0xfdde <getNch>
-    fc92:	80 c0       	rjmp	.+256    	; 0xfd94 <main+0x194>
+    fc90:	9c d0       	rcall	.+312    	; 0xfdca <getNch>
+    fc92:	76 c0       	rjmp	.+236    	; 0xfd80 <main+0x180>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     fc94:	85 35       	cpi	r24, 0x55	; 85
@@ -223,11 +223,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    fc98:	88 d0       	rcall	.+272    	; 0xfdaa <getch>
+    fc98:	7e d0       	rcall	.+252    	; 0xfd96 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     fc9a:	e8 2e       	mov	r14, r24
     fc9c:	ff 24       	eor	r15, r15
-    fc9e:	85 d0       	rcall	.+266    	; 0xfdaa <getch>
+    fc9e:	7b d0       	rcall	.+246    	; 0xfd96 <getch>
     fca0:	08 2f       	mov	r16, r24
     fca2:	10 e0       	ldi	r17, 0x00	; 0
     fca4:	10 2f       	mov	r17, r16
@@ -243,9 +243,9 @@ void watchdogReset() {
     fcae:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    fcb0:	8e d0       	rcall	.+284    	; 0xfdce <verifySpace>
-    fcb2:	68 01       	movw	r12, r16
-    fcb4:	6f c0       	rjmp	.+222    	; 0xfd94 <main+0x194>
+    fcb0:	84 d0       	rcall	.+264    	; 0xfdba <verifySpace>
+    fcb2:	78 01       	movw	r14, r16
+    fcb4:	65 c0       	rjmp	.+202    	; 0xfd80 <main+0x180>
     }
     else if(ch == STK_UNIVERSAL) {
     fcb6:	86 35       	cpi	r24, 0x56	; 86
@@ -253,7 +253,7 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     fcba:	84 e0       	ldi	r24, 0x04	; 4
-    fcbc:	90 d0       	rcall	.+288    	; 0xfdde <getNch>
+    fcbc:	86 d0       	rcall	.+268    	; 0xfdca <getNch>
       putch(0x00);
     fcbe:	80 e0       	ldi	r24, 0x00	; 0
     fcc0:	de cf       	rjmp	.-68     	; 0xfc7e <main+0x7e>
@@ -268,22 +268,22 @@ void watchdogReset() {
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    fcc8:	70 d0       	rcall	.+224    	; 0xfdaa <getch>
+    fcc8:	66 d0       	rcall	.+204    	; 0xfd96 <getch>
       length = getch();
-    fcca:	6f d0       	rcall	.+222    	; 0xfdaa <getch>
+    fcca:	65 d0       	rcall	.+202    	; 0xfd96 <getch>
     fccc:	08 2f       	mov	r16, r24
       getch();
-    fcce:	6d d0       	rcall	.+218    	; 0xfdaa <getch>
+    fcce:	63 d0       	rcall	.+198    	; 0xfd96 <getch>
 
       // If we are in RWW section, immediately start page erase
       if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     fcd0:	80 e0       	ldi	r24, 0x00	; 0
-    fcd2:	c8 16       	cp	r12, r24
+    fcd2:	e8 16       	cp	r14, r24
     fcd4:	80 ee       	ldi	r24, 0xE0	; 224
-    fcd6:	d8 06       	cpc	r13, r24
+    fcd6:	f8 06       	cpc	r15, r24
     fcd8:	18 f4       	brcc	.+6      	; 0xfce0 <main+0xe0>
-    fcda:	f6 01       	movw	r30, r12
-    fcdc:	b7 be       	out	0x37, r11	; 55
+    fcda:	f7 01       	movw	r30, r14
+    fcdc:	d7 be       	out	0x37, r13	; 55
     fcde:	e8 95       	spm
     fce0:	c0 e0       	ldi	r28, 0x00	; 0
     fce2:	d1 e0       	ldi	r29, 0x01	; 1
@@ -291,7 +291,7 @@ void watchdogReset() {
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    fce4:	62 d0       	rcall	.+196    	; 0xfdaa <getch>
+    fce4:	58 d0       	rcall	.+176    	; 0xfd96 <getch>
     fce6:	89 93       	st	Y+, r24
       while (--length);
     fce8:	0c 17       	cp	r16, r28
@@ -301,17 +301,17 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     fcec:	f0 e0       	ldi	r31, 0x00	; 0
-    fcee:	cf 16       	cp	r12, r31
+    fcee:	ef 16       	cp	r14, r31
     fcf0:	f0 ee       	ldi	r31, 0xE0	; 224
-    fcf2:	df 06       	cpc	r13, r31
+    fcf2:	ff 06       	cpc	r15, r31
     fcf4:	18 f0       	brcs	.+6      	; 0xfcfc <main+0xfc>
-    fcf6:	f6 01       	movw	r30, r12
-    fcf8:	b7 be       	out	0x37, r11	; 55
+    fcf6:	f7 01       	movw	r30, r14
+    fcf8:	d7 be       	out	0x37, r13	; 55
     fcfa:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    fcfc:	68 d0       	rcall	.+208    	; 0xfdce <verifySpace>
+    fcfc:	5e d0       	rcall	.+188    	; 0xfdba <verifySpace>
 
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
@@ -319,7 +319,7 @@ void watchdogReset() {
     fcfe:	07 b6       	in	r0, 0x37	; 55
     fd00:	00 fc       	sbrc	r0, 0
     fd02:	fd cf       	rjmp	.-6      	; 0xfcfe <main+0xfe>
-    fd04:	a6 01       	movw	r20, r12
+    fd04:	a7 01       	movw	r20, r14
     fd06:	a0 e0       	ldi	r26, 0x00	; 0
     fd08:	b1 e0       	ldi	r27, 0x01	; 1
       bufPtr = buff;
@@ -339,8 +339,8 @@ void watchdogReset() {
     fd18:	88 27       	eor	r24, r24
     fd1a:	82 2b       	or	r24, r18
     fd1c:	93 2b       	or	r25, r19
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -354,7 +354,7 @@ int main(void) {
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
     fd20:	fa 01       	movw	r30, r20
     fd22:	0c 01       	movw	r0, r24
-    fd24:	87 be       	out	0x37, r8	; 55
+    fd24:	a7 be       	out	0x37, r10	; 55
     fd26:	e8 95       	spm
     fd28:	11 24       	eor	r1, r1
         addrPtr += 2;
@@ -368,8 +368,8 @@ int main(void) {
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    fd36:	f6 01       	movw	r30, r12
-    fd38:	a7 be       	out	0x37, r10	; 55
+    fd36:	f7 01       	movw	r30, r14
+    fd38:	c7 be       	out	0x37, r12	; 55
     fd3a:	e8 95       	spm
       boot_spm_busy_wait();
     fd3c:	07 b6       	in	r0, 0x37	; 55
@@ -379,222 +379,204 @@ int main(void) {
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    fd42:	97 be       	out	0x37, r9	; 55
+    fd42:	b7 be       	out	0x37, r11	; 55
     fd44:	e8 95       	spm
-    fd46:	26 c0       	rjmp	.+76     	; 0xfd94 <main+0x194>
+    fd46:	1c c0       	rjmp	.+56     	; 0xfd80 <main+0x180>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     fd48:	84 37       	cpi	r24, 0x74	; 116
-    fd4a:	b1 f4       	brne	.+44     	; 0xfd78 <main+0x178>
+    fd4a:	61 f4       	brne	.+24     	; 0xfd64 <main+0x164>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    fd4c:	2e d0       	rcall	.+92     	; 0xfdaa <getch>
+    fd4c:	24 d0       	rcall	.+72     	; 0xfd96 <getch>
       length = getch();
-    fd4e:	2d d0       	rcall	.+90     	; 0xfdaa <getch>
-    fd50:	f8 2e       	mov	r15, r24
+    fd4e:	23 d0       	rcall	.+70     	; 0xfd96 <getch>
+    fd50:	08 2f       	mov	r16, r24
       getch();
-    fd52:	2b d0       	rcall	.+86     	; 0xfdaa <getch>
+    fd52:	21 d0       	rcall	.+66     	; 0xfd96 <getch>
 
       verifySpace();
-    fd54:	3c d0       	rcall	.+120    	; 0xfdce <verifySpace>
-    fd56:	f6 01       	movw	r30, r12
-    fd58:	ef 2c       	mov	r14, r15
-        putch(result);
-        address++;
-      }
-      while (--length);
+    fd54:	32 d0       	rcall	.+100    	; 0xfdba <verifySpace>
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-    fd5a:	8f 01       	movw	r16, r30
-    fd5c:	0f 5f       	subi	r16, 0xFF	; 255
-    fd5e:	1f 4f       	sbci	r17, 0xFF	; 255
-    fd60:	84 91       	lpm	r24, Z+
-    fd62:	1b d0       	rcall	.+54     	; 0xfd9a <putch>
-      while (--length);
-    fd64:	ea 94       	dec	r14
-    fd66:	f8 01       	movw	r30, r16
-    fd68:	c1 f7       	brne	.-16     	; 0xfd5a <main+0x15a>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-/* main program starts here */
-int main(void) {
-    fd6a:	08 94       	sec
-    fd6c:	c1 1c       	adc	r12, r1
-    fd6e:	d1 1c       	adc	r13, r1
-    fd70:	fa 94       	dec	r15
-    fd72:	cf 0c       	add	r12, r15
-    fd74:	d1 1c       	adc	r13, r1
-    fd76:	0e c0       	rjmp	.+28     	; 0xfd94 <main+0x194>
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+    fd56:	f7 01       	movw	r30, r14
+    fd58:	85 91       	lpm	r24, Z+
+    fd5a:	7f 01       	movw	r14, r30
+    fd5c:	14 d0       	rcall	.+40     	; 0xfd86 <putch>
+      } while (--length);
+    fd5e:	01 50       	subi	r16, 0x01	; 1
+    fd60:	d1 f7       	brne	.-12     	; 0xfd56 <main+0x156>
+    fd62:	0e c0       	rjmp	.+28     	; 0xfd80 <main+0x180>
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    fd78:	85 37       	cpi	r24, 0x75	; 117
-    fd7a:	39 f4       	brne	.+14     	; 0xfd8a <main+0x18a>
+    fd64:	85 37       	cpi	r24, 0x75	; 117
+    fd66:	39 f4       	brne	.+14     	; 0xfd76 <main+0x176>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    fd7c:	28 d0       	rcall	.+80     	; 0xfdce <verifySpace>
+    fd68:	28 d0       	rcall	.+80     	; 0xfdba <verifySpace>
       putch(SIGNATURE_0);
-    fd7e:	8e e1       	ldi	r24, 0x1E	; 30
-    fd80:	0c d0       	rcall	.+24     	; 0xfd9a <putch>
+    fd6a:	8e e1       	ldi	r24, 0x1E	; 30
+    fd6c:	0c d0       	rcall	.+24     	; 0xfd86 <putch>
       putch(SIGNATURE_1);
-    fd82:	86 e9       	ldi	r24, 0x96	; 150
-    fd84:	0a d0       	rcall	.+20     	; 0xfd9a <putch>
+    fd6e:	86 e9       	ldi	r24, 0x96	; 150
+    fd70:	0a d0       	rcall	.+20     	; 0xfd86 <putch>
       putch(SIGNATURE_2);
-    fd86:	8a e0       	ldi	r24, 0x0A	; 10
-    fd88:	7a cf       	rjmp	.-268    	; 0xfc7e <main+0x7e>
+    fd72:	8a e0       	ldi	r24, 0x0A	; 10
+    fd74:	84 cf       	rjmp	.-248    	; 0xfc7e <main+0x7e>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    fd8a:	81 35       	cpi	r24, 0x51	; 81
-    fd8c:	11 f4       	brne	.+4      	; 0xfd92 <main+0x192>
+    fd76:	81 35       	cpi	r24, 0x51	; 81
+    fd78:	11 f4       	brne	.+4      	; 0xfd7e <main+0x17e>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    fd8e:	88 e0       	ldi	r24, 0x08	; 8
-    fd90:	18 d0       	rcall	.+48     	; 0xfdc2 <watchdogConfig>
+    fd7a:	88 e0       	ldi	r24, 0x08	; 8
+    fd7c:	18 d0       	rcall	.+48     	; 0xfdae <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    fd92:	1d d0       	rcall	.+58     	; 0xfdce <verifySpace>
+    fd7e:	1d d0       	rcall	.+58     	; 0xfdba <verifySpace>
     }
     putch(STK_OK);
-    fd94:	80 e1       	ldi	r24, 0x10	; 16
-    fd96:	01 d0       	rcall	.+2      	; 0xfd9a <putch>
-    fd98:	63 cf       	rjmp	.-314    	; 0xfc60 <main+0x60>
+    fd80:	80 e1       	ldi	r24, 0x10	; 16
+    fd82:	01 d0       	rcall	.+2      	; 0xfd86 <putch>
+    fd84:	6d cf       	rjmp	.-294    	; 0xfc60 <main+0x60>
 
-0000fd9a <putch>:
+0000fd86 <putch>:
   }
 }
 
 void putch(char ch) {
-    fd9a:	98 2f       	mov	r25, r24
+    fd86:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-    fd9c:	80 91 c0 00 	lds	r24, 0x00C0
-    fda0:	85 ff       	sbrs	r24, 5
-    fda2:	fc cf       	rjmp	.-8      	; 0xfd9c <putch+0x2>
-  UDR0 = ch;
-    fda4:	90 93 c6 00 	sts	0x00C6, r25
+  while (!(UART_SRA & _BV(UDRE0)));
+    fd88:	80 91 c0 00 	lds	r24, 0x00C0
+    fd8c:	85 ff       	sbrs	r24, 5
+    fd8e:	fc cf       	rjmp	.-8      	; 0xfd88 <putch+0x2>
+  UART_UDR = ch;
+    fd90:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    fda8:	08 95       	ret
+    fd94:	08 95       	ret
 
-0000fdaa <getch>:
+0000fd96 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
-  while(!(UCSR0A & _BV(RXC0)))
-    fdaa:	80 91 c0 00 	lds	r24, 0x00C0
-    fdae:	87 ff       	sbrs	r24, 7
-    fdb0:	fc cf       	rjmp	.-8      	; 0xfdaa <getch>
+  while(!(UART_SRA & _BV(RXC0)))
+    fd96:	80 91 c0 00 	lds	r24, 0x00C0
+    fd9a:	87 ff       	sbrs	r24, 7
+    fd9c:	fc cf       	rjmp	.-8      	; 0xfd96 <getch>
     ;
-  if (!(UCSR0A & _BV(FE0))) {
-    fdb2:	80 91 c0 00 	lds	r24, 0x00C0
-    fdb6:	84 fd       	sbrc	r24, 4
-    fdb8:	01 c0       	rjmp	.+2      	; 0xfdbc <getch+0x12>
+  if (!(UART_SRA & _BV(FE0))) {
+    fd9e:	80 91 c0 00 	lds	r24, 0x00C0
+    fda2:	84 fd       	sbrc	r24, 4
+    fda4:	01 c0       	rjmp	.+2      	; 0xfda8 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    fdba:	a8 95       	wdr
+    fda6:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
-  ch = UDR0;
-    fdbc:	80 91 c6 00 	lds	r24, 0x00C6
+  ch = UART_UDR;
+    fda8:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    fdc0:	08 95       	ret
+    fdac:	08 95       	ret
 
-0000fdc2 <watchdogConfig>:
+0000fdae <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    fdc2:	e0 e6       	ldi	r30, 0x60	; 96
-    fdc4:	f0 e0       	ldi	r31, 0x00	; 0
-    fdc6:	98 e1       	ldi	r25, 0x18	; 24
-    fdc8:	90 83       	st	Z, r25
+    fdae:	e0 e6       	ldi	r30, 0x60	; 96
+    fdb0:	f0 e0       	ldi	r31, 0x00	; 0
+    fdb2:	98 e1       	ldi	r25, 0x18	; 24
+    fdb4:	90 83       	st	Z, r25
   WDTCSR = x;
-    fdca:	80 83       	st	Z, r24
+    fdb6:	80 83       	st	Z, r24
 }
-    fdcc:	08 95       	ret
+    fdb8:	08 95       	ret
 
-0000fdce <verifySpace>:
+0000fdba <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    fdce:	ed df       	rcall	.-38     	; 0xfdaa <getch>
-    fdd0:	80 32       	cpi	r24, 0x20	; 32
-    fdd2:	19 f0       	breq	.+6      	; 0xfdda <verifySpace+0xc>
+    fdba:	ed df       	rcall	.-38     	; 0xfd96 <getch>
+    fdbc:	80 32       	cpi	r24, 0x20	; 32
+    fdbe:	19 f0       	breq	.+6      	; 0xfdc6 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    fdd4:	88 e0       	ldi	r24, 0x08	; 8
-    fdd6:	f5 df       	rcall	.-22     	; 0xfdc2 <watchdogConfig>
-    fdd8:	ff cf       	rjmp	.-2      	; 0xfdd8 <verifySpace+0xa>
+    fdc0:	88 e0       	ldi	r24, 0x08	; 8
+    fdc2:	f5 df       	rcall	.-22     	; 0xfdae <watchdogConfig>
+    fdc4:	ff cf       	rjmp	.-2      	; 0xfdc4 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    fdda:	84 e1       	ldi	r24, 0x14	; 20
+    fdc6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    fddc:	de cf       	rjmp	.-68     	; 0xfd9a <putch>
+    fdc8:	de cf       	rjmp	.-68     	; 0xfd86 <putch>
 
-0000fdde <getNch>:
+0000fdca <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    fdde:	1f 93       	push	r17
-    fde0:	18 2f       	mov	r17, r24
+    fdca:	1f 93       	push	r17
+    fdcc:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    fde2:	e3 df       	rcall	.-58     	; 0xfdaa <getch>
-    fde4:	11 50       	subi	r17, 0x01	; 1
-    fde6:	e9 f7       	brne	.-6      	; 0xfde2 <getNch+0x4>
+    fdce:	e3 df       	rcall	.-58     	; 0xfd96 <getch>
+    fdd0:	11 50       	subi	r17, 0x01	; 1
+    fdd2:	e9 f7       	brne	.-6      	; 0xfdce <getNch+0x4>
   verifySpace();
-    fde8:	f2 df       	rcall	.-28     	; 0xfdce <verifySpace>
+    fdd4:	f2 df       	rcall	.-28     	; 0xfdba <verifySpace>
 }
-    fdea:	1f 91       	pop	r17
-    fdec:	08 95       	ret
+    fdd6:	1f 91       	pop	r17
+    fdd8:	08 95       	ret
 
-0000fdee <appStart>:
+0000fdda <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    fdee:	80 e0       	ldi	r24, 0x00	; 0
-    fdf0:	e8 df       	rcall	.-48     	; 0xfdc2 <watchdogConfig>
+    fdda:	80 e0       	ldi	r24, 0x00	; 0
+    fddc:	e8 df       	rcall	.-48     	; 0xfdae <watchdogConfig>
   __asm__ __volatile__ (
-    fdf2:	ee 27       	eor	r30, r30
-    fdf4:	ff 27       	eor	r31, r31
-    fdf6:	09 94       	ijmp
+    fdde:	ee 27       	eor	r30, r30
+    fde0:	ff 27       	eor	r31, r31
+    fde2:	09 94       	ijmp

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

@@ -1,35 +1,34 @@
-:103E0000112484B714BE81FFF0D085E08093810037
+:103E0000112484B714BE81FFE7D085E08093810040
 :103E100082E08093C00088E18093C10086E08093B7
-:103E2000C20088E08093C4008EE0C9D0259A86E065
+:103E2000C20088E08093C4008EE0C0D0259A86E06E
 :103E300028E13EEF91E0309385002093840096BB0B
-:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
-:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
-:103E6000A2D0813461F49FD0082FAFD0023811F076
-:103E7000013811F484E001C083E08DD089C0823420
-:103E800011F484E103C0853419F485E0A6D080C024
-:103E9000853579F488D0E82EFF2485D0082F10E0EE
-:103EA000102F00270E291F29000F111F8ED0680127
-:103EB0006FC0863521F484E090D080E0DECF843678
-:103EC00009F040C070D06FD0082F6DD080E0C816C8
-:103ED00088E3D80618F4F601B7BEE895C0E0D1E053
-:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
-:103EF00018F0F601B7BEE89568D007B600FCFDCF14
-:103F0000A601A0E0B1E02C9130E011968C911197C0
-:103F100090E0982F8827822B932B1296FA010C01A0
-:103F200087BEE89511244E5F5F4FF1E0A038BF07D0
-:103F300051F7F601A7BEE89507B600FCFDCF97BE86
-:103F4000E89526C08437B1F42ED02DD0F82E2BD092
-:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
-:103F6000EA94F801C1F70894C11CD11CFA94CF0C53
-:103F7000D11C0EC0853739F428D08EE10CD084E9ED
-:103F80000AD086E07ACF813511F488E018D01DD0B0
-:103F900080E101D065CF982F8091C00085FFFCCFD4
-:103FA0009093C60008958091C00087FFFCCF809158
-:103FB000C00084FD01C0A8958091C6000895E0E688
-:103FC000F0E098E1908380830895EDDF803219F06E
-:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
-:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
-:043FF000FF2709940A
-:023FFE000404B9
+:103E4000B09BFECF1D9AA8958150A9F7EE24FF24C0
+:103E5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2E85
+:103E600099D0813469F496D0082FA6D0023809F48D
+:103E70007FC0013811F484E001C083E083D07FC0AB
+:103E8000823411F484E103C0853419F485E09CD0B8
+:103E900076C0853579F47ED0E82EFF247BD0082FBC
+:103EA00010E0102F00270E291F29000F111F84D0AA
+:103EB000780165C0863521F484E086D080E0DECFCD
+:103EC000843609F040C066D065D0082F63D080E00A
+:103ED000E81688E3F80618F4F701D7BEE895C0E0C5
+:103EE000D1E058D089930C17E1F7F0E0EF16F8E332
+:103EF000FF0618F0F701D7BEE8955ED007B600FCC4
+:103F0000FDCFA701A0E0B1E02C9130E011968C919B
+:103F1000119790E0982F8827822B932B1296FA0105
+:103F20000C01A7BEE89511244E5F5F4FF1E0A03869
+:103F3000BF0751F7F701C7BEE89507B600FCFDCFF4
+:103F4000B7BEE8951CC0843761F424D023D0082F75
+:103F500021D032D0F70185917F0114D00150D1F7E3
+:103F60000EC0853739F428D08EE10CD084E90AD010
+:103F700086E084CF813511F488E018D01DD080E12F
+:103F800001D06ECF982F8091C00085FFFCCF909319
+:103F9000C60008958091C00087FFFCCF8091C000CB
+:103FA00084FD01C0A8958091C6000895E0E6F0E088
+:103FB00098E1908380830895EDDF803219F088E0E6
+:103FC000F5DFFFCF84E1DECF1F93182FE3DF115021
+:103FD000E9F7F2DF1F91089580E0E8DFEE27FF2781
+:023FE000099442
+:023FFE000604B7
 :0400000300003E00BB
 :00000001FF

+ 230 - 247
optiboot/bootloaders/optiboot/optiboot_lilypad.lst

@@ -3,34 +3,34 @@ optiboot_lilypad.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f4  00003e00  00003e00  00000054  2**1
+  0 .text         000001e2  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  00000248  2**0
+  1 .version      00000002  00003ffe  00003ffe  00000236  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  0000024a  2**0
+  2 .debug_aranges 00000028  00000000  00000000  00000238  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000005f  00000000  00000000  00000272  2**0
+  3 .debug_pubnames 0000005f  00000000  00000000  00000260  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002a8  00000000  00000000  000002d1  2**0
+  4 .debug_info   0000027e  00000000  00000000  000002bf  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000178  00000000  00000000  00000579  2**0
+  5 .debug_abbrev 0000016b  00000000  00000000  0000053d  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000046b  00000000  00000000  000006f1  2**0
+  6 .debug_line   00000460  00000000  00000000  000006a8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000b5c  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000b08  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000143  00000000  00000000  00000bdc  2**0
+  8 .debug_str    00000128  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d8  00000000  00000000  00000d1f  2**0
+  9 .debug_loc    00000253  00000000  00000000  00000cb0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000078  00000000  00000000  00000ff7  2**0
+ 10 .debug_ranges 00000078  00000000  00000000  00000f03  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00003e00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,7 +47,7 @@ int main(void) {
     3e04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e06:	81 ff       	sbrs	r24, 1
-    3e08:	f0 d0       	rcall	.+480    	; 0x3fea <appStart>
+    3e08:	e7 d0       	rcall	.+462    	; 0x3fd8 <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -59,16 +59,16 @@ int main(void) {
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
-  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UART_SRA = _BV(U2X0); //Double speed mode USART0
     3e10:	82 e0       	ldi	r24, 0x02	; 2
     3e12:	80 93 c0 00 	sts	0x00C0, r24
-  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
     3e16:	88 e1       	ldi	r24, 0x18	; 24
     3e18:	80 93 c1 00 	sts	0x00C1, r24
-  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
     3e1c:	86 e0       	ldi	r24, 0x06	; 6
     3e1e:	80 93 c2 00 	sts	0x00C2, r24
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
     3e22:	88 e0       	ldi	r24, 0x08	; 8
     3e24:	80 93 c4 00 	sts	0x00C4, r24
 #endif
@@ -77,7 +77,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e28:	8e e0       	ldi	r24, 0x0E	; 14
-    3e2a:	c9 d0       	rcall	.+402    	; 0x3fbe <watchdogConfig>
+    3e2a:	c0 d0       	rcall	.+384    	; 0x3fac <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -126,30 +126,30 @@ void watchdogReset() {
   } while (--count);
     3e48:	81 50       	subi	r24, 0x01	; 1
     3e4a:	a9 f7       	brne	.-22     	; 0x3e36 <main+0x36>
-    3e4c:	cc 24       	eor	r12, r12
-    3e4e:	dd 24       	eor	r13, r13
+    3e4c:	ee 24       	eor	r14, r14
+    3e4e:	ff 24       	eor	r15, r15
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e50:	88 24       	eor	r8, r8
-    3e52:	83 94       	inc	r8
+    3e50:	aa 24       	eor	r10, r10
+    3e52:	a3 94       	inc	r10
         addrPtr += 2;
       } while (--ch);
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e54:	b5 e0       	ldi	r27, 0x05	; 5
-    3e56:	ab 2e       	mov	r10, r27
+    3e56:	cb 2e       	mov	r12, r27
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e58:	a1 e1       	ldi	r26, 0x11	; 17
-    3e5a:	9a 2e       	mov	r9, r26
+    3e5a:	ba 2e       	mov	r11, r26
       do *bufPtr++ = getch();
       while (--length);
 
@@ -157,442 +157,425 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3e5c:	f3 e0       	ldi	r31, 0x03	; 3
-    3e5e:	bf 2e       	mov	r11, r31
+    3e5e:	df 2e       	mov	r13, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e60:	a2 d0       	rcall	.+324    	; 0x3fa6 <getch>
+    3e60:	99 d0       	rcall	.+306    	; 0x3f94 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e62:	81 34       	cpi	r24, 0x41	; 65
-    3e64:	61 f4       	brne	.+24     	; 0x3e7e <main+0x7e>
+    3e64:	69 f4       	brne	.+26     	; 0x3e80 <main+0x80>
       unsigned char which = getch();
-    3e66:	9f d0       	rcall	.+318    	; 0x3fa6 <getch>
+    3e66:	96 d0       	rcall	.+300    	; 0x3f94 <getch>
     3e68:	08 2f       	mov	r16, r24
       verifySpace();
-    3e6a:	af d0       	rcall	.+350    	; 0x3fca <verifySpace>
+    3e6a:	a6 d0       	rcall	.+332    	; 0x3fb8 <verifySpace>
       if (which == 0x82) {
     3e6c:	02 38       	cpi	r16, 0x82	; 130
-    3e6e:	11 f0       	breq	.+4      	; 0x3e74 <main+0x74>
+    3e6e:	09 f4       	brne	.+2      	; 0x3e72 <main+0x72>
+    3e70:	7f c0       	rjmp	.+254    	; 0x3f70 <main+0x170>
 	/*
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
       } else if (which == 0x81) {
-    3e70:	01 38       	cpi	r16, 0x81	; 129
-    3e72:	11 f4       	brne	.+4      	; 0x3e78 <main+0x78>
+    3e72:	01 38       	cpi	r16, 0x81	; 129
+    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(OPTIBOOT_MAJVER);
-    3e74:	84 e0       	ldi	r24, 0x04	; 4
-    3e76:	01 c0       	rjmp	.+2      	; 0x3e7a <main+0x7a>
+    3e76:	84 e0       	ldi	r24, 0x04	; 4
+    3e78:	01 c0       	rjmp	.+2      	; 0x3e7c <main+0x7c>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    3e78:	83 e0       	ldi	r24, 0x03	; 3
-    3e7a:	8d d0       	rcall	.+282    	; 0x3f96 <putch>
-    3e7c:	89 c0       	rjmp	.+274    	; 0x3f90 <main+0x190>
+    3e7a:	83 e0       	ldi	r24, 0x03	; 3
+    3e7c:	83 d0       	rcall	.+262    	; 0x3f84 <putch>
+    3e7e:	7f c0       	rjmp	.+254    	; 0x3f7e <main+0x17e>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    3e7e:	82 34       	cpi	r24, 0x42	; 66
-    3e80:	11 f4       	brne	.+4      	; 0x3e86 <main+0x86>
+    3e80:	82 34       	cpi	r24, 0x42	; 66
+    3e82:	11 f4       	brne	.+4      	; 0x3e88 <main+0x88>
       // SET DEVICE is ignored
       getNch(20);
-    3e82:	84 e1       	ldi	r24, 0x14	; 20
-    3e84:	03 c0       	rjmp	.+6      	; 0x3e8c <main+0x8c>
+    3e84:	84 e1       	ldi	r24, 0x14	; 20
+    3e86:	03 c0       	rjmp	.+6      	; 0x3e8e <main+0x8e>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e86:	85 34       	cpi	r24, 0x45	; 69
-    3e88:	19 f4       	brne	.+6      	; 0x3e90 <main+0x90>
+    3e88:	85 34       	cpi	r24, 0x45	; 69
+    3e8a:	19 f4       	brne	.+6      	; 0x3e92 <main+0x92>
       // SET DEVICE EXT is ignored
       getNch(5);
-    3e8a:	85 e0       	ldi	r24, 0x05	; 5
-    3e8c:	a6 d0       	rcall	.+332    	; 0x3fda <getNch>
-    3e8e:	80 c0       	rjmp	.+256    	; 0x3f90 <main+0x190>
+    3e8c:	85 e0       	ldi	r24, 0x05	; 5
+    3e8e:	9c d0       	rcall	.+312    	; 0x3fc8 <getNch>
+    3e90:	76 c0       	rjmp	.+236    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    3e90:	85 35       	cpi	r24, 0x55	; 85
-    3e92:	79 f4       	brne	.+30     	; 0x3eb2 <main+0xb2>
+    3e92:	85 35       	cpi	r24, 0x55	; 85
+    3e94:	79 f4       	brne	.+30     	; 0x3eb4 <main+0xb4>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e94:	88 d0       	rcall	.+272    	; 0x3fa6 <getch>
+    3e96:	7e d0       	rcall	.+252    	; 0x3f94 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e96:	e8 2e       	mov	r14, r24
-    3e98:	ff 24       	eor	r15, r15
-    3e9a:	85 d0       	rcall	.+266    	; 0x3fa6 <getch>
-    3e9c:	08 2f       	mov	r16, r24
-    3e9e:	10 e0       	ldi	r17, 0x00	; 0
-    3ea0:	10 2f       	mov	r17, r16
-    3ea2:	00 27       	eor	r16, r16
-    3ea4:	0e 29       	or	r16, r14
-    3ea6:	1f 29       	or	r17, r15
+    3e98:	e8 2e       	mov	r14, r24
+    3e9a:	ff 24       	eor	r15, r15
+    3e9c:	7b d0       	rcall	.+246    	; 0x3f94 <getch>
+    3e9e:	08 2f       	mov	r16, r24
+    3ea0:	10 e0       	ldi	r17, 0x00	; 0
+    3ea2:	10 2f       	mov	r17, r16
+    3ea4:	00 27       	eor	r16, r16
+    3ea6:	0e 29       	or	r16, r14
+    3ea8:	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
-    3ea8:	00 0f       	add	r16, r16
-    3eaa:	11 1f       	adc	r17, r17
+    3eaa:	00 0f       	add	r16, r16
+    3eac:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eac:	8e d0       	rcall	.+284    	; 0x3fca <verifySpace>
-    3eae:	68 01       	movw	r12, r16
-    3eb0:	6f c0       	rjmp	.+222    	; 0x3f90 <main+0x190>
+    3eae:	84 d0       	rcall	.+264    	; 0x3fb8 <verifySpace>
+    3eb0:	78 01       	movw	r14, r16
+    3eb2:	65 c0       	rjmp	.+202    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_UNIVERSAL) {
-    3eb2:	86 35       	cpi	r24, 0x56	; 86
-    3eb4:	21 f4       	brne	.+8      	; 0x3ebe <main+0xbe>
+    3eb4:	86 35       	cpi	r24, 0x56	; 86
+    3eb6:	21 f4       	brne	.+8      	; 0x3ec0 <main+0xc0>
       // UNIVERSAL command is ignored
       getNch(4);
-    3eb6:	84 e0       	ldi	r24, 0x04	; 4
-    3eb8:	90 d0       	rcall	.+288    	; 0x3fda <getNch>
+    3eb8:	84 e0       	ldi	r24, 0x04	; 4
+    3eba:	86 d0       	rcall	.+268    	; 0x3fc8 <getNch>
       putch(0x00);
-    3eba:	80 e0       	ldi	r24, 0x00	; 0
-    3ebc:	de cf       	rjmp	.-68     	; 0x3e7a <main+0x7a>
+    3ebc:	80 e0       	ldi	r24, 0x00	; 0
+    3ebe:	de cf       	rjmp	.-68     	; 0x3e7c <main+0x7c>
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    3ebe:	84 36       	cpi	r24, 0x64	; 100
-    3ec0:	09 f0       	breq	.+2      	; 0x3ec4 <main+0xc4>
-    3ec2:	40 c0       	rjmp	.+128    	; 0x3f44 <main+0x144>
+    3ec0:	84 36       	cpi	r24, 0x64	; 100
+    3ec2:	09 f0       	breq	.+2      	; 0x3ec6 <main+0xc6>
+    3ec4:	40 c0       	rjmp	.+128    	; 0x3f46 <main+0x146>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    3ec4:	70 d0       	rcall	.+224    	; 0x3fa6 <getch>
+    3ec6:	66 d0       	rcall	.+204    	; 0x3f94 <getch>
       length = getch();
-    3ec6:	6f d0       	rcall	.+222    	; 0x3fa6 <getch>
-    3ec8:	08 2f       	mov	r16, r24
+    3ec8:	65 d0       	rcall	.+202    	; 0x3f94 <getch>
+    3eca:	08 2f       	mov	r16, r24
       getch();
-    3eca:	6d d0       	rcall	.+218    	; 0x3fa6 <getch>
+    3ecc:	63 d0       	rcall	.+198    	; 0x3f94 <getch>
 
       // If we are in RWW section, immediately start page erase
       if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ecc:	80 e0       	ldi	r24, 0x00	; 0
-    3ece:	c8 16       	cp	r12, r24
-    3ed0:	88 e3       	ldi	r24, 0x38	; 56
-    3ed2:	d8 06       	cpc	r13, r24
-    3ed4:	18 f4       	brcc	.+6      	; 0x3edc <main+0xdc>
-    3ed6:	f6 01       	movw	r30, r12
-    3ed8:	b7 be       	out	0x37, r11	; 55
-    3eda:	e8 95       	spm
-    3edc:	c0 e0       	ldi	r28, 0x00	; 0
-    3ede:	d1 e0       	ldi	r29, 0x01	; 1
+    3ece:	80 e0       	ldi	r24, 0x00	; 0
+    3ed0:	e8 16       	cp	r14, r24
+    3ed2:	88 e3       	ldi	r24, 0x38	; 56
+    3ed4:	f8 06       	cpc	r15, r24
+    3ed6:	18 f4       	brcc	.+6      	; 0x3ede <main+0xde>
+    3ed8:	f7 01       	movw	r30, r14
+    3eda:	d7 be       	out	0x37, r13	; 55
+    3edc:	e8 95       	spm
+    3ede:	c0 e0       	ldi	r28, 0x00	; 0
+    3ee0:	d1 e0       	ldi	r29, 0x01	; 1
 
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee0:	62 d0       	rcall	.+196    	; 0x3fa6 <getch>
-    3ee2:	89 93       	st	Y+, r24
+    3ee2:	58 d0       	rcall	.+176    	; 0x3f94 <getch>
+    3ee4:	89 93       	st	Y+, r24
       while (--length);
-    3ee4:	0c 17       	cp	r16, r28
-    3ee6:	e1 f7       	brne	.-8      	; 0x3ee0 <main+0xe0>
+    3ee6:	0c 17       	cp	r16, r28
+    3ee8:	e1 f7       	brne	.-8      	; 0x3ee2 <main+0xe2>
 
       // If we are in NRWW section, page erase has to be delayed until now.
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ee8:	f0 e0       	ldi	r31, 0x00	; 0
-    3eea:	cf 16       	cp	r12, r31
-    3eec:	f8 e3       	ldi	r31, 0x38	; 56
-    3eee:	df 06       	cpc	r13, r31
-    3ef0:	18 f0       	brcs	.+6      	; 0x3ef8 <main+0xf8>
-    3ef2:	f6 01       	movw	r30, r12
-    3ef4:	b7 be       	out	0x37, r11	; 55
-    3ef6:	e8 95       	spm
+    3eea:	f0 e0       	ldi	r31, 0x00	; 0
+    3eec:	ef 16       	cp	r14, r31
+    3eee:	f8 e3       	ldi	r31, 0x38	; 56
+    3ef0:	ff 06       	cpc	r15, r31
+    3ef2:	18 f0       	brcs	.+6      	; 0x3efa <main+0xfa>
+    3ef4:	f7 01       	movw	r30, r14
+    3ef6:	d7 be       	out	0x37, r13	; 55
+    3ef8:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ef8:	68 d0       	rcall	.+208    	; 0x3fca <verifySpace>
+    3efa:	5e d0       	rcall	.+188    	; 0x3fb8 <verifySpace>
 
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3efa:	07 b6       	in	r0, 0x37	; 55
-    3efc:	00 fc       	sbrc	r0, 0
-    3efe:	fd cf       	rjmp	.-6      	; 0x3efa <main+0xfa>
-    3f00:	a6 01       	movw	r20, r12
-    3f02:	a0 e0       	ldi	r26, 0x00	; 0
-    3f04:	b1 e0       	ldi	r27, 0x01	; 1
+    3efc:	07 b6       	in	r0, 0x37	; 55
+    3efe:	00 fc       	sbrc	r0, 0
+    3f00:	fd cf       	rjmp	.-6      	; 0x3efc <main+0xfc>
+    3f02:	a7 01       	movw	r20, r14
+    3f04:	a0 e0       	ldi	r26, 0x00	; 0
+    3f06:	b1 e0       	ldi	r27, 0x01	; 1
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3f06:	2c 91       	ld	r18, X
-    3f08:	30 e0       	ldi	r19, 0x00	; 0
+    3f08:	2c 91       	ld	r18, X
+    3f0a:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3f0a:	11 96       	adiw	r26, 0x01	; 1
-    3f0c:	8c 91       	ld	r24, X
-    3f0e:	11 97       	sbiw	r26, 0x01	; 1
-    3f10:	90 e0       	ldi	r25, 0x00	; 0
-    3f12:	98 2f       	mov	r25, r24
-    3f14:	88 27       	eor	r24, r24
-    3f16:	82 2b       	or	r24, r18
-    3f18:	93 2b       	or	r25, r19
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    3f0c:	11 96       	adiw	r26, 0x01	; 1
+    3f0e:	8c 91       	ld	r24, X
+    3f10:	11 97       	sbiw	r26, 0x01	; 1
+    3f12:	90 e0       	ldi	r25, 0x00	; 0
+    3f14:	98 2f       	mov	r25, r24
+    3f16:	88 27       	eor	r24, r24
+    3f18:	82 2b       	or	r24, r18
+    3f1a:	93 2b       	or	r25, r19
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
 int main(void) {
-    3f1a:	12 96       	adiw	r26, 0x02	; 2
+    3f1c:	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);
-    3f1c:	fa 01       	movw	r30, r20
-    3f1e:	0c 01       	movw	r0, r24
-    3f20:	87 be       	out	0x37, r8	; 55
-    3f22:	e8 95       	spm
-    3f24:	11 24       	eor	r1, r1
+    3f1e:	fa 01       	movw	r30, r20
+    3f20:	0c 01       	movw	r0, r24
+    3f22:	a7 be       	out	0x37, r10	; 55
+    3f24:	e8 95       	spm
+    3f26:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f26:	4e 5f       	subi	r20, 0xFE	; 254
-    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f28:	4e 5f       	subi	r20, 0xFE	; 254
+    3f2a:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f2a:	f1 e0       	ldi	r31, 0x01	; 1
-    3f2c:	a0 38       	cpi	r26, 0x80	; 128
-    3f2e:	bf 07       	cpc	r27, r31
-    3f30:	51 f7       	brne	.-44     	; 0x3f06 <main+0x106>
+    3f2c:	f1 e0       	ldi	r31, 0x01	; 1
+    3f2e:	a0 38       	cpi	r26, 0x80	; 128
+    3f30:	bf 07       	cpc	r27, r31
+    3f32:	51 f7       	brne	.-44     	; 0x3f08 <main+0x108>
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f32:	f6 01       	movw	r30, r12
-    3f34:	a7 be       	out	0x37, r10	; 55
-    3f36:	e8 95       	spm
+    3f34:	f7 01       	movw	r30, r14
+    3f36:	c7 be       	out	0x37, r12	; 55
+    3f38:	e8 95       	spm
       boot_spm_busy_wait();
-    3f38:	07 b6       	in	r0, 0x37	; 55
-    3f3a:	00 fc       	sbrc	r0, 0
-    3f3c:	fd cf       	rjmp	.-6      	; 0x3f38 <main+0x138>
+    3f3a:	07 b6       	in	r0, 0x37	; 55
+    3f3c:	00 fc       	sbrc	r0, 0
+    3f3e:	fd cf       	rjmp	.-6      	; 0x3f3a <main+0x13a>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
-    3f42:	26 c0       	rjmp	.+76     	; 0x3f90 <main+0x190>
+    3f40:	b7 be       	out	0x37, r11	; 55
+    3f42:	e8 95       	spm
+    3f44:	1c c0       	rjmp	.+56     	; 0x3f7e <main+0x17e>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f44:	84 37       	cpi	r24, 0x74	; 116
-    3f46:	b1 f4       	brne	.+44     	; 0x3f74 <main+0x174>
+    3f46:	84 37       	cpi	r24, 0x74	; 116
+    3f48:	61 f4       	brne	.+24     	; 0x3f62 <main+0x162>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    3f48:	2e d0       	rcall	.+92     	; 0x3fa6 <getch>
+    3f4a:	24 d0       	rcall	.+72     	; 0x3f94 <getch>
       length = getch();
-    3f4a:	2d d0       	rcall	.+90     	; 0x3fa6 <getch>
-    3f4c:	f8 2e       	mov	r15, r24
+    3f4c:	23 d0       	rcall	.+70     	; 0x3f94 <getch>
+    3f4e:	08 2f       	mov	r16, r24
       getch();
-    3f4e:	2b d0       	rcall	.+86     	; 0x3fa6 <getch>
+    3f50:	21 d0       	rcall	.+66     	; 0x3f94 <getch>
 
       verifySpace();
-    3f50:	3c d0       	rcall	.+120    	; 0x3fca <verifySpace>
-    3f52:	f6 01       	movw	r30, r12
-    3f54:	ef 2c       	mov	r14, r15
-        putch(result);
-        address++;
-      }
-      while (--length);
+    3f52:	32 d0       	rcall	.+100    	; 0x3fb8 <verifySpace>
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-    3f56:	8f 01       	movw	r16, r30
-    3f58:	0f 5f       	subi	r16, 0xFF	; 255
-    3f5a:	1f 4f       	sbci	r17, 0xFF	; 255
-    3f5c:	84 91       	lpm	r24, Z+
-    3f5e:	1b d0       	rcall	.+54     	; 0x3f96 <putch>
-      while (--length);
-    3f60:	ea 94       	dec	r14
-    3f62:	f8 01       	movw	r30, r16
-    3f64:	c1 f7       	brne	.-16     	; 0x3f56 <main+0x156>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-/* main program starts here */
-int main(void) {
-    3f66:	08 94       	sec
-    3f68:	c1 1c       	adc	r12, r1
-    3f6a:	d1 1c       	adc	r13, r1
-    3f6c:	fa 94       	dec	r15
-    3f6e:	cf 0c       	add	r12, r15
-    3f70:	d1 1c       	adc	r13, r1
-    3f72:	0e c0       	rjmp	.+28     	; 0x3f90 <main+0x190>
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+    3f54:	f7 01       	movw	r30, r14
+    3f56:	85 91       	lpm	r24, Z+
+    3f58:	7f 01       	movw	r14, r30
+    3f5a:	14 d0       	rcall	.+40     	; 0x3f84 <putch>
+      } while (--length);
+    3f5c:	01 50       	subi	r16, 0x01	; 1
+    3f5e:	d1 f7       	brne	.-12     	; 0x3f54 <main+0x154>
+    3f60:	0e c0       	rjmp	.+28     	; 0x3f7e <main+0x17e>
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f74:	85 37       	cpi	r24, 0x75	; 117
-    3f76:	39 f4       	brne	.+14     	; 0x3f86 <main+0x186>
+    3f62:	85 37       	cpi	r24, 0x75	; 117
+    3f64:	39 f4       	brne	.+14     	; 0x3f74 <main+0x174>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f78:	28 d0       	rcall	.+80     	; 0x3fca <verifySpace>
+    3f66:	28 d0       	rcall	.+80     	; 0x3fb8 <verifySpace>
       putch(SIGNATURE_0);
-    3f7a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7c:	0c d0       	rcall	.+24     	; 0x3f96 <putch>
+    3f68:	8e e1       	ldi	r24, 0x1E	; 30
+    3f6a:	0c d0       	rcall	.+24     	; 0x3f84 <putch>
       putch(SIGNATURE_1);
-    3f7e:	84 e9       	ldi	r24, 0x94	; 148
-    3f80:	0a d0       	rcall	.+20     	; 0x3f96 <putch>
+    3f6c:	84 e9       	ldi	r24, 0x94	; 148
+    3f6e:	0a d0       	rcall	.+20     	; 0x3f84 <putch>
       putch(SIGNATURE_2);
-    3f82:	86 e0       	ldi	r24, 0x06	; 6
-    3f84:	7a cf       	rjmp	.-268    	; 0x3e7a <main+0x7a>
+    3f70:	86 e0       	ldi	r24, 0x06	; 6
+    3f72:	84 cf       	rjmp	.-248    	; 0x3e7c <main+0x7c>
     }
-    else if (ch == 'Q') {
-    3f86:	81 35       	cpi	r24, 0x51	; 81
-    3f88:	11 f4       	brne	.+4      	; 0x3f8e <main+0x18e>
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+    3f74:	81 35       	cpi	r24, 0x51	; 81
+    3f76:	11 f4       	brne	.+4      	; 0x3f7c <main+0x17c>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8a:	88 e0       	ldi	r24, 0x08	; 8
-    3f8c:	18 d0       	rcall	.+48     	; 0x3fbe <watchdogConfig>
+    3f78:	88 e0       	ldi	r24, 0x08	; 8
+    3f7a:	18 d0       	rcall	.+48     	; 0x3fac <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f8e:	1d d0       	rcall	.+58     	; 0x3fca <verifySpace>
+    3f7c:	1d d0       	rcall	.+58     	; 0x3fb8 <verifySpace>
     }
     putch(STK_OK);
-    3f90:	80 e1       	ldi	r24, 0x10	; 16
-    3f92:	01 d0       	rcall	.+2      	; 0x3f96 <putch>
-    3f94:	65 cf       	rjmp	.-310    	; 0x3e60 <main+0x60>
+    3f7e:	80 e1       	ldi	r24, 0x10	; 16
+    3f80:	01 d0       	rcall	.+2      	; 0x3f84 <putch>
+    3f82:	6e cf       	rjmp	.-292    	; 0x3e60 <main+0x60>
 
-00003f96 <putch>:
+00003f84 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f96:	98 2f       	mov	r25, r24
+    3f84:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-    3f98:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9c:	85 ff       	sbrs	r24, 5
-    3f9e:	fc cf       	rjmp	.-8      	; 0x3f98 <putch+0x2>
-  UDR0 = ch;
-    3fa0:	90 93 c6 00 	sts	0x00C6, r25
+  while (!(UART_SRA & _BV(UDRE0)));
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	85 ff       	sbrs	r24, 5
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <putch+0x2>
+  UART_UDR = ch;
+    3f8e:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa4:	08 95       	ret
+    3f92:	08 95       	ret
 
-00003fa6 <getch>:
+00003f94 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
-  while(!(UCSR0A & _BV(RXC0)))
-    3fa6:	80 91 c0 00 	lds	r24, 0x00C0
-    3faa:	87 ff       	sbrs	r24, 7
-    3fac:	fc cf       	rjmp	.-8      	; 0x3fa6 <getch>
+  while(!(UART_SRA & _BV(RXC0)))
+    3f94:	80 91 c0 00 	lds	r24, 0x00C0
+    3f98:	87 ff       	sbrs	r24, 7
+    3f9a:	fc cf       	rjmp	.-8      	; 0x3f94 <getch>
     ;
-  if (!(UCSR0A & _BV(FE0))) {
-    3fae:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb2:	84 fd       	sbrc	r24, 4
-    3fb4:	01 c0       	rjmp	.+2      	; 0x3fb8 <getch+0x12>
+  if (!(UART_SRA & _BV(FE0))) {
+    3f9c:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa0:	84 fd       	sbrc	r24, 4
+    3fa2:	01 c0       	rjmp	.+2      	; 0x3fa6 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb6:	a8 95       	wdr
+    3fa4:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
-  ch = UDR0;
-    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
+  ch = UART_UDR;
+    3fa6:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbc:	08 95       	ret
+    3faa:	08 95       	ret
 
-00003fbe <watchdogConfig>:
+00003fac <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fbe:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc2:	98 e1       	ldi	r25, 0x18	; 24
-    3fc4:	90 83       	st	Z, r25
+    3fac:	e0 e6       	ldi	r30, 0x60	; 96
+    3fae:	f0 e0       	ldi	r31, 0x00	; 0
+    3fb0:	98 e1       	ldi	r25, 0x18	; 24
+    3fb2:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc6:	80 83       	st	Z, r24
+    3fb4:	80 83       	st	Z, r24
 }
-    3fc8:	08 95       	ret
+    3fb6:	08 95       	ret
 
-00003fca <verifySpace>:
+00003fb8 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fca:	ed df       	rcall	.-38     	; 0x3fa6 <getch>
-    3fcc:	80 32       	cpi	r24, 0x20	; 32
-    3fce:	19 f0       	breq	.+6      	; 0x3fd6 <verifySpace+0xc>
+    3fb8:	ed df       	rcall	.-38     	; 0x3f94 <getch>
+    3fba:	80 32       	cpi	r24, 0x20	; 32
+    3fbc:	19 f0       	breq	.+6      	; 0x3fc4 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd0:	88 e0       	ldi	r24, 0x08	; 8
-    3fd2:	f5 df       	rcall	.-22     	; 0x3fbe <watchdogConfig>
-    3fd4:	ff cf       	rjmp	.-2      	; 0x3fd4 <verifySpace+0xa>
+    3fbe:	88 e0       	ldi	r24, 0x08	; 8
+    3fc0:	f5 df       	rcall	.-22     	; 0x3fac <watchdogConfig>
+    3fc2:	ff cf       	rjmp	.-2      	; 0x3fc2 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd6:	84 e1       	ldi	r24, 0x14	; 20
+    3fc4:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fd8:	de cf       	rjmp	.-68     	; 0x3f96 <putch>
+    3fc6:	de cf       	rjmp	.-68     	; 0x3f84 <putch>
 
-00003fda <getNch>:
+00003fc8 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fda:	1f 93       	push	r17
-    3fdc:	18 2f       	mov	r17, r24
+    3fc8:	1f 93       	push	r17
+    3fca:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fde:	e3 df       	rcall	.-58     	; 0x3fa6 <getch>
-    3fe0:	11 50       	subi	r17, 0x01	; 1
-    3fe2:	e9 f7       	brne	.-6      	; 0x3fde <getNch+0x4>
+    3fcc:	e3 df       	rcall	.-58     	; 0x3f94 <getch>
+    3fce:	11 50       	subi	r17, 0x01	; 1
+    3fd0:	e9 f7       	brne	.-6      	; 0x3fcc <getNch+0x4>
   verifySpace();
-    3fe4:	f2 df       	rcall	.-28     	; 0x3fca <verifySpace>
+    3fd2:	f2 df       	rcall	.-28     	; 0x3fb8 <verifySpace>
 }
-    3fe6:	1f 91       	pop	r17
-    3fe8:	08 95       	ret
+    3fd4:	1f 91       	pop	r17
+    3fd6:	08 95       	ret
 
-00003fea <appStart>:
+00003fd8 <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fea:	80 e0       	ldi	r24, 0x00	; 0
-    3fec:	e8 df       	rcall	.-48     	; 0x3fbe <watchdogConfig>
+    3fd8:	80 e0       	ldi	r24, 0x00	; 0
+    3fda:	e8 df       	rcall	.-48     	; 0x3fac <watchdogConfig>
   __asm__ __volatile__ (
-    3fee:	ee 27       	eor	r30, r30
-    3ff0:	ff 27       	eor	r31, r31
-    3ff2:	09 94       	ijmp
+    3fdc:	ee 27       	eor	r30, r30
+    3fde:	ff 27       	eor	r31, r31
+    3fe0:	09 94       	ijmp

+ 30 - 31
optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.hex

@@ -1,35 +1,34 @@
-:103E0000112484B714BE81FFF0D085E08093810037
+:103E0000112484B714BE81FFE7D085E08093810040
 :103E100082E08093C00088E18093C10086E08093B7
-:103E2000C20088E08093C4008EE0C9D0259A86E065
+:103E2000C20088E08093C4008EE0C0D0259A86E06E
 :103E300028E13EEF91E0309385002093840096BB0B
-:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
-:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
-:103E6000A2D0813461F49FD0082FAFD0023811F076
-:103E7000013811F484E001C083E08DD089C0823420
-:103E800011F484E103C0853419F485E0A6D080C024
-:103E9000853579F488D0E82EFF2485D0082F10E0EE
-:103EA000102F00270E291F29000F111F8ED0680127
-:103EB0006FC0863521F484E090D080E0DECF843678
-:103EC00009F040C070D06FD0082F6DD080E0C816C8
-:103ED00088E3D80618F4F601B7BEE895C0E0D1E053
-:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
-:103EF00018F0F601B7BEE89568D007B600FCFDCF14
-:103F0000A601A0E0B1E02C9130E011968C911197C0
-:103F100090E0982F8827822B932B1296FA010C01A0
-:103F200087BEE89511244E5F5F4FF1E0A038BF07D0
-:103F300051F7F601A7BEE89507B600FCFDCF97BE86
-:103F4000E89526C08437B1F42ED02DD0F82E2BD092
-:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
-:103F6000EA94F801C1F70894C11CD11CFA94CF0C53
-:103F7000D11C0EC0853739F428D08EE10CD084E9ED
-:103F80000AD086E07ACF813511F488E018D01DD0B0
-:103F900080E101D065CF982F8091C00085FFFCCFD4
-:103FA0009093C60008958091C00087FFFCCF809158
-:103FB000C00084FD01C0A8958091C6000895E0E688
-:103FC000F0E098E1908380830895EDDF803219F06E
-:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
-:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
-:043FF000FF2709940A
-:023FFE000404B9
+:103E4000B09BFECF1D9AA8958150A9F7EE24FF24C0
+:103E5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2E85
+:103E600099D0813469F496D0082FA6D0023809F48D
+:103E70007FC0013811F484E001C083E083D07FC0AB
+:103E8000823411F484E103C0853419F485E09CD0B8
+:103E900076C0853579F47ED0E82EFF247BD0082FBC
+:103EA00010E0102F00270E291F29000F111F84D0AA
+:103EB000780165C0863521F484E086D080E0DECFCD
+:103EC000843609F040C066D065D0082F63D080E00A
+:103ED000E81688E3F80618F4F701D7BEE895C0E0C5
+:103EE000D1E058D089930C17E1F7F0E0EF16F8E332
+:103EF000FF0618F0F701D7BEE8955ED007B600FCC4
+:103F0000FDCFA701A0E0B1E02C9130E011968C919B
+:103F1000119790E0982F8827822B932B1296FA0105
+:103F20000C01A7BEE89511244E5F5F4FF1E0A03869
+:103F3000BF0751F7F701C7BEE89507B600FCFDCFF4
+:103F4000B7BEE8951CC0843761F424D023D0082F75
+:103F500021D032D0F70185917F0114D00150D1F7E3
+:103F60000EC0853739F428D08EE10CD084E90AD010
+:103F700086E084CF813511F488E018D01DD080E12F
+:103F800001D06ECF982F8091C00085FFFCCF909319
+:103F9000C60008958091C00087FFFCCF8091C000CB
+:103FA00084FD01C0A8958091C6000895E0E6F0E088
+:103FB00098E1908380830895EDDF803219F088E0E6
+:103FC000F5DFFFCF84E1DECF1F93182FE3DF115021
+:103FD000E9F7F2DF1F91089580E0E8DFEE27FF2781
+:023FE000099442
+:023FFE000604B7
 :0400000300003E00BB
 :00000001FF

+ 230 - 247
optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.lst

@@ -3,34 +3,34 @@ optiboot_lilypad_resonator.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f4  00003e00  00003e00  00000054  2**1
+  0 .text         000001e2  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  00000248  2**0
+  1 .version      00000002  00003ffe  00003ffe  00000236  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  0000024a  2**0
+  2 .debug_aranges 00000028  00000000  00000000  00000238  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000005f  00000000  00000000  00000272  2**0
+  3 .debug_pubnames 0000005f  00000000  00000000  00000260  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002a8  00000000  00000000  000002d1  2**0
+  4 .debug_info   0000027e  00000000  00000000  000002bf  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000178  00000000  00000000  00000579  2**0
+  5 .debug_abbrev 0000016b  00000000  00000000  0000053d  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000046b  00000000  00000000  000006f1  2**0
+  6 .debug_line   00000460  00000000  00000000  000006a8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000b5c  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000b08  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000143  00000000  00000000  00000bdc  2**0
+  8 .debug_str    00000128  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d8  00000000  00000000  00000d1f  2**0
+  9 .debug_loc    00000253  00000000  00000000  00000cb0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000078  00000000  00000000  00000ff7  2**0
+ 10 .debug_ranges 00000078  00000000  00000000  00000f03  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00003e00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,7 +47,7 @@ int main(void) {
     3e04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e06:	81 ff       	sbrs	r24, 1
-    3e08:	f0 d0       	rcall	.+480    	; 0x3fea <appStart>
+    3e08:	e7 d0       	rcall	.+462    	; 0x3fd8 <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -59,16 +59,16 @@ int main(void) {
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
-  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UART_SRA = _BV(U2X0); //Double speed mode USART0
     3e10:	82 e0       	ldi	r24, 0x02	; 2
     3e12:	80 93 c0 00 	sts	0x00C0, r24
-  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
     3e16:	88 e1       	ldi	r24, 0x18	; 24
     3e18:	80 93 c1 00 	sts	0x00C1, r24
-  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
     3e1c:	86 e0       	ldi	r24, 0x06	; 6
     3e1e:	80 93 c2 00 	sts	0x00C2, r24
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
     3e22:	88 e0       	ldi	r24, 0x08	; 8
     3e24:	80 93 c4 00 	sts	0x00C4, r24
 #endif
@@ -77,7 +77,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e28:	8e e0       	ldi	r24, 0x0E	; 14
-    3e2a:	c9 d0       	rcall	.+402    	; 0x3fbe <watchdogConfig>
+    3e2a:	c0 d0       	rcall	.+384    	; 0x3fac <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -126,30 +126,30 @@ void watchdogReset() {
   } while (--count);
     3e48:	81 50       	subi	r24, 0x01	; 1
     3e4a:	a9 f7       	brne	.-22     	; 0x3e36 <main+0x36>
-    3e4c:	cc 24       	eor	r12, r12
-    3e4e:	dd 24       	eor	r13, r13
+    3e4c:	ee 24       	eor	r14, r14
+    3e4e:	ff 24       	eor	r15, r15
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e50:	88 24       	eor	r8, r8
-    3e52:	83 94       	inc	r8
+    3e50:	aa 24       	eor	r10, r10
+    3e52:	a3 94       	inc	r10
         addrPtr += 2;
       } while (--ch);
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e54:	b5 e0       	ldi	r27, 0x05	; 5
-    3e56:	ab 2e       	mov	r10, r27
+    3e56:	cb 2e       	mov	r12, r27
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e58:	a1 e1       	ldi	r26, 0x11	; 17
-    3e5a:	9a 2e       	mov	r9, r26
+    3e5a:	ba 2e       	mov	r11, r26
       do *bufPtr++ = getch();
       while (--length);
 
@@ -157,442 +157,425 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3e5c:	f3 e0       	ldi	r31, 0x03	; 3
-    3e5e:	bf 2e       	mov	r11, r31
+    3e5e:	df 2e       	mov	r13, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e60:	a2 d0       	rcall	.+324    	; 0x3fa6 <getch>
+    3e60:	99 d0       	rcall	.+306    	; 0x3f94 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e62:	81 34       	cpi	r24, 0x41	; 65
-    3e64:	61 f4       	brne	.+24     	; 0x3e7e <main+0x7e>
+    3e64:	69 f4       	brne	.+26     	; 0x3e80 <main+0x80>
       unsigned char which = getch();
-    3e66:	9f d0       	rcall	.+318    	; 0x3fa6 <getch>
+    3e66:	96 d0       	rcall	.+300    	; 0x3f94 <getch>
     3e68:	08 2f       	mov	r16, r24
       verifySpace();
-    3e6a:	af d0       	rcall	.+350    	; 0x3fca <verifySpace>
+    3e6a:	a6 d0       	rcall	.+332    	; 0x3fb8 <verifySpace>
       if (which == 0x82) {
     3e6c:	02 38       	cpi	r16, 0x82	; 130
-    3e6e:	11 f0       	breq	.+4      	; 0x3e74 <main+0x74>
+    3e6e:	09 f4       	brne	.+2      	; 0x3e72 <main+0x72>
+    3e70:	7f c0       	rjmp	.+254    	; 0x3f70 <main+0x170>
 	/*
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
       } else if (which == 0x81) {
-    3e70:	01 38       	cpi	r16, 0x81	; 129
-    3e72:	11 f4       	brne	.+4      	; 0x3e78 <main+0x78>
+    3e72:	01 38       	cpi	r16, 0x81	; 129
+    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(OPTIBOOT_MAJVER);
-    3e74:	84 e0       	ldi	r24, 0x04	; 4
-    3e76:	01 c0       	rjmp	.+2      	; 0x3e7a <main+0x7a>
+    3e76:	84 e0       	ldi	r24, 0x04	; 4
+    3e78:	01 c0       	rjmp	.+2      	; 0x3e7c <main+0x7c>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    3e78:	83 e0       	ldi	r24, 0x03	; 3
-    3e7a:	8d d0       	rcall	.+282    	; 0x3f96 <putch>
-    3e7c:	89 c0       	rjmp	.+274    	; 0x3f90 <main+0x190>
+    3e7a:	83 e0       	ldi	r24, 0x03	; 3
+    3e7c:	83 d0       	rcall	.+262    	; 0x3f84 <putch>
+    3e7e:	7f c0       	rjmp	.+254    	; 0x3f7e <main+0x17e>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    3e7e:	82 34       	cpi	r24, 0x42	; 66
-    3e80:	11 f4       	brne	.+4      	; 0x3e86 <main+0x86>
+    3e80:	82 34       	cpi	r24, 0x42	; 66
+    3e82:	11 f4       	brne	.+4      	; 0x3e88 <main+0x88>
       // SET DEVICE is ignored
       getNch(20);
-    3e82:	84 e1       	ldi	r24, 0x14	; 20
-    3e84:	03 c0       	rjmp	.+6      	; 0x3e8c <main+0x8c>
+    3e84:	84 e1       	ldi	r24, 0x14	; 20
+    3e86:	03 c0       	rjmp	.+6      	; 0x3e8e <main+0x8e>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e86:	85 34       	cpi	r24, 0x45	; 69
-    3e88:	19 f4       	brne	.+6      	; 0x3e90 <main+0x90>
+    3e88:	85 34       	cpi	r24, 0x45	; 69
+    3e8a:	19 f4       	brne	.+6      	; 0x3e92 <main+0x92>
       // SET DEVICE EXT is ignored
       getNch(5);
-    3e8a:	85 e0       	ldi	r24, 0x05	; 5
-    3e8c:	a6 d0       	rcall	.+332    	; 0x3fda <getNch>
-    3e8e:	80 c0       	rjmp	.+256    	; 0x3f90 <main+0x190>
+    3e8c:	85 e0       	ldi	r24, 0x05	; 5
+    3e8e:	9c d0       	rcall	.+312    	; 0x3fc8 <getNch>
+    3e90:	76 c0       	rjmp	.+236    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    3e90:	85 35       	cpi	r24, 0x55	; 85
-    3e92:	79 f4       	brne	.+30     	; 0x3eb2 <main+0xb2>
+    3e92:	85 35       	cpi	r24, 0x55	; 85
+    3e94:	79 f4       	brne	.+30     	; 0x3eb4 <main+0xb4>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e94:	88 d0       	rcall	.+272    	; 0x3fa6 <getch>
+    3e96:	7e d0       	rcall	.+252    	; 0x3f94 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e96:	e8 2e       	mov	r14, r24
-    3e98:	ff 24       	eor	r15, r15
-    3e9a:	85 d0       	rcall	.+266    	; 0x3fa6 <getch>
-    3e9c:	08 2f       	mov	r16, r24
-    3e9e:	10 e0       	ldi	r17, 0x00	; 0
-    3ea0:	10 2f       	mov	r17, r16
-    3ea2:	00 27       	eor	r16, r16
-    3ea4:	0e 29       	or	r16, r14
-    3ea6:	1f 29       	or	r17, r15
+    3e98:	e8 2e       	mov	r14, r24
+    3e9a:	ff 24       	eor	r15, r15
+    3e9c:	7b d0       	rcall	.+246    	; 0x3f94 <getch>
+    3e9e:	08 2f       	mov	r16, r24
+    3ea0:	10 e0       	ldi	r17, 0x00	; 0
+    3ea2:	10 2f       	mov	r17, r16
+    3ea4:	00 27       	eor	r16, r16
+    3ea6:	0e 29       	or	r16, r14
+    3ea8:	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
-    3ea8:	00 0f       	add	r16, r16
-    3eaa:	11 1f       	adc	r17, r17
+    3eaa:	00 0f       	add	r16, r16
+    3eac:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eac:	8e d0       	rcall	.+284    	; 0x3fca <verifySpace>
-    3eae:	68 01       	movw	r12, r16
-    3eb0:	6f c0       	rjmp	.+222    	; 0x3f90 <main+0x190>
+    3eae:	84 d0       	rcall	.+264    	; 0x3fb8 <verifySpace>
+    3eb0:	78 01       	movw	r14, r16
+    3eb2:	65 c0       	rjmp	.+202    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_UNIVERSAL) {
-    3eb2:	86 35       	cpi	r24, 0x56	; 86
-    3eb4:	21 f4       	brne	.+8      	; 0x3ebe <main+0xbe>
+    3eb4:	86 35       	cpi	r24, 0x56	; 86
+    3eb6:	21 f4       	brne	.+8      	; 0x3ec0 <main+0xc0>
       // UNIVERSAL command is ignored
       getNch(4);
-    3eb6:	84 e0       	ldi	r24, 0x04	; 4
-    3eb8:	90 d0       	rcall	.+288    	; 0x3fda <getNch>
+    3eb8:	84 e0       	ldi	r24, 0x04	; 4
+    3eba:	86 d0       	rcall	.+268    	; 0x3fc8 <getNch>
       putch(0x00);
-    3eba:	80 e0       	ldi	r24, 0x00	; 0
-    3ebc:	de cf       	rjmp	.-68     	; 0x3e7a <main+0x7a>
+    3ebc:	80 e0       	ldi	r24, 0x00	; 0
+    3ebe:	de cf       	rjmp	.-68     	; 0x3e7c <main+0x7c>
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    3ebe:	84 36       	cpi	r24, 0x64	; 100
-    3ec0:	09 f0       	breq	.+2      	; 0x3ec4 <main+0xc4>
-    3ec2:	40 c0       	rjmp	.+128    	; 0x3f44 <main+0x144>
+    3ec0:	84 36       	cpi	r24, 0x64	; 100
+    3ec2:	09 f0       	breq	.+2      	; 0x3ec6 <main+0xc6>
+    3ec4:	40 c0       	rjmp	.+128    	; 0x3f46 <main+0x146>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    3ec4:	70 d0       	rcall	.+224    	; 0x3fa6 <getch>
+    3ec6:	66 d0       	rcall	.+204    	; 0x3f94 <getch>
       length = getch();
-    3ec6:	6f d0       	rcall	.+222    	; 0x3fa6 <getch>
-    3ec8:	08 2f       	mov	r16, r24
+    3ec8:	65 d0       	rcall	.+202    	; 0x3f94 <getch>
+    3eca:	08 2f       	mov	r16, r24
       getch();
-    3eca:	6d d0       	rcall	.+218    	; 0x3fa6 <getch>
+    3ecc:	63 d0       	rcall	.+198    	; 0x3f94 <getch>
 
       // If we are in RWW section, immediately start page erase
       if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ecc:	80 e0       	ldi	r24, 0x00	; 0
-    3ece:	c8 16       	cp	r12, r24
-    3ed0:	88 e3       	ldi	r24, 0x38	; 56
-    3ed2:	d8 06       	cpc	r13, r24
-    3ed4:	18 f4       	brcc	.+6      	; 0x3edc <main+0xdc>
-    3ed6:	f6 01       	movw	r30, r12
-    3ed8:	b7 be       	out	0x37, r11	; 55
-    3eda:	e8 95       	spm
-    3edc:	c0 e0       	ldi	r28, 0x00	; 0
-    3ede:	d1 e0       	ldi	r29, 0x01	; 1
+    3ece:	80 e0       	ldi	r24, 0x00	; 0
+    3ed0:	e8 16       	cp	r14, r24
+    3ed2:	88 e3       	ldi	r24, 0x38	; 56
+    3ed4:	f8 06       	cpc	r15, r24
+    3ed6:	18 f4       	brcc	.+6      	; 0x3ede <main+0xde>
+    3ed8:	f7 01       	movw	r30, r14
+    3eda:	d7 be       	out	0x37, r13	; 55
+    3edc:	e8 95       	spm
+    3ede:	c0 e0       	ldi	r28, 0x00	; 0
+    3ee0:	d1 e0       	ldi	r29, 0x01	; 1
 
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee0:	62 d0       	rcall	.+196    	; 0x3fa6 <getch>
-    3ee2:	89 93       	st	Y+, r24
+    3ee2:	58 d0       	rcall	.+176    	; 0x3f94 <getch>
+    3ee4:	89 93       	st	Y+, r24
       while (--length);
-    3ee4:	0c 17       	cp	r16, r28
-    3ee6:	e1 f7       	brne	.-8      	; 0x3ee0 <main+0xe0>
+    3ee6:	0c 17       	cp	r16, r28
+    3ee8:	e1 f7       	brne	.-8      	; 0x3ee2 <main+0xe2>
 
       // If we are in NRWW section, page erase has to be delayed until now.
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ee8:	f0 e0       	ldi	r31, 0x00	; 0
-    3eea:	cf 16       	cp	r12, r31
-    3eec:	f8 e3       	ldi	r31, 0x38	; 56
-    3eee:	df 06       	cpc	r13, r31
-    3ef0:	18 f0       	brcs	.+6      	; 0x3ef8 <main+0xf8>
-    3ef2:	f6 01       	movw	r30, r12
-    3ef4:	b7 be       	out	0x37, r11	; 55
-    3ef6:	e8 95       	spm
+    3eea:	f0 e0       	ldi	r31, 0x00	; 0
+    3eec:	ef 16       	cp	r14, r31
+    3eee:	f8 e3       	ldi	r31, 0x38	; 56
+    3ef0:	ff 06       	cpc	r15, r31
+    3ef2:	18 f0       	brcs	.+6      	; 0x3efa <main+0xfa>
+    3ef4:	f7 01       	movw	r30, r14
+    3ef6:	d7 be       	out	0x37, r13	; 55
+    3ef8:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ef8:	68 d0       	rcall	.+208    	; 0x3fca <verifySpace>
+    3efa:	5e d0       	rcall	.+188    	; 0x3fb8 <verifySpace>
 
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3efa:	07 b6       	in	r0, 0x37	; 55
-    3efc:	00 fc       	sbrc	r0, 0
-    3efe:	fd cf       	rjmp	.-6      	; 0x3efa <main+0xfa>
-    3f00:	a6 01       	movw	r20, r12
-    3f02:	a0 e0       	ldi	r26, 0x00	; 0
-    3f04:	b1 e0       	ldi	r27, 0x01	; 1
+    3efc:	07 b6       	in	r0, 0x37	; 55
+    3efe:	00 fc       	sbrc	r0, 0
+    3f00:	fd cf       	rjmp	.-6      	; 0x3efc <main+0xfc>
+    3f02:	a7 01       	movw	r20, r14
+    3f04:	a0 e0       	ldi	r26, 0x00	; 0
+    3f06:	b1 e0       	ldi	r27, 0x01	; 1
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3f06:	2c 91       	ld	r18, X
-    3f08:	30 e0       	ldi	r19, 0x00	; 0
+    3f08:	2c 91       	ld	r18, X
+    3f0a:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3f0a:	11 96       	adiw	r26, 0x01	; 1
-    3f0c:	8c 91       	ld	r24, X
-    3f0e:	11 97       	sbiw	r26, 0x01	; 1
-    3f10:	90 e0       	ldi	r25, 0x00	; 0
-    3f12:	98 2f       	mov	r25, r24
-    3f14:	88 27       	eor	r24, r24
-    3f16:	82 2b       	or	r24, r18
-    3f18:	93 2b       	or	r25, r19
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    3f0c:	11 96       	adiw	r26, 0x01	; 1
+    3f0e:	8c 91       	ld	r24, X
+    3f10:	11 97       	sbiw	r26, 0x01	; 1
+    3f12:	90 e0       	ldi	r25, 0x00	; 0
+    3f14:	98 2f       	mov	r25, r24
+    3f16:	88 27       	eor	r24, r24
+    3f18:	82 2b       	or	r24, r18
+    3f1a:	93 2b       	or	r25, r19
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
 int main(void) {
-    3f1a:	12 96       	adiw	r26, 0x02	; 2
+    3f1c:	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);
-    3f1c:	fa 01       	movw	r30, r20
-    3f1e:	0c 01       	movw	r0, r24
-    3f20:	87 be       	out	0x37, r8	; 55
-    3f22:	e8 95       	spm
-    3f24:	11 24       	eor	r1, r1
+    3f1e:	fa 01       	movw	r30, r20
+    3f20:	0c 01       	movw	r0, r24
+    3f22:	a7 be       	out	0x37, r10	; 55
+    3f24:	e8 95       	spm
+    3f26:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f26:	4e 5f       	subi	r20, 0xFE	; 254
-    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f28:	4e 5f       	subi	r20, 0xFE	; 254
+    3f2a:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f2a:	f1 e0       	ldi	r31, 0x01	; 1
-    3f2c:	a0 38       	cpi	r26, 0x80	; 128
-    3f2e:	bf 07       	cpc	r27, r31
-    3f30:	51 f7       	brne	.-44     	; 0x3f06 <main+0x106>
+    3f2c:	f1 e0       	ldi	r31, 0x01	; 1
+    3f2e:	a0 38       	cpi	r26, 0x80	; 128
+    3f30:	bf 07       	cpc	r27, r31
+    3f32:	51 f7       	brne	.-44     	; 0x3f08 <main+0x108>
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f32:	f6 01       	movw	r30, r12
-    3f34:	a7 be       	out	0x37, r10	; 55
-    3f36:	e8 95       	spm
+    3f34:	f7 01       	movw	r30, r14
+    3f36:	c7 be       	out	0x37, r12	; 55
+    3f38:	e8 95       	spm
       boot_spm_busy_wait();
-    3f38:	07 b6       	in	r0, 0x37	; 55
-    3f3a:	00 fc       	sbrc	r0, 0
-    3f3c:	fd cf       	rjmp	.-6      	; 0x3f38 <main+0x138>
+    3f3a:	07 b6       	in	r0, 0x37	; 55
+    3f3c:	00 fc       	sbrc	r0, 0
+    3f3e:	fd cf       	rjmp	.-6      	; 0x3f3a <main+0x13a>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
-    3f42:	26 c0       	rjmp	.+76     	; 0x3f90 <main+0x190>
+    3f40:	b7 be       	out	0x37, r11	; 55
+    3f42:	e8 95       	spm
+    3f44:	1c c0       	rjmp	.+56     	; 0x3f7e <main+0x17e>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f44:	84 37       	cpi	r24, 0x74	; 116
-    3f46:	b1 f4       	brne	.+44     	; 0x3f74 <main+0x174>
+    3f46:	84 37       	cpi	r24, 0x74	; 116
+    3f48:	61 f4       	brne	.+24     	; 0x3f62 <main+0x162>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    3f48:	2e d0       	rcall	.+92     	; 0x3fa6 <getch>
+    3f4a:	24 d0       	rcall	.+72     	; 0x3f94 <getch>
       length = getch();
-    3f4a:	2d d0       	rcall	.+90     	; 0x3fa6 <getch>
-    3f4c:	f8 2e       	mov	r15, r24
+    3f4c:	23 d0       	rcall	.+70     	; 0x3f94 <getch>
+    3f4e:	08 2f       	mov	r16, r24
       getch();
-    3f4e:	2b d0       	rcall	.+86     	; 0x3fa6 <getch>
+    3f50:	21 d0       	rcall	.+66     	; 0x3f94 <getch>
 
       verifySpace();
-    3f50:	3c d0       	rcall	.+120    	; 0x3fca <verifySpace>
-    3f52:	f6 01       	movw	r30, r12
-    3f54:	ef 2c       	mov	r14, r15
-        putch(result);
-        address++;
-      }
-      while (--length);
+    3f52:	32 d0       	rcall	.+100    	; 0x3fb8 <verifySpace>
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-    3f56:	8f 01       	movw	r16, r30
-    3f58:	0f 5f       	subi	r16, 0xFF	; 255
-    3f5a:	1f 4f       	sbci	r17, 0xFF	; 255
-    3f5c:	84 91       	lpm	r24, Z+
-    3f5e:	1b d0       	rcall	.+54     	; 0x3f96 <putch>
-      while (--length);
-    3f60:	ea 94       	dec	r14
-    3f62:	f8 01       	movw	r30, r16
-    3f64:	c1 f7       	brne	.-16     	; 0x3f56 <main+0x156>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-/* main program starts here */
-int main(void) {
-    3f66:	08 94       	sec
-    3f68:	c1 1c       	adc	r12, r1
-    3f6a:	d1 1c       	adc	r13, r1
-    3f6c:	fa 94       	dec	r15
-    3f6e:	cf 0c       	add	r12, r15
-    3f70:	d1 1c       	adc	r13, r1
-    3f72:	0e c0       	rjmp	.+28     	; 0x3f90 <main+0x190>
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+    3f54:	f7 01       	movw	r30, r14
+    3f56:	85 91       	lpm	r24, Z+
+    3f58:	7f 01       	movw	r14, r30
+    3f5a:	14 d0       	rcall	.+40     	; 0x3f84 <putch>
+      } while (--length);
+    3f5c:	01 50       	subi	r16, 0x01	; 1
+    3f5e:	d1 f7       	brne	.-12     	; 0x3f54 <main+0x154>
+    3f60:	0e c0       	rjmp	.+28     	; 0x3f7e <main+0x17e>
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f74:	85 37       	cpi	r24, 0x75	; 117
-    3f76:	39 f4       	brne	.+14     	; 0x3f86 <main+0x186>
+    3f62:	85 37       	cpi	r24, 0x75	; 117
+    3f64:	39 f4       	brne	.+14     	; 0x3f74 <main+0x174>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f78:	28 d0       	rcall	.+80     	; 0x3fca <verifySpace>
+    3f66:	28 d0       	rcall	.+80     	; 0x3fb8 <verifySpace>
       putch(SIGNATURE_0);
-    3f7a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7c:	0c d0       	rcall	.+24     	; 0x3f96 <putch>
+    3f68:	8e e1       	ldi	r24, 0x1E	; 30
+    3f6a:	0c d0       	rcall	.+24     	; 0x3f84 <putch>
       putch(SIGNATURE_1);
-    3f7e:	84 e9       	ldi	r24, 0x94	; 148
-    3f80:	0a d0       	rcall	.+20     	; 0x3f96 <putch>
+    3f6c:	84 e9       	ldi	r24, 0x94	; 148
+    3f6e:	0a d0       	rcall	.+20     	; 0x3f84 <putch>
       putch(SIGNATURE_2);
-    3f82:	86 e0       	ldi	r24, 0x06	; 6
-    3f84:	7a cf       	rjmp	.-268    	; 0x3e7a <main+0x7a>
+    3f70:	86 e0       	ldi	r24, 0x06	; 6
+    3f72:	84 cf       	rjmp	.-248    	; 0x3e7c <main+0x7c>
     }
-    else if (ch == 'Q') {
-    3f86:	81 35       	cpi	r24, 0x51	; 81
-    3f88:	11 f4       	brne	.+4      	; 0x3f8e <main+0x18e>
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+    3f74:	81 35       	cpi	r24, 0x51	; 81
+    3f76:	11 f4       	brne	.+4      	; 0x3f7c <main+0x17c>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8a:	88 e0       	ldi	r24, 0x08	; 8
-    3f8c:	18 d0       	rcall	.+48     	; 0x3fbe <watchdogConfig>
+    3f78:	88 e0       	ldi	r24, 0x08	; 8
+    3f7a:	18 d0       	rcall	.+48     	; 0x3fac <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f8e:	1d d0       	rcall	.+58     	; 0x3fca <verifySpace>
+    3f7c:	1d d0       	rcall	.+58     	; 0x3fb8 <verifySpace>
     }
     putch(STK_OK);
-    3f90:	80 e1       	ldi	r24, 0x10	; 16
-    3f92:	01 d0       	rcall	.+2      	; 0x3f96 <putch>
-    3f94:	65 cf       	rjmp	.-310    	; 0x3e60 <main+0x60>
+    3f7e:	80 e1       	ldi	r24, 0x10	; 16
+    3f80:	01 d0       	rcall	.+2      	; 0x3f84 <putch>
+    3f82:	6e cf       	rjmp	.-292    	; 0x3e60 <main+0x60>
 
-00003f96 <putch>:
+00003f84 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f96:	98 2f       	mov	r25, r24
+    3f84:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-    3f98:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9c:	85 ff       	sbrs	r24, 5
-    3f9e:	fc cf       	rjmp	.-8      	; 0x3f98 <putch+0x2>
-  UDR0 = ch;
-    3fa0:	90 93 c6 00 	sts	0x00C6, r25
+  while (!(UART_SRA & _BV(UDRE0)));
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	85 ff       	sbrs	r24, 5
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <putch+0x2>
+  UART_UDR = ch;
+    3f8e:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa4:	08 95       	ret
+    3f92:	08 95       	ret
 
-00003fa6 <getch>:
+00003f94 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
-  while(!(UCSR0A & _BV(RXC0)))
-    3fa6:	80 91 c0 00 	lds	r24, 0x00C0
-    3faa:	87 ff       	sbrs	r24, 7
-    3fac:	fc cf       	rjmp	.-8      	; 0x3fa6 <getch>
+  while(!(UART_SRA & _BV(RXC0)))
+    3f94:	80 91 c0 00 	lds	r24, 0x00C0
+    3f98:	87 ff       	sbrs	r24, 7
+    3f9a:	fc cf       	rjmp	.-8      	; 0x3f94 <getch>
     ;
-  if (!(UCSR0A & _BV(FE0))) {
-    3fae:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb2:	84 fd       	sbrc	r24, 4
-    3fb4:	01 c0       	rjmp	.+2      	; 0x3fb8 <getch+0x12>
+  if (!(UART_SRA & _BV(FE0))) {
+    3f9c:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa0:	84 fd       	sbrc	r24, 4
+    3fa2:	01 c0       	rjmp	.+2      	; 0x3fa6 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb6:	a8 95       	wdr
+    3fa4:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
-  ch = UDR0;
-    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
+  ch = UART_UDR;
+    3fa6:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbc:	08 95       	ret
+    3faa:	08 95       	ret
 
-00003fbe <watchdogConfig>:
+00003fac <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fbe:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc2:	98 e1       	ldi	r25, 0x18	; 24
-    3fc4:	90 83       	st	Z, r25
+    3fac:	e0 e6       	ldi	r30, 0x60	; 96
+    3fae:	f0 e0       	ldi	r31, 0x00	; 0
+    3fb0:	98 e1       	ldi	r25, 0x18	; 24
+    3fb2:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc6:	80 83       	st	Z, r24
+    3fb4:	80 83       	st	Z, r24
 }
-    3fc8:	08 95       	ret
+    3fb6:	08 95       	ret
 
-00003fca <verifySpace>:
+00003fb8 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fca:	ed df       	rcall	.-38     	; 0x3fa6 <getch>
-    3fcc:	80 32       	cpi	r24, 0x20	; 32
-    3fce:	19 f0       	breq	.+6      	; 0x3fd6 <verifySpace+0xc>
+    3fb8:	ed df       	rcall	.-38     	; 0x3f94 <getch>
+    3fba:	80 32       	cpi	r24, 0x20	; 32
+    3fbc:	19 f0       	breq	.+6      	; 0x3fc4 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd0:	88 e0       	ldi	r24, 0x08	; 8
-    3fd2:	f5 df       	rcall	.-22     	; 0x3fbe <watchdogConfig>
-    3fd4:	ff cf       	rjmp	.-2      	; 0x3fd4 <verifySpace+0xa>
+    3fbe:	88 e0       	ldi	r24, 0x08	; 8
+    3fc0:	f5 df       	rcall	.-22     	; 0x3fac <watchdogConfig>
+    3fc2:	ff cf       	rjmp	.-2      	; 0x3fc2 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd6:	84 e1       	ldi	r24, 0x14	; 20
+    3fc4:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fd8:	de cf       	rjmp	.-68     	; 0x3f96 <putch>
+    3fc6:	de cf       	rjmp	.-68     	; 0x3f84 <putch>
 
-00003fda <getNch>:
+00003fc8 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fda:	1f 93       	push	r17
-    3fdc:	18 2f       	mov	r17, r24
+    3fc8:	1f 93       	push	r17
+    3fca:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fde:	e3 df       	rcall	.-58     	; 0x3fa6 <getch>
-    3fe0:	11 50       	subi	r17, 0x01	; 1
-    3fe2:	e9 f7       	brne	.-6      	; 0x3fde <getNch+0x4>
+    3fcc:	e3 df       	rcall	.-58     	; 0x3f94 <getch>
+    3fce:	11 50       	subi	r17, 0x01	; 1
+    3fd0:	e9 f7       	brne	.-6      	; 0x3fcc <getNch+0x4>
   verifySpace();
-    3fe4:	f2 df       	rcall	.-28     	; 0x3fca <verifySpace>
+    3fd2:	f2 df       	rcall	.-28     	; 0x3fb8 <verifySpace>
 }
-    3fe6:	1f 91       	pop	r17
-    3fe8:	08 95       	ret
+    3fd4:	1f 91       	pop	r17
+    3fd6:	08 95       	ret
 
-00003fea <appStart>:
+00003fd8 <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fea:	80 e0       	ldi	r24, 0x00	; 0
-    3fec:	e8 df       	rcall	.-48     	; 0x3fbe <watchdogConfig>
+    3fd8:	80 e0       	ldi	r24, 0x00	; 0
+    3fda:	e8 df       	rcall	.-48     	; 0x3fac <watchdogConfig>
   __asm__ __volatile__ (
-    3fee:	ee 27       	eor	r30, r30
-    3ff0:	ff 27       	eor	r31, r31
-    3ff2:	09 94       	ijmp
+    3fdc:	ee 27       	eor	r30, r30
+    3fde:	ff 27       	eor	r31, r31
+    3fe0:	09 94       	ijmp

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

@@ -1,41 +1,41 @@
-:101D0000112484B714BE81FF24D185E08EBD8EE0FE
-:101D10000CD1D49AD29A86E023EC3FEF91E03DBDFE
+:101D0000112484B714BE81FF26D185E08EBD8EE0FC
+:101D10000ED1D49AD29A86E023EC3FEF91E03DBDFC
 :101D20002CBD9BB9589BFECFCC9AA8958150B9F792
 :101D3000EE24FF2493E0992EBB24B39485E0A82ED3
-:101D40000FE7D02E1EECC12EDDD0813461F4DAD045
-:101D5000082FEFD0023811F0013811F484E001C0EF
-: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
-:0C1F5000089580E0EADFE4E0FF27099438
-:021EFE000404DA
+:101D40000FE7D02E1EECC12EDFD0813471F4DCD031
+:101D5000082FF1D0023811F486E005C0013811F4E3
+:101D600084E001C083E0C1D0BDC0823411F484E1BD
+:101D700003C0853419F485E0E6D0B4C0853579F424
+:101D8000C3D0E82EFF24C0D0082F10E0102F00276A
+:101D90000E291F29000F111FCED07801A3C0863550
+:101DA00021F484E0D0D080E0DECF843609F05FC03B
+:101DB000ABD0AAD0182FA8D0C0E0D1E0A5D089938D
+:101DC0001C17E1F7F70197BEE895B5D007B600FC00
+:101DD000FDCFE114F10411F0A7012AC080910001A8
+:101DE0002091010130E0322F222790E0282B392B5F
+:101DF000309385012093840140910801809109016D
+:101E000090E0982F882750E0842B952B90938701A2
+:101E1000809386012450304020930801232F3327DC
+:101E200020930901D0920001C092010140E050E0EE
+:101E3000A0E0B1E02C9130E011968C91119790E0E8
+:101E4000982F8827822B932B1296FA010C01B7BE8C
+:101E5000E89511244E5F5F4FF1E0A034BF0751F7C2
+:101E6000F701A7BEE89507B600FCFDCF3BC084375D
+:101E700059F54AD049D0182F47D05DD0E701012F3E
+:101E8000209719F48091840114C0C130D10519F450
+:101E9000809185010EC0C830D10519F4809186016A
+:101EA00008C0C930D10519F48091870102C0FE0134
+:101EB000849121961AD0015019F70894E11CF11C65
+:101EC0001150E10EF11C0EC0853739F434D08EE18B
+:101ED0000CD083E90AD08CE046CF813511F488E03C
+:101EE00026D029D080E101D02FCF2AE030E08095A4
+:101EF000089410F4DA9802C0DA9A000014D013D0D3
+:101F000086952A95B1F7089529E030E0CB99FECF68
+:101F10000AD009D008D08894CB9908942A9511F05A
+:101F20008795F7CF08959EE09A95F1F7089598E187
+:101F300091BD81BD0895E8DF803219F088E0F7DFB8
+:101F4000FFCF84E1D2CF1F93182FDEDF1150E9F7C6
+:101F5000F2DF1F91089580E0EADFE4E0FF270994B3
+:021EFE000604D8
 :0400000300001D00DC
 :00000001FF

+ 288 - 281
optiboot/bootloaders/optiboot/optiboot_luminet.lst

@@ -3,34 +3,34 @@ optiboot_luminet.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         0000025c  00001d00  00001d00  00000054  2**1
+  0 .text         00000260  00001d00  00001d00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00001efe  00001efe  000002b0  2**0
+  1 .version      00000002  00001efe  00001efe  000002b4  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  000002b2  2**0
+  2 .debug_aranges 00000028  00000000  00000000  000002b6  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000006d  00000000  00000000  000002da  2**0
+  3 .debug_pubnames 0000006d  00000000  00000000  000002de  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002bc  00000000  00000000  00000347  2**0
+  4 .debug_info   000002bc  00000000  00000000  0000034b  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000176  00000000  00000000  00000603  2**0
+  5 .debug_abbrev 00000176  00000000  00000000  00000607  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   000004b0  00000000  00000000  00000779  2**0
+  6 .debug_line   000004b8  00000000  00000000  0000077d  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000090  00000000  00000000  00000c2c  2**2
+  7 .debug_frame  00000090  00000000  00000000  00000c38  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000152  00000000  00000000  00000cbc  2**0
+  8 .debug_str    00000149  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002a1  00000000  00000000  00000e0e  2**0
+  9 .debug_loc    000002a1  00000000  00000000  00000e11  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000098  00000000  00000000  000010af  2**0
+ 10 .debug_ranges 00000098  00000000  00000000  000010b2  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00001d00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,21 +47,21 @@ int main(void) {
     1d04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     1d06:	81 ff       	sbrs	r24, 1
-    1d08:	24 d1       	rcall	.+584    	; 0x1f52 <appStart>
+    1d08:	26 d1       	rcall	.+588    	; 0x1f56 <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
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  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>
+    1d10:	0e d1       	rcall	.+540    	; 0x1f2e <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -157,492 +157,499 @@ void watchdogReset() {
   for (;;) {
     /* get character from UART */
     ch = getch();
-    1d48:	dd d0       	rcall	.+442    	; 0x1f04 <getch>
+    1d48:	df d0       	rcall	.+446    	; 0x1f08 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     1d4a:	81 34       	cpi	r24, 0x41	; 65
-    1d4c:	61 f4       	brne	.+24     	; 0x1d66 <main+0x66>
+    1d4c:	71 f4       	brne	.+28     	; 0x1d6a <main+0x6a>
       unsigned char which = getch();
-    1d4e:	da d0       	rcall	.+436    	; 0x1f04 <getch>
+    1d4e:	dc d0       	rcall	.+440    	; 0x1f08 <getch>
     1d50:	08 2f       	mov	r16, r24
       verifySpace();
-    1d52:	ef d0       	rcall	.+478    	; 0x1f32 <verifySpace>
+    1d52:	f1 d0       	rcall	.+482    	; 0x1f36 <verifySpace>
       if (which == 0x82) {
     1d54:	02 38       	cpi	r16, 0x82	; 130
-    1d56:	11 f0       	breq	.+4      	; 0x1d5c <main+0x5c>
+    1d56:	11 f4       	brne	.+4      	; 0x1d5c <main+0x5c>
 	/*
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
+    1d58:	86 e0       	ldi	r24, 0x06	; 6
+    1d5a:	05 c0       	rjmp	.+10     	; 0x1d66 <main+0x66>
       } else if (which == 0x81) {
-    1d58:	01 38       	cpi	r16, 0x81	; 129
-    1d5a:	11 f4       	brne	.+4      	; 0x1d60 <main+0x60>
+    1d5c:	01 38       	cpi	r16, 0x81	; 129
+    1d5e:	11 f4       	brne	.+4      	; 0x1d64 <main+0x64>
 	  putch(OPTIBOOT_MAJVER);
-    1d5c:	84 e0       	ldi	r24, 0x04	; 4
-    1d5e:	01 c0       	rjmp	.+2      	; 0x1d62 <main+0x62>
+    1d60:	84 e0       	ldi	r24, 0x04	; 4
+    1d62:	01 c0       	rjmp	.+2      	; 0x1d66 <main+0x66>
       } 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>
+    1d64:	83 e0       	ldi	r24, 0x03	; 3
+    1d66:	c1 d0       	rcall	.+386    	; 0x1eea <putch>
+    1d68:	bd c0       	rjmp	.+378    	; 0x1ee4 <main+0x1e4>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    1d66:	82 34       	cpi	r24, 0x42	; 66
-    1d68:	11 f4       	brne	.+4      	; 0x1d6e <main+0x6e>
+    1d6a:	82 34       	cpi	r24, 0x42	; 66
+    1d6c:	11 f4       	brne	.+4      	; 0x1d72 <main+0x72>
       // SET DEVICE is ignored
       getNch(20);
-    1d6a:	84 e1       	ldi	r24, 0x14	; 20
-    1d6c:	03 c0       	rjmp	.+6      	; 0x1d74 <main+0x74>
+    1d6e:	84 e1       	ldi	r24, 0x14	; 20
+    1d70:	03 c0       	rjmp	.+6      	; 0x1d78 <main+0x78>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    1d6e:	85 34       	cpi	r24, 0x45	; 69
-    1d70:	19 f4       	brne	.+6      	; 0x1d78 <main+0x78>
+    1d72:	85 34       	cpi	r24, 0x45	; 69
+    1d74:	19 f4       	brne	.+6      	; 0x1d7c <main+0x7c>
       // 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>
+    1d76:	85 e0       	ldi	r24, 0x05	; 5
+    1d78:	e6 d0       	rcall	.+460    	; 0x1f46 <getNch>
+    1d7a:	b4 c0       	rjmp	.+360    	; 0x1ee4 <main+0x1e4>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    1d78:	85 35       	cpi	r24, 0x55	; 85
-    1d7a:	79 f4       	brne	.+30     	; 0x1d9a <main+0x9a>
+    1d7c:	85 35       	cpi	r24, 0x55	; 85
+    1d7e:	79 f4       	brne	.+30     	; 0x1d9e <main+0x9e>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    1d7c:	c3 d0       	rcall	.+390    	; 0x1f04 <getch>
+    1d80:	c3 d0       	rcall	.+390    	; 0x1f08 <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
+    1d82:	e8 2e       	mov	r14, r24
+    1d84:	ff 24       	eor	r15, r15
+    1d86:	c0 d0       	rcall	.+384    	; 0x1f08 <getch>
+    1d88:	08 2f       	mov	r16, r24
+    1d8a:	10 e0       	ldi	r17, 0x00	; 0
+    1d8c:	10 2f       	mov	r17, r16
+    1d8e:	00 27       	eor	r16, r16
+    1d90:	0e 29       	or	r16, r14
+    1d92:	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
+    1d94:	00 0f       	add	r16, r16
+    1d96:	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>
+    1d98:	ce d0       	rcall	.+412    	; 0x1f36 <verifySpace>
+    1d9a:	78 01       	movw	r14, r16
+    1d9c:	a3 c0       	rjmp	.+326    	; 0x1ee4 <main+0x1e4>
     }
     else if(ch == STK_UNIVERSAL) {
-    1d9a:	86 35       	cpi	r24, 0x56	; 86
-    1d9c:	21 f4       	brne	.+8      	; 0x1da6 <main+0xa6>
+    1d9e:	86 35       	cpi	r24, 0x56	; 86
+    1da0:	21 f4       	brne	.+8      	; 0x1daa <main+0xaa>
       // UNIVERSAL command is ignored
       getNch(4);
-    1d9e:	84 e0       	ldi	r24, 0x04	; 4
-    1da0:	d0 d0       	rcall	.+416    	; 0x1f42 <getNch>
+    1da2:	84 e0       	ldi	r24, 0x04	; 4
+    1da4:	d0 d0       	rcall	.+416    	; 0x1f46 <getNch>
       putch(0x00);
-    1da2:	80 e0       	ldi	r24, 0x00	; 0
-    1da4:	de cf       	rjmp	.-68     	; 0x1d62 <main+0x62>
+    1da6:	80 e0       	ldi	r24, 0x00	; 0
+    1da8:	de cf       	rjmp	.-68     	; 0x1d66 <main+0x66>
     }
     /* 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>
+    1daa:	84 36       	cpi	r24, 0x64	; 100
+    1dac:	09 f0       	breq	.+2      	; 0x1db0 <main+0xb0>
+    1dae:	5f c0       	rjmp	.+190    	; 0x1e6e <main+0x16e>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    1dac:	ab d0       	rcall	.+342    	; 0x1f04 <getch>
+    1db0:	ab d0       	rcall	.+342    	; 0x1f08 <getch>
       length = getch();
-    1dae:	aa d0       	rcall	.+340    	; 0x1f04 <getch>
-    1db0:	18 2f       	mov	r17, r24
+    1db2:	aa d0       	rcall	.+340    	; 0x1f08 <getch>
+    1db4:	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
+    1db6:	a8 d0       	rcall	.+336    	; 0x1f08 <getch>
+    1db8:	c0 e0       	ldi	r28, 0x00	; 0
+    1dba:	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
       bufPtr = buff;
       do *bufPtr++ = getch();
-    1db8:	a5 d0       	rcall	.+330    	; 0x1f04 <getch>
-    1dba:	89 93       	st	Y+, r24
+    1dbc:	a5 d0       	rcall	.+330    	; 0x1f08 <getch>
+    1dbe:	89 93       	st	Y+, r24
       while (--length);
-    1dbc:	1c 17       	cp	r17, r28
-    1dbe:	e1 f7       	brne	.-8      	; 0x1db8 <main+0xb8>
+    1dc0:	1c 17       	cp	r17, r28
+    1dc2:	e1 f7       	brne	.-8      	; 0x1dbc <main+0xbc>
 
       // If we are in NRWW section, page erase has to be delayed until now.
       // Todo: Take RAMPZ into account
       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
+    1dc4:	f7 01       	movw	r30, r14
+    1dc6:	97 be       	out	0x37, r9	; 55
+    1dc8:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    1dc6:	b5 d0       	rcall	.+362    	; 0x1f32 <verifySpace>
+    1dca:	b5 d0       	rcall	.+362    	; 0x1f36 <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>
+    1dcc:	07 b6       	in	r0, 0x37	; 55
+    1dce:	00 fc       	sbrc	r0, 0
+    1dd0:	fd cf       	rjmp	.-6      	; 0x1dcc <main+0xcc>
 
 #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>
+    1dd2:	e1 14       	cp	r14, r1
+    1dd4:	f1 04       	cpc	r15, r1
+    1dd6:	11 f0       	breq	.+4      	; 0x1ddc <main+0xdc>
+    1dd8:	a7 01       	movw	r20, r14
+    1dda:	2a c0       	rjmp	.+84     	; 0x1e30 <main+0x130>
         // 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
+    1ddc:	80 91 00 01 	lds	r24, 0x0100
+    1de0:	20 91 01 01 	lds	r18, 0x0101
+    1de4:	30 e0       	ldi	r19, 0x00	; 0
+    1de6:	32 2f       	mov	r19, r18
+    1de8:	22 27       	eor	r18, r18
+    1dea:	90 e0       	ldi	r25, 0x00	; 0
+    1dec:	28 2b       	or	r18, r24
+    1dee:	39 2b       	or	r19, r25
         rstVect = vect;
-    1dec:	30 93 85 01 	sts	0x0185, r19
-    1df0:	20 93 84 01 	sts	0x0184, r18
+    1df0:	30 93 85 01 	sts	0x0185, r19
+    1df4:	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
+    1df8:	40 91 08 01 	lds	r20, 0x0108
+    1dfc:	80 91 09 01 	lds	r24, 0x0109
+    1e00:	90 e0       	ldi	r25, 0x00	; 0
+    1e02:	98 2f       	mov	r25, r24
+    1e04:	88 27       	eor	r24, r24
+    1e06:	50 e0       	ldi	r21, 0x00	; 0
+    1e08:	84 2b       	or	r24, r20
+    1e0a:	95 2b       	or	r25, r21
+    1e0c:	90 93 87 01 	sts	0x0187, r25
+    1e10:	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
+    1e14:	24 50       	subi	r18, 0x04	; 4
+    1e16:	30 40       	sbci	r19, 0x00	; 0
         buff[8] = vect & 0xff;
-    1e14:	20 93 08 01 	sts	0x0108, r18
+    1e18:	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
+    1e1c:	23 2f       	mov	r18, r19
+    1e1e:	33 27       	eor	r19, r19
+    1e20:	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
+    1e24:	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
+    1e28:	c0 92 01 01 	sts	0x0101, r12
+    1e2c:	40 e0       	ldi	r20, 0x00	; 0
+    1e2e:	50 e0       	ldi	r21, 0x00	; 0
+    1e30:	a0 e0       	ldi	r26, 0x00	; 0
+    1e32:	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
+    1e34:	2c 91       	ld	r18, X
+    1e36:	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 rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    1e38:	11 96       	adiw	r26, 0x01	; 1
+    1e3a:	8c 91       	ld	r24, X
+    1e3c:	11 97       	sbiw	r26, 0x01	; 1
+    1e3e:	90 e0       	ldi	r25, 0x00	; 0
+    1e40:	98 2f       	mov	r25, r24
+    1e42:	88 27       	eor	r24, r24
+    1e44:	82 2b       	or	r24, r18
+    1e46:	93 2b       	or	r25, r19
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
 int main(void) {
-    1e44:	12 96       	adiw	r26, 0x02	; 2
+    1e48:	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
+    1e4a:	fa 01       	movw	r30, r20
+    1e4c:	0c 01       	movw	r0, r24
+    1e4e:	b7 be       	out	0x37, r11	; 55
+    1e50:	e8 95       	spm
+    1e52:	11 24       	eor	r1, r1
         addrPtr += 2;
-    1e50:	4e 5f       	subi	r20, 0xFE	; 254
-    1e52:	5f 4f       	sbci	r21, 0xFF	; 255
+    1e54:	4e 5f       	subi	r20, 0xFE	; 254
+    1e56:	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>
+    1e58:	f1 e0       	ldi	r31, 0x01	; 1
+    1e5a:	a0 34       	cpi	r26, 0x40	; 64
+    1e5c:	bf 07       	cpc	r27, r31
+    1e5e:	51 f7       	brne	.-44     	; 0x1e34 <main+0x134>
 
       // 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
+    1e60:	f7 01       	movw	r30, r14
+    1e62:	a7 be       	out	0x37, r10	; 55
+    1e64:	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>
+    1e66:	07 b6       	in	r0, 0x37	; 55
+    1e68:	00 fc       	sbrc	r0, 0
+    1e6a:	fd cf       	rjmp	.-6      	; 0x1e66 <main+0x166>
+    1e6c:	3b c0       	rjmp	.+118    	; 0x1ee4 <main+0x1e4>
       boot_rww_enable();
 #endif
 
     }
     /* 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>
+    1e6e:	84 37       	cpi	r24, 0x74	; 116
+    1e70:	59 f5       	brne	.+86     	; 0x1ec8 <main+0x1c8>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    1e6e:	4a d0       	rcall	.+148    	; 0x1f04 <getch>
+    1e72:	4a d0       	rcall	.+148    	; 0x1f08 <getch>
       length = getch();
-    1e70:	49 d0       	rcall	.+146    	; 0x1f04 <getch>
-    1e72:	18 2f       	mov	r17, r24
+    1e74:	49 d0       	rcall	.+146    	; 0x1f08 <getch>
+    1e76:	18 2f       	mov	r17, r24
       getch();
-    1e74:	47 d0       	rcall	.+142    	; 0x1f04 <getch>
+    1e78:	47 d0       	rcall	.+142    	; 0x1f08 <getch>
 
       verifySpace();
-    1e76:	5d d0       	rcall	.+186    	; 0x1f32 <verifySpace>
-    1e78:	e7 01       	movw	r28, r14
-    1e7a:	01 2f       	mov	r16, r17
-#ifdef VIRTUAL_BOOT_PARTITION
+    1e7a:	5d d0       	rcall	.+186    	; 0x1f36 <verifySpace>
+    1e7c:	e7 01       	movw	r28, r14
+    1e7e:	01 2f       	mov	r16, r17
       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>
+    1e80:	20 97       	sbiw	r28, 0x00	; 0
+    1e82:	19 f4       	brne	.+6      	; 0x1e8a <main+0x18a>
+    1e84:	80 91 84 01 	lds	r24, 0x0184
+    1e88:	14 c0       	rjmp	.+40     	; 0x1eb2 <main+0x1b2>
         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>
+    1e8a:	c1 30       	cpi	r28, 0x01	; 1
+    1e8c:	d1 05       	cpc	r29, r1
+    1e8e:	19 f4       	brne	.+6      	; 0x1e96 <main+0x196>
+    1e90:	80 91 85 01 	lds	r24, 0x0185
+    1e94:	0e c0       	rjmp	.+28     	; 0x1eb2 <main+0x1b2>
         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>
+    1e96:	c8 30       	cpi	r28, 0x08	; 8
+    1e98:	d1 05       	cpc	r29, r1
+    1e9a:	19 f4       	brne	.+6      	; 0x1ea2 <main+0x1a2>
+    1e9c:	80 91 86 01 	lds	r24, 0x0186
+    1ea0:	08 c0       	rjmp	.+16     	; 0x1eb2 <main+0x1b2>
         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>
+    1ea2:	c9 30       	cpi	r28, 0x09	; 9
+    1ea4:	d1 05       	cpc	r29, r1
+    1ea6:	19 f4       	brne	.+6      	; 0x1eae <main+0x1ae>
+    1ea8:	80 91 87 01 	lds	r24, 0x0187
+    1eac:	02 c0       	rjmp	.+4      	; 0x1eb2 <main+0x1b2>
         else ch = pgm_read_byte_near(address);
-    1eaa:	fe 01       	movw	r30, r28
-    1eac:	84 91       	lpm	r24, Z+
+    1eae:	fe 01       	movw	r30, r28
+    1eb0:	84 91       	lpm	r24, Z+
         address++;
-    1eae:	21 96       	adiw	r28, 0x01	; 1
+    1eb2:	21 96       	adiw	r28, 0x01	; 1
+        __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);
-    1eb0:	1a d0       	rcall	.+52     	; 0x1ee6 <putch>
+    1eb4:	1a d0       	rcall	.+52     	; 0x1eea <putch>
       } while (--length);
-    1eb2:	01 50       	subi	r16, 0x01	; 1
-    1eb4:	19 f7       	brne	.-58     	; 0x1e7c <main+0x17c>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    1eb6:	01 50       	subi	r16, 0x01	; 1
+    1eb8:	19 f7       	brne	.-58     	; 0x1e80 <main+0x180>
+# 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>
-#endif
-#endif
+    1eba:	08 94       	sec
+    1ebc:	e1 1c       	adc	r14, r1
+    1ebe:	f1 1c       	adc	r15, r1
+    1ec0:	11 50       	subi	r17, 0x01	; 1
+    1ec2:	e1 0e       	add	r14, r17
+    1ec4:	f1 1c       	adc	r15, r1
+    1ec6:	0e c0       	rjmp	.+28     	; 0x1ee4 <main+0x1e4>
+        putch(ch);
+      } while (--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>
+    1ec8:	85 37       	cpi	r24, 0x75	; 117
+    1eca:	39 f4       	brne	.+14     	; 0x1eda <main+0x1da>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    1ec8:	34 d0       	rcall	.+104    	; 0x1f32 <verifySpace>
+    1ecc:	34 d0       	rcall	.+104    	; 0x1f36 <verifySpace>
       putch(SIGNATURE_0);
-    1eca:	8e e1       	ldi	r24, 0x1E	; 30
-    1ecc:	0c d0       	rcall	.+24     	; 0x1ee6 <putch>
+    1ece:	8e e1       	ldi	r24, 0x1E	; 30
+    1ed0:	0c d0       	rcall	.+24     	; 0x1eea <putch>
       putch(SIGNATURE_1);
-    1ece:	83 e9       	ldi	r24, 0x93	; 147
-    1ed0:	0a d0       	rcall	.+20     	; 0x1ee6 <putch>
+    1ed2:	83 e9       	ldi	r24, 0x93	; 147
+    1ed4:	0a d0       	rcall	.+20     	; 0x1eea <putch>
       putch(SIGNATURE_2);
-    1ed2:	8c e0       	ldi	r24, 0x0C	; 12
-    1ed4:	46 cf       	rjmp	.-372    	; 0x1d62 <main+0x62>
+    1ed6:	8c e0       	ldi	r24, 0x0C	; 12
+    1ed8:	46 cf       	rjmp	.-372    	; 0x1d66 <main+0x66>
     }
-    else if (ch == 'Q') {
-    1ed6:	81 35       	cpi	r24, 0x51	; 81
-    1ed8:	11 f4       	brne	.+4      	; 0x1ede <main+0x1de>
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+    1eda:	81 35       	cpi	r24, 0x51	; 81
+    1edc:	11 f4       	brne	.+4      	; 0x1ee2 <main+0x1e2>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    1eda:	88 e0       	ldi	r24, 0x08	; 8
-    1edc:	26 d0       	rcall	.+76     	; 0x1f2a <watchdogConfig>
+    1ede:	88 e0       	ldi	r24, 0x08	; 8
+    1ee0:	26 d0       	rcall	.+76     	; 0x1f2e <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    1ede:	29 d0       	rcall	.+82     	; 0x1f32 <verifySpace>
+    1ee2:	29 d0       	rcall	.+82     	; 0x1f36 <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>
+    1ee4:	80 e1       	ldi	r24, 0x10	; 16
+    1ee6:	01 d0       	rcall	.+2      	; 0x1eea <putch>
+    1ee8:	2f cf       	rjmp	.-418    	; 0x1d48 <main+0x48>
 
-00001ee6 <putch>:
+00001eea <putch>:
 void putch(char ch) {
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-  UDR0 = ch;
+  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>
+    1eea:	2a e0       	ldi	r18, 0x0A	; 10
+    1eec:	30 e0       	ldi	r19, 0x00	; 0
+    1eee:	80 95       	com	r24
+    1ef0:	08 94       	sec
+    1ef2:	10 f4       	brcc	.+4      	; 0x1ef8 <putch+0xe>
+    1ef4:	da 98       	cbi	0x1b, 2	; 27
+    1ef6:	02 c0       	rjmp	.+4      	; 0x1efc <putch+0x12>
+    1ef8:	da 9a       	sbi	0x1b, 2	; 27
+    1efa:	00 00       	nop
+    1efc:	14 d0       	rcall	.+40     	; 0x1f26 <uartDelay>
+    1efe:	13 d0       	rcall	.+38     	; 0x1f26 <uartDelay>
+    1f00:	86 95       	lsr	r24
+    1f02:	2a 95       	dec	r18
+    1f04:	b1 f7       	brne	.-20     	; 0x1ef2 <putch+0x8>
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    1f02:	08 95       	ret
+    1f06:	08 95       	ret
 
-00001f04 <getch>:
+00001f08 <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>:
+    1f08:	29 e0       	ldi	r18, 0x09	; 9
+    1f0a:	30 e0       	ldi	r19, 0x00	; 0
+    1f0c:	cb 99       	sbic	0x19, 3	; 25
+    1f0e:	fe cf       	rjmp	.-4      	; 0x1f0c <getch+0x4>
+    1f10:	0a d0       	rcall	.+20     	; 0x1f26 <uartDelay>
+    1f12:	09 d0       	rcall	.+18     	; 0x1f26 <uartDelay>
+    1f14:	08 d0       	rcall	.+16     	; 0x1f26 <uartDelay>
+    1f16:	88 94       	clc
+    1f18:	cb 99       	sbic	0x19, 3	; 25
+    1f1a:	08 94       	sec
+    1f1c:	2a 95       	dec	r18
+    1f1e:	11 f0       	breq	.+4      	; 0x1f24 <getch+0x1c>
+    1f20:	87 95       	ror	r24
+    1f22:	f7 cf       	rjmp	.-18     	; 0x1f12 <getch+0xa>
+    1f24:	08 95       	ret
+
+00001f26 <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
+    1f26:	9e e0       	ldi	r25, 0x0E	; 14
+    1f28:	9a 95       	dec	r25
+    1f2a:	f1 f7       	brne	.-4      	; 0x1f28 <uartDelay+0x2>
+    1f2c:	08 95       	ret
 
-00001f2a <watchdogConfig>:
+00001f2e <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
+    1f2e:	98 e1       	ldi	r25, 0x18	; 24
+    1f30:	91 bd       	out	0x21, r25	; 33
   WDTCSR = x;
-    1f2e:	81 bd       	out	0x21, r24	; 33
+    1f32:	81 bd       	out	0x21, r24	; 33
 }
-    1f30:	08 95       	ret
+    1f34:	08 95       	ret
 
-00001f32 <verifySpace>:
+00001f36 <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>
+    1f36:	e8 df       	rcall	.-48     	; 0x1f08 <getch>
+    1f38:	80 32       	cpi	r24, 0x20	; 32
+    1f3a:	19 f0       	breq	.+6      	; 0x1f42 <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>
+    1f3c:	88 e0       	ldi	r24, 0x08	; 8
+    1f3e:	f7 df       	rcall	.-18     	; 0x1f2e <watchdogConfig>
+    1f40:	ff cf       	rjmp	.-2      	; 0x1f40 <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
+    1f42:	84 e1       	ldi	r24, 0x14	; 20
 }
-    1f40:	d2 cf       	rjmp	.-92     	; 0x1ee6 <putch>
+    1f44:	d2 cf       	rjmp	.-92     	; 0x1eea <putch>
 
-00001f42 <getNch>:
+00001f46 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    1f42:	1f 93       	push	r17
-    1f44:	18 2f       	mov	r17, r24
+    1f46:	1f 93       	push	r17
+    1f48:	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>
+    1f4a:	de df       	rcall	.-68     	; 0x1f08 <getch>
+    1f4c:	11 50       	subi	r17, 0x01	; 1
+    1f4e:	e9 f7       	brne	.-6      	; 0x1f4a <getNch+0x4>
   verifySpace();
-    1f4c:	f2 df       	rcall	.-28     	; 0x1f32 <verifySpace>
+    1f50:	f2 df       	rcall	.-28     	; 0x1f36 <verifySpace>
 }
-    1f4e:	1f 91       	pop	r17
-    1f50:	08 95       	ret
+    1f52:	1f 91       	pop	r17
+    1f54:	08 95       	ret
 
-00001f52 <appStart>:
+00001f56 <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    1f52:	80 e0       	ldi	r24, 0x00	; 0
-    1f54:	ea df       	rcall	.-44     	; 0x1f2a <watchdogConfig>
+    1f56:	80 e0       	ldi	r24, 0x00	; 0
+    1f58:	ea df       	rcall	.-44     	; 0x1f2e <watchdogConfig>
   __asm__ __volatile__ (
-    1f56:	e4 e0       	ldi	r30, 0x04	; 4
-    1f58:	ff 27       	eor	r31, r31
-    1f5a:	09 94       	ijmp
+    1f5a:	e4 e0       	ldi	r30, 0x04	; 4
+    1f5c:	ff 27       	eor	r31, r31
+    1f5e:	09 94       	ijmp

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

@@ -1,35 +1,34 @@
-:103E0000112484B714BE81FFF0D085E08093810037
+:103E0000112484B714BE81FFE7D085E08093810040
 :103E100082E08093C00088E18093C10086E08093B7
-:103E2000C20080E18093C4008EE0C9D0259A86E06C
+:103E2000C20080E18093C4008EE0C0D0259A86E075
 :103E300020E33CEF91E0309385002093840096BB13
-:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
-:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
-:103E6000A2D0813461F49FD0082FAFD0023811F076
-:103E7000013811F484E001C083E08DD089C0823420
-:103E800011F484E103C0853419F485E0A6D080C024
-:103E9000853579F488D0E82EFF2485D0082F10E0EE
-:103EA000102F00270E291F29000F111F8ED0680127
-:103EB0006FC0863521F484E090D080E0DECF843678
-:103EC00009F040C070D06FD0082F6DD080E0C816C8
-:103ED00088E3D80618F4F601B7BEE895C0E0D1E053
-:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
-:103EF00018F0F601B7BEE89568D007B600FCFDCF14
-:103F0000A601A0E0B1E02C9130E011968C911197C0
-:103F100090E0982F8827822B932B1296FA010C01A0
-:103F200087BEE89511244E5F5F4FF1E0A038BF07D0
-:103F300051F7F601A7BEE89507B600FCFDCF97BE86
-:103F4000E89526C08437B1F42ED02DD0F82E2BD092
-:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
-:103F6000EA94F801C1F70894C11CD11CFA94CF0C53
-:103F7000D11C0EC0853739F428D08EE10CD084E9ED
-:103F80000AD086E07ACF813511F488E018D01DD0B0
-:103F900080E101D065CF982F8091C00085FFFCCFD4
-:103FA0009093C60008958091C00087FFFCCF809158
-:103FB000C00084FD01C0A8958091C6000895E0E688
-:103FC000F0E098E1908380830895EDDF803219F06E
-:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
-:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
-:043FF000FF2709940A
-:023FFE000404B9
+:103E4000B09BFECF1D9AA8958150A9F7EE24FF24C0
+:103E5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2E85
+:103E600099D0813469F496D0082FA6D0023809F48D
+:103E70007FC0013811F484E001C083E083D07FC0AB
+:103E8000823411F484E103C0853419F485E09CD0B8
+:103E900076C0853579F47ED0E82EFF247BD0082FBC
+:103EA00010E0102F00270E291F29000F111F84D0AA
+:103EB000780165C0863521F484E086D080E0DECFCD
+:103EC000843609F040C066D065D0082F63D080E00A
+:103ED000E81688E3F80618F4F701D7BEE895C0E0C5
+:103EE000D1E058D089930C17E1F7F0E0EF16F8E332
+:103EF000FF0618F0F701D7BEE8955ED007B600FCC4
+:103F0000FDCFA701A0E0B1E02C9130E011968C919B
+:103F1000119790E0982F8827822B932B1296FA0105
+:103F20000C01A7BEE89511244E5F5F4FF1E0A03869
+:103F3000BF0751F7F701C7BEE89507B600FCFDCFF4
+:103F4000B7BEE8951CC0843761F424D023D0082F75
+:103F500021D032D0F70185917F0114D00150D1F7E3
+:103F60000EC0853739F428D08EE10CD084E90AD010
+:103F700086E084CF813511F488E018D01DD080E12F
+:103F800001D06ECF982F8091C00085FFFCCF909319
+:103F9000C60008958091C00087FFFCCF8091C000CB
+:103FA00084FD01C0A8958091C6000895E0E6F0E088
+:103FB00098E1908380830895EDDF803219F088E0E6
+:103FC000F5DFFFCF84E1DECF1F93182FE3DF115021
+:103FD000E9F7F2DF1F91089580E0E8DFEE27FF2781
+:023FE000099442
+:023FFE000604B7
 :0400000300003E00BB
 :00000001FF

+ 230 - 247
optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst

@@ -3,34 +3,34 @@ optiboot_pro_16MHz.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f4  00003e00  00003e00  00000054  2**1
+  0 .text         000001e2  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  00000248  2**0
+  1 .version      00000002  00003ffe  00003ffe  00000236  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  0000024a  2**0
+  2 .debug_aranges 00000028  00000000  00000000  00000238  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000005f  00000000  00000000  00000272  2**0
+  3 .debug_pubnames 0000005f  00000000  00000000  00000260  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002a8  00000000  00000000  000002d1  2**0
+  4 .debug_info   0000027e  00000000  00000000  000002bf  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000178  00000000  00000000  00000579  2**0
+  5 .debug_abbrev 0000016b  00000000  00000000  0000053d  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000046b  00000000  00000000  000006f1  2**0
+  6 .debug_line   00000460  00000000  00000000  000006a8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000b5c  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000b08  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000143  00000000  00000000  00000bdc  2**0
+  8 .debug_str    00000128  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d8  00000000  00000000  00000d1f  2**0
+  9 .debug_loc    00000253  00000000  00000000  00000cb0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000078  00000000  00000000  00000ff7  2**0
+ 10 .debug_ranges 00000078  00000000  00000000  00000f03  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00003e00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,7 +47,7 @@ int main(void) {
     3e04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e06:	81 ff       	sbrs	r24, 1
-    3e08:	f0 d0       	rcall	.+480    	; 0x3fea <appStart>
+    3e08:	e7 d0       	rcall	.+462    	; 0x3fd8 <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -59,16 +59,16 @@ int main(void) {
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
-  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UART_SRA = _BV(U2X0); //Double speed mode USART0
     3e10:	82 e0       	ldi	r24, 0x02	; 2
     3e12:	80 93 c0 00 	sts	0x00C0, r24
-  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
     3e16:	88 e1       	ldi	r24, 0x18	; 24
     3e18:	80 93 c1 00 	sts	0x00C1, r24
-  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
     3e1c:	86 e0       	ldi	r24, 0x06	; 6
     3e1e:	80 93 c2 00 	sts	0x00C2, r24
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
     3e22:	80 e1       	ldi	r24, 0x10	; 16
     3e24:	80 93 c4 00 	sts	0x00C4, r24
 #endif
@@ -77,7 +77,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e28:	8e e0       	ldi	r24, 0x0E	; 14
-    3e2a:	c9 d0       	rcall	.+402    	; 0x3fbe <watchdogConfig>
+    3e2a:	c0 d0       	rcall	.+384    	; 0x3fac <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -126,30 +126,30 @@ void watchdogReset() {
   } while (--count);
     3e48:	81 50       	subi	r24, 0x01	; 1
     3e4a:	a9 f7       	brne	.-22     	; 0x3e36 <main+0x36>
-    3e4c:	cc 24       	eor	r12, r12
-    3e4e:	dd 24       	eor	r13, r13
+    3e4c:	ee 24       	eor	r14, r14
+    3e4e:	ff 24       	eor	r15, r15
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e50:	88 24       	eor	r8, r8
-    3e52:	83 94       	inc	r8
+    3e50:	aa 24       	eor	r10, r10
+    3e52:	a3 94       	inc	r10
         addrPtr += 2;
       } while (--ch);
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e54:	b5 e0       	ldi	r27, 0x05	; 5
-    3e56:	ab 2e       	mov	r10, r27
+    3e56:	cb 2e       	mov	r12, r27
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e58:	a1 e1       	ldi	r26, 0x11	; 17
-    3e5a:	9a 2e       	mov	r9, r26
+    3e5a:	ba 2e       	mov	r11, r26
       do *bufPtr++ = getch();
       while (--length);
 
@@ -157,442 +157,425 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3e5c:	f3 e0       	ldi	r31, 0x03	; 3
-    3e5e:	bf 2e       	mov	r11, r31
+    3e5e:	df 2e       	mov	r13, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e60:	a2 d0       	rcall	.+324    	; 0x3fa6 <getch>
+    3e60:	99 d0       	rcall	.+306    	; 0x3f94 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e62:	81 34       	cpi	r24, 0x41	; 65
-    3e64:	61 f4       	brne	.+24     	; 0x3e7e <main+0x7e>
+    3e64:	69 f4       	brne	.+26     	; 0x3e80 <main+0x80>
       unsigned char which = getch();
-    3e66:	9f d0       	rcall	.+318    	; 0x3fa6 <getch>
+    3e66:	96 d0       	rcall	.+300    	; 0x3f94 <getch>
     3e68:	08 2f       	mov	r16, r24
       verifySpace();
-    3e6a:	af d0       	rcall	.+350    	; 0x3fca <verifySpace>
+    3e6a:	a6 d0       	rcall	.+332    	; 0x3fb8 <verifySpace>
       if (which == 0x82) {
     3e6c:	02 38       	cpi	r16, 0x82	; 130
-    3e6e:	11 f0       	breq	.+4      	; 0x3e74 <main+0x74>
+    3e6e:	09 f4       	brne	.+2      	; 0x3e72 <main+0x72>
+    3e70:	7f c0       	rjmp	.+254    	; 0x3f70 <main+0x170>
 	/*
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
       } else if (which == 0x81) {
-    3e70:	01 38       	cpi	r16, 0x81	; 129
-    3e72:	11 f4       	brne	.+4      	; 0x3e78 <main+0x78>
+    3e72:	01 38       	cpi	r16, 0x81	; 129
+    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(OPTIBOOT_MAJVER);
-    3e74:	84 e0       	ldi	r24, 0x04	; 4
-    3e76:	01 c0       	rjmp	.+2      	; 0x3e7a <main+0x7a>
+    3e76:	84 e0       	ldi	r24, 0x04	; 4
+    3e78:	01 c0       	rjmp	.+2      	; 0x3e7c <main+0x7c>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    3e78:	83 e0       	ldi	r24, 0x03	; 3
-    3e7a:	8d d0       	rcall	.+282    	; 0x3f96 <putch>
-    3e7c:	89 c0       	rjmp	.+274    	; 0x3f90 <main+0x190>
+    3e7a:	83 e0       	ldi	r24, 0x03	; 3
+    3e7c:	83 d0       	rcall	.+262    	; 0x3f84 <putch>
+    3e7e:	7f c0       	rjmp	.+254    	; 0x3f7e <main+0x17e>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    3e7e:	82 34       	cpi	r24, 0x42	; 66
-    3e80:	11 f4       	brne	.+4      	; 0x3e86 <main+0x86>
+    3e80:	82 34       	cpi	r24, 0x42	; 66
+    3e82:	11 f4       	brne	.+4      	; 0x3e88 <main+0x88>
       // SET DEVICE is ignored
       getNch(20);
-    3e82:	84 e1       	ldi	r24, 0x14	; 20
-    3e84:	03 c0       	rjmp	.+6      	; 0x3e8c <main+0x8c>
+    3e84:	84 e1       	ldi	r24, 0x14	; 20
+    3e86:	03 c0       	rjmp	.+6      	; 0x3e8e <main+0x8e>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e86:	85 34       	cpi	r24, 0x45	; 69
-    3e88:	19 f4       	brne	.+6      	; 0x3e90 <main+0x90>
+    3e88:	85 34       	cpi	r24, 0x45	; 69
+    3e8a:	19 f4       	brne	.+6      	; 0x3e92 <main+0x92>
       // SET DEVICE EXT is ignored
       getNch(5);
-    3e8a:	85 e0       	ldi	r24, 0x05	; 5
-    3e8c:	a6 d0       	rcall	.+332    	; 0x3fda <getNch>
-    3e8e:	80 c0       	rjmp	.+256    	; 0x3f90 <main+0x190>
+    3e8c:	85 e0       	ldi	r24, 0x05	; 5
+    3e8e:	9c d0       	rcall	.+312    	; 0x3fc8 <getNch>
+    3e90:	76 c0       	rjmp	.+236    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    3e90:	85 35       	cpi	r24, 0x55	; 85
-    3e92:	79 f4       	brne	.+30     	; 0x3eb2 <main+0xb2>
+    3e92:	85 35       	cpi	r24, 0x55	; 85
+    3e94:	79 f4       	brne	.+30     	; 0x3eb4 <main+0xb4>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e94:	88 d0       	rcall	.+272    	; 0x3fa6 <getch>
+    3e96:	7e d0       	rcall	.+252    	; 0x3f94 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e96:	e8 2e       	mov	r14, r24
-    3e98:	ff 24       	eor	r15, r15
-    3e9a:	85 d0       	rcall	.+266    	; 0x3fa6 <getch>
-    3e9c:	08 2f       	mov	r16, r24
-    3e9e:	10 e0       	ldi	r17, 0x00	; 0
-    3ea0:	10 2f       	mov	r17, r16
-    3ea2:	00 27       	eor	r16, r16
-    3ea4:	0e 29       	or	r16, r14
-    3ea6:	1f 29       	or	r17, r15
+    3e98:	e8 2e       	mov	r14, r24
+    3e9a:	ff 24       	eor	r15, r15
+    3e9c:	7b d0       	rcall	.+246    	; 0x3f94 <getch>
+    3e9e:	08 2f       	mov	r16, r24
+    3ea0:	10 e0       	ldi	r17, 0x00	; 0
+    3ea2:	10 2f       	mov	r17, r16
+    3ea4:	00 27       	eor	r16, r16
+    3ea6:	0e 29       	or	r16, r14
+    3ea8:	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
-    3ea8:	00 0f       	add	r16, r16
-    3eaa:	11 1f       	adc	r17, r17
+    3eaa:	00 0f       	add	r16, r16
+    3eac:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eac:	8e d0       	rcall	.+284    	; 0x3fca <verifySpace>
-    3eae:	68 01       	movw	r12, r16
-    3eb0:	6f c0       	rjmp	.+222    	; 0x3f90 <main+0x190>
+    3eae:	84 d0       	rcall	.+264    	; 0x3fb8 <verifySpace>
+    3eb0:	78 01       	movw	r14, r16
+    3eb2:	65 c0       	rjmp	.+202    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_UNIVERSAL) {
-    3eb2:	86 35       	cpi	r24, 0x56	; 86
-    3eb4:	21 f4       	brne	.+8      	; 0x3ebe <main+0xbe>
+    3eb4:	86 35       	cpi	r24, 0x56	; 86
+    3eb6:	21 f4       	brne	.+8      	; 0x3ec0 <main+0xc0>
       // UNIVERSAL command is ignored
       getNch(4);
-    3eb6:	84 e0       	ldi	r24, 0x04	; 4
-    3eb8:	90 d0       	rcall	.+288    	; 0x3fda <getNch>
+    3eb8:	84 e0       	ldi	r24, 0x04	; 4
+    3eba:	86 d0       	rcall	.+268    	; 0x3fc8 <getNch>
       putch(0x00);
-    3eba:	80 e0       	ldi	r24, 0x00	; 0
-    3ebc:	de cf       	rjmp	.-68     	; 0x3e7a <main+0x7a>
+    3ebc:	80 e0       	ldi	r24, 0x00	; 0
+    3ebe:	de cf       	rjmp	.-68     	; 0x3e7c <main+0x7c>
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    3ebe:	84 36       	cpi	r24, 0x64	; 100
-    3ec0:	09 f0       	breq	.+2      	; 0x3ec4 <main+0xc4>
-    3ec2:	40 c0       	rjmp	.+128    	; 0x3f44 <main+0x144>
+    3ec0:	84 36       	cpi	r24, 0x64	; 100
+    3ec2:	09 f0       	breq	.+2      	; 0x3ec6 <main+0xc6>
+    3ec4:	40 c0       	rjmp	.+128    	; 0x3f46 <main+0x146>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    3ec4:	70 d0       	rcall	.+224    	; 0x3fa6 <getch>
+    3ec6:	66 d0       	rcall	.+204    	; 0x3f94 <getch>
       length = getch();
-    3ec6:	6f d0       	rcall	.+222    	; 0x3fa6 <getch>
-    3ec8:	08 2f       	mov	r16, r24
+    3ec8:	65 d0       	rcall	.+202    	; 0x3f94 <getch>
+    3eca:	08 2f       	mov	r16, r24
       getch();
-    3eca:	6d d0       	rcall	.+218    	; 0x3fa6 <getch>
+    3ecc:	63 d0       	rcall	.+198    	; 0x3f94 <getch>
 
       // If we are in RWW section, immediately start page erase
       if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ecc:	80 e0       	ldi	r24, 0x00	; 0
-    3ece:	c8 16       	cp	r12, r24
-    3ed0:	88 e3       	ldi	r24, 0x38	; 56
-    3ed2:	d8 06       	cpc	r13, r24
-    3ed4:	18 f4       	brcc	.+6      	; 0x3edc <main+0xdc>
-    3ed6:	f6 01       	movw	r30, r12
-    3ed8:	b7 be       	out	0x37, r11	; 55
-    3eda:	e8 95       	spm
-    3edc:	c0 e0       	ldi	r28, 0x00	; 0
-    3ede:	d1 e0       	ldi	r29, 0x01	; 1
+    3ece:	80 e0       	ldi	r24, 0x00	; 0
+    3ed0:	e8 16       	cp	r14, r24
+    3ed2:	88 e3       	ldi	r24, 0x38	; 56
+    3ed4:	f8 06       	cpc	r15, r24
+    3ed6:	18 f4       	brcc	.+6      	; 0x3ede <main+0xde>
+    3ed8:	f7 01       	movw	r30, r14
+    3eda:	d7 be       	out	0x37, r13	; 55
+    3edc:	e8 95       	spm
+    3ede:	c0 e0       	ldi	r28, 0x00	; 0
+    3ee0:	d1 e0       	ldi	r29, 0x01	; 1
 
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee0:	62 d0       	rcall	.+196    	; 0x3fa6 <getch>
-    3ee2:	89 93       	st	Y+, r24
+    3ee2:	58 d0       	rcall	.+176    	; 0x3f94 <getch>
+    3ee4:	89 93       	st	Y+, r24
       while (--length);
-    3ee4:	0c 17       	cp	r16, r28
-    3ee6:	e1 f7       	brne	.-8      	; 0x3ee0 <main+0xe0>
+    3ee6:	0c 17       	cp	r16, r28
+    3ee8:	e1 f7       	brne	.-8      	; 0x3ee2 <main+0xe2>
 
       // If we are in NRWW section, page erase has to be delayed until now.
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ee8:	f0 e0       	ldi	r31, 0x00	; 0
-    3eea:	cf 16       	cp	r12, r31
-    3eec:	f8 e3       	ldi	r31, 0x38	; 56
-    3eee:	df 06       	cpc	r13, r31
-    3ef0:	18 f0       	brcs	.+6      	; 0x3ef8 <main+0xf8>
-    3ef2:	f6 01       	movw	r30, r12
-    3ef4:	b7 be       	out	0x37, r11	; 55
-    3ef6:	e8 95       	spm
+    3eea:	f0 e0       	ldi	r31, 0x00	; 0
+    3eec:	ef 16       	cp	r14, r31
+    3eee:	f8 e3       	ldi	r31, 0x38	; 56
+    3ef0:	ff 06       	cpc	r15, r31
+    3ef2:	18 f0       	brcs	.+6      	; 0x3efa <main+0xfa>
+    3ef4:	f7 01       	movw	r30, r14
+    3ef6:	d7 be       	out	0x37, r13	; 55
+    3ef8:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ef8:	68 d0       	rcall	.+208    	; 0x3fca <verifySpace>
+    3efa:	5e d0       	rcall	.+188    	; 0x3fb8 <verifySpace>
 
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3efa:	07 b6       	in	r0, 0x37	; 55
-    3efc:	00 fc       	sbrc	r0, 0
-    3efe:	fd cf       	rjmp	.-6      	; 0x3efa <main+0xfa>
-    3f00:	a6 01       	movw	r20, r12
-    3f02:	a0 e0       	ldi	r26, 0x00	; 0
-    3f04:	b1 e0       	ldi	r27, 0x01	; 1
+    3efc:	07 b6       	in	r0, 0x37	; 55
+    3efe:	00 fc       	sbrc	r0, 0
+    3f00:	fd cf       	rjmp	.-6      	; 0x3efc <main+0xfc>
+    3f02:	a7 01       	movw	r20, r14
+    3f04:	a0 e0       	ldi	r26, 0x00	; 0
+    3f06:	b1 e0       	ldi	r27, 0x01	; 1
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3f06:	2c 91       	ld	r18, X
-    3f08:	30 e0       	ldi	r19, 0x00	; 0
+    3f08:	2c 91       	ld	r18, X
+    3f0a:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3f0a:	11 96       	adiw	r26, 0x01	; 1
-    3f0c:	8c 91       	ld	r24, X
-    3f0e:	11 97       	sbiw	r26, 0x01	; 1
-    3f10:	90 e0       	ldi	r25, 0x00	; 0
-    3f12:	98 2f       	mov	r25, r24
-    3f14:	88 27       	eor	r24, r24
-    3f16:	82 2b       	or	r24, r18
-    3f18:	93 2b       	or	r25, r19
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    3f0c:	11 96       	adiw	r26, 0x01	; 1
+    3f0e:	8c 91       	ld	r24, X
+    3f10:	11 97       	sbiw	r26, 0x01	; 1
+    3f12:	90 e0       	ldi	r25, 0x00	; 0
+    3f14:	98 2f       	mov	r25, r24
+    3f16:	88 27       	eor	r24, r24
+    3f18:	82 2b       	or	r24, r18
+    3f1a:	93 2b       	or	r25, r19
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
 int main(void) {
-    3f1a:	12 96       	adiw	r26, 0x02	; 2
+    3f1c:	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);
-    3f1c:	fa 01       	movw	r30, r20
-    3f1e:	0c 01       	movw	r0, r24
-    3f20:	87 be       	out	0x37, r8	; 55
-    3f22:	e8 95       	spm
-    3f24:	11 24       	eor	r1, r1
+    3f1e:	fa 01       	movw	r30, r20
+    3f20:	0c 01       	movw	r0, r24
+    3f22:	a7 be       	out	0x37, r10	; 55
+    3f24:	e8 95       	spm
+    3f26:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f26:	4e 5f       	subi	r20, 0xFE	; 254
-    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f28:	4e 5f       	subi	r20, 0xFE	; 254
+    3f2a:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f2a:	f1 e0       	ldi	r31, 0x01	; 1
-    3f2c:	a0 38       	cpi	r26, 0x80	; 128
-    3f2e:	bf 07       	cpc	r27, r31
-    3f30:	51 f7       	brne	.-44     	; 0x3f06 <main+0x106>
+    3f2c:	f1 e0       	ldi	r31, 0x01	; 1
+    3f2e:	a0 38       	cpi	r26, 0x80	; 128
+    3f30:	bf 07       	cpc	r27, r31
+    3f32:	51 f7       	brne	.-44     	; 0x3f08 <main+0x108>
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f32:	f6 01       	movw	r30, r12
-    3f34:	a7 be       	out	0x37, r10	; 55
-    3f36:	e8 95       	spm
+    3f34:	f7 01       	movw	r30, r14
+    3f36:	c7 be       	out	0x37, r12	; 55
+    3f38:	e8 95       	spm
       boot_spm_busy_wait();
-    3f38:	07 b6       	in	r0, 0x37	; 55
-    3f3a:	00 fc       	sbrc	r0, 0
-    3f3c:	fd cf       	rjmp	.-6      	; 0x3f38 <main+0x138>
+    3f3a:	07 b6       	in	r0, 0x37	; 55
+    3f3c:	00 fc       	sbrc	r0, 0
+    3f3e:	fd cf       	rjmp	.-6      	; 0x3f3a <main+0x13a>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
-    3f42:	26 c0       	rjmp	.+76     	; 0x3f90 <main+0x190>
+    3f40:	b7 be       	out	0x37, r11	; 55
+    3f42:	e8 95       	spm
+    3f44:	1c c0       	rjmp	.+56     	; 0x3f7e <main+0x17e>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f44:	84 37       	cpi	r24, 0x74	; 116
-    3f46:	b1 f4       	brne	.+44     	; 0x3f74 <main+0x174>
+    3f46:	84 37       	cpi	r24, 0x74	; 116
+    3f48:	61 f4       	brne	.+24     	; 0x3f62 <main+0x162>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    3f48:	2e d0       	rcall	.+92     	; 0x3fa6 <getch>
+    3f4a:	24 d0       	rcall	.+72     	; 0x3f94 <getch>
       length = getch();
-    3f4a:	2d d0       	rcall	.+90     	; 0x3fa6 <getch>
-    3f4c:	f8 2e       	mov	r15, r24
+    3f4c:	23 d0       	rcall	.+70     	; 0x3f94 <getch>
+    3f4e:	08 2f       	mov	r16, r24
       getch();
-    3f4e:	2b d0       	rcall	.+86     	; 0x3fa6 <getch>
+    3f50:	21 d0       	rcall	.+66     	; 0x3f94 <getch>
 
       verifySpace();
-    3f50:	3c d0       	rcall	.+120    	; 0x3fca <verifySpace>
-    3f52:	f6 01       	movw	r30, r12
-    3f54:	ef 2c       	mov	r14, r15
-        putch(result);
-        address++;
-      }
-      while (--length);
+    3f52:	32 d0       	rcall	.+100    	; 0x3fb8 <verifySpace>
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-    3f56:	8f 01       	movw	r16, r30
-    3f58:	0f 5f       	subi	r16, 0xFF	; 255
-    3f5a:	1f 4f       	sbci	r17, 0xFF	; 255
-    3f5c:	84 91       	lpm	r24, Z+
-    3f5e:	1b d0       	rcall	.+54     	; 0x3f96 <putch>
-      while (--length);
-    3f60:	ea 94       	dec	r14
-    3f62:	f8 01       	movw	r30, r16
-    3f64:	c1 f7       	brne	.-16     	; 0x3f56 <main+0x156>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-/* main program starts here */
-int main(void) {
-    3f66:	08 94       	sec
-    3f68:	c1 1c       	adc	r12, r1
-    3f6a:	d1 1c       	adc	r13, r1
-    3f6c:	fa 94       	dec	r15
-    3f6e:	cf 0c       	add	r12, r15
-    3f70:	d1 1c       	adc	r13, r1
-    3f72:	0e c0       	rjmp	.+28     	; 0x3f90 <main+0x190>
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+    3f54:	f7 01       	movw	r30, r14
+    3f56:	85 91       	lpm	r24, Z+
+    3f58:	7f 01       	movw	r14, r30
+    3f5a:	14 d0       	rcall	.+40     	; 0x3f84 <putch>
+      } while (--length);
+    3f5c:	01 50       	subi	r16, 0x01	; 1
+    3f5e:	d1 f7       	brne	.-12     	; 0x3f54 <main+0x154>
+    3f60:	0e c0       	rjmp	.+28     	; 0x3f7e <main+0x17e>
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f74:	85 37       	cpi	r24, 0x75	; 117
-    3f76:	39 f4       	brne	.+14     	; 0x3f86 <main+0x186>
+    3f62:	85 37       	cpi	r24, 0x75	; 117
+    3f64:	39 f4       	brne	.+14     	; 0x3f74 <main+0x174>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f78:	28 d0       	rcall	.+80     	; 0x3fca <verifySpace>
+    3f66:	28 d0       	rcall	.+80     	; 0x3fb8 <verifySpace>
       putch(SIGNATURE_0);
-    3f7a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7c:	0c d0       	rcall	.+24     	; 0x3f96 <putch>
+    3f68:	8e e1       	ldi	r24, 0x1E	; 30
+    3f6a:	0c d0       	rcall	.+24     	; 0x3f84 <putch>
       putch(SIGNATURE_1);
-    3f7e:	84 e9       	ldi	r24, 0x94	; 148
-    3f80:	0a d0       	rcall	.+20     	; 0x3f96 <putch>
+    3f6c:	84 e9       	ldi	r24, 0x94	; 148
+    3f6e:	0a d0       	rcall	.+20     	; 0x3f84 <putch>
       putch(SIGNATURE_2);
-    3f82:	86 e0       	ldi	r24, 0x06	; 6
-    3f84:	7a cf       	rjmp	.-268    	; 0x3e7a <main+0x7a>
+    3f70:	86 e0       	ldi	r24, 0x06	; 6
+    3f72:	84 cf       	rjmp	.-248    	; 0x3e7c <main+0x7c>
     }
-    else if (ch == 'Q') {
-    3f86:	81 35       	cpi	r24, 0x51	; 81
-    3f88:	11 f4       	brne	.+4      	; 0x3f8e <main+0x18e>
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+    3f74:	81 35       	cpi	r24, 0x51	; 81
+    3f76:	11 f4       	brne	.+4      	; 0x3f7c <main+0x17c>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8a:	88 e0       	ldi	r24, 0x08	; 8
-    3f8c:	18 d0       	rcall	.+48     	; 0x3fbe <watchdogConfig>
+    3f78:	88 e0       	ldi	r24, 0x08	; 8
+    3f7a:	18 d0       	rcall	.+48     	; 0x3fac <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f8e:	1d d0       	rcall	.+58     	; 0x3fca <verifySpace>
+    3f7c:	1d d0       	rcall	.+58     	; 0x3fb8 <verifySpace>
     }
     putch(STK_OK);
-    3f90:	80 e1       	ldi	r24, 0x10	; 16
-    3f92:	01 d0       	rcall	.+2      	; 0x3f96 <putch>
-    3f94:	65 cf       	rjmp	.-310    	; 0x3e60 <main+0x60>
+    3f7e:	80 e1       	ldi	r24, 0x10	; 16
+    3f80:	01 d0       	rcall	.+2      	; 0x3f84 <putch>
+    3f82:	6e cf       	rjmp	.-292    	; 0x3e60 <main+0x60>
 
-00003f96 <putch>:
+00003f84 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f96:	98 2f       	mov	r25, r24
+    3f84:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-    3f98:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9c:	85 ff       	sbrs	r24, 5
-    3f9e:	fc cf       	rjmp	.-8      	; 0x3f98 <putch+0x2>
-  UDR0 = ch;
-    3fa0:	90 93 c6 00 	sts	0x00C6, r25
+  while (!(UART_SRA & _BV(UDRE0)));
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	85 ff       	sbrs	r24, 5
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <putch+0x2>
+  UART_UDR = ch;
+    3f8e:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa4:	08 95       	ret
+    3f92:	08 95       	ret
 
-00003fa6 <getch>:
+00003f94 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
-  while(!(UCSR0A & _BV(RXC0)))
-    3fa6:	80 91 c0 00 	lds	r24, 0x00C0
-    3faa:	87 ff       	sbrs	r24, 7
-    3fac:	fc cf       	rjmp	.-8      	; 0x3fa6 <getch>
+  while(!(UART_SRA & _BV(RXC0)))
+    3f94:	80 91 c0 00 	lds	r24, 0x00C0
+    3f98:	87 ff       	sbrs	r24, 7
+    3f9a:	fc cf       	rjmp	.-8      	; 0x3f94 <getch>
     ;
-  if (!(UCSR0A & _BV(FE0))) {
-    3fae:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb2:	84 fd       	sbrc	r24, 4
-    3fb4:	01 c0       	rjmp	.+2      	; 0x3fb8 <getch+0x12>
+  if (!(UART_SRA & _BV(FE0))) {
+    3f9c:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa0:	84 fd       	sbrc	r24, 4
+    3fa2:	01 c0       	rjmp	.+2      	; 0x3fa6 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb6:	a8 95       	wdr
+    3fa4:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
-  ch = UDR0;
-    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
+  ch = UART_UDR;
+    3fa6:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbc:	08 95       	ret
+    3faa:	08 95       	ret
 
-00003fbe <watchdogConfig>:
+00003fac <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fbe:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc2:	98 e1       	ldi	r25, 0x18	; 24
-    3fc4:	90 83       	st	Z, r25
+    3fac:	e0 e6       	ldi	r30, 0x60	; 96
+    3fae:	f0 e0       	ldi	r31, 0x00	; 0
+    3fb0:	98 e1       	ldi	r25, 0x18	; 24
+    3fb2:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc6:	80 83       	st	Z, r24
+    3fb4:	80 83       	st	Z, r24
 }
-    3fc8:	08 95       	ret
+    3fb6:	08 95       	ret
 
-00003fca <verifySpace>:
+00003fb8 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fca:	ed df       	rcall	.-38     	; 0x3fa6 <getch>
-    3fcc:	80 32       	cpi	r24, 0x20	; 32
-    3fce:	19 f0       	breq	.+6      	; 0x3fd6 <verifySpace+0xc>
+    3fb8:	ed df       	rcall	.-38     	; 0x3f94 <getch>
+    3fba:	80 32       	cpi	r24, 0x20	; 32
+    3fbc:	19 f0       	breq	.+6      	; 0x3fc4 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd0:	88 e0       	ldi	r24, 0x08	; 8
-    3fd2:	f5 df       	rcall	.-22     	; 0x3fbe <watchdogConfig>
-    3fd4:	ff cf       	rjmp	.-2      	; 0x3fd4 <verifySpace+0xa>
+    3fbe:	88 e0       	ldi	r24, 0x08	; 8
+    3fc0:	f5 df       	rcall	.-22     	; 0x3fac <watchdogConfig>
+    3fc2:	ff cf       	rjmp	.-2      	; 0x3fc2 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd6:	84 e1       	ldi	r24, 0x14	; 20
+    3fc4:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fd8:	de cf       	rjmp	.-68     	; 0x3f96 <putch>
+    3fc6:	de cf       	rjmp	.-68     	; 0x3f84 <putch>
 
-00003fda <getNch>:
+00003fc8 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fda:	1f 93       	push	r17
-    3fdc:	18 2f       	mov	r17, r24
+    3fc8:	1f 93       	push	r17
+    3fca:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fde:	e3 df       	rcall	.-58     	; 0x3fa6 <getch>
-    3fe0:	11 50       	subi	r17, 0x01	; 1
-    3fe2:	e9 f7       	brne	.-6      	; 0x3fde <getNch+0x4>
+    3fcc:	e3 df       	rcall	.-58     	; 0x3f94 <getch>
+    3fce:	11 50       	subi	r17, 0x01	; 1
+    3fd0:	e9 f7       	brne	.-6      	; 0x3fcc <getNch+0x4>
   verifySpace();
-    3fe4:	f2 df       	rcall	.-28     	; 0x3fca <verifySpace>
+    3fd2:	f2 df       	rcall	.-28     	; 0x3fb8 <verifySpace>
 }
-    3fe6:	1f 91       	pop	r17
-    3fe8:	08 95       	ret
+    3fd4:	1f 91       	pop	r17
+    3fd6:	08 95       	ret
 
-00003fea <appStart>:
+00003fd8 <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fea:	80 e0       	ldi	r24, 0x00	; 0
-    3fec:	e8 df       	rcall	.-48     	; 0x3fbe <watchdogConfig>
+    3fd8:	80 e0       	ldi	r24, 0x00	; 0
+    3fda:	e8 df       	rcall	.-48     	; 0x3fac <watchdogConfig>
   __asm__ __volatile__ (
-    3fee:	ee 27       	eor	r30, r30
-    3ff0:	ff 27       	eor	r31, r31
-    3ff2:	09 94       	ijmp
+    3fdc:	ee 27       	eor	r30, r30
+    3fde:	ff 27       	eor	r31, r31
+    3fe0:	09 94       	ijmp

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

@@ -1,35 +1,34 @@
-:103E0000112484B714BE81FFF0D085E08093810037
+:103E0000112484B714BE81FFE7D085E08093810040
 :103E100082E08093C00088E18093C10086E08093B7
-:103E2000C20085E18093C4008EE0C9D0259A86E067
+:103E2000C20085E18093C4008EE0C0D0259A86E070
 :103E30002CE33BEF91E0309385002093840096BB08
-:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
-:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
-:103E6000A2D0813461F49FD0082FAFD0023811F076
-:103E7000013811F484E001C083E08DD089C0823420
-:103E800011F484E103C0853419F485E0A6D080C024
-:103E9000853579F488D0E82EFF2485D0082F10E0EE
-:103EA000102F00270E291F29000F111F8ED0680127
-:103EB0006FC0863521F484E090D080E0DECF843678
-:103EC00009F040C070D06FD0082F6DD080E0C816C8
-:103ED00088E3D80618F4F601B7BEE895C0E0D1E053
-:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
-:103EF00018F0F601B7BEE89568D007B600FCFDCF14
-:103F0000A601A0E0B1E02C9130E011968C911197C0
-:103F100090E0982F8827822B932B1296FA010C01A0
-:103F200087BEE89511244E5F5F4FF1E0A038BF07D0
-:103F300051F7F601A7BEE89507B600FCFDCF97BE86
-:103F4000E89526C08437B1F42ED02DD0F82E2BD092
-:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
-:103F6000EA94F801C1F70894C11CD11CFA94CF0C53
-:103F7000D11C0EC0853739F428D08EE10CD084E9ED
-:103F80000AD086E07ACF813511F488E018D01DD0B0
-:103F900080E101D065CF982F8091C00085FFFCCFD4
-:103FA0009093C60008958091C00087FFFCCF809158
-:103FB000C00084FD01C0A8958091C6000895E0E688
-:103FC000F0E098E1908380830895EDDF803219F06E
-:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
-:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
-:043FF000FF2709940A
-:023FFE000404B9
+:103E4000B09BFECF1D9AA8958150A9F7EE24FF24C0
+:103E5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2E85
+:103E600099D0813469F496D0082FA6D0023809F48D
+:103E70007FC0013811F484E001C083E083D07FC0AB
+:103E8000823411F484E103C0853419F485E09CD0B8
+:103E900076C0853579F47ED0E82EFF247BD0082FBC
+:103EA00010E0102F00270E291F29000F111F84D0AA
+:103EB000780165C0863521F484E086D080E0DECFCD
+:103EC000843609F040C066D065D0082F63D080E00A
+:103ED000E81688E3F80618F4F701D7BEE895C0E0C5
+:103EE000D1E058D089930C17E1F7F0E0EF16F8E332
+:103EF000FF0618F0F701D7BEE8955ED007B600FCC4
+:103F0000FDCFA701A0E0B1E02C9130E011968C919B
+:103F1000119790E0982F8827822B932B1296FA0105
+:103F20000C01A7BEE89511244E5F5F4FF1E0A03869
+:103F3000BF0751F7F701C7BEE89507B600FCFDCFF4
+:103F4000B7BEE8951CC0843761F424D023D0082F75
+:103F500021D032D0F70185917F0114D00150D1F7E3
+:103F60000EC0853739F428D08EE10CD084E90AD010
+:103F700086E084CF813511F488E018D01DD080E12F
+:103F800001D06ECF982F8091C00085FFFCCF909319
+:103F9000C60008958091C00087FFFCCF8091C000CB
+:103FA00084FD01C0A8958091C6000895E0E6F0E088
+:103FB00098E1908380830895EDDF803219F088E0E6
+:103FC000F5DFFFCF84E1DECF1F93182FE3DF115021
+:103FD000E9F7F2DF1F91089580E0E8DFEE27FF2781
+:023FE000099442
+:023FFE000604B7
 :0400000300003E00BB
 :00000001FF

+ 230 - 247
optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst

@@ -3,34 +3,34 @@ optiboot_pro_20mhz.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f4  00003e00  00003e00  00000054  2**1
+  0 .text         000001e2  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  00000248  2**0
+  1 .version      00000002  00003ffe  00003ffe  00000236  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  0000024a  2**0
+  2 .debug_aranges 00000028  00000000  00000000  00000238  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000005f  00000000  00000000  00000272  2**0
+  3 .debug_pubnames 0000005f  00000000  00000000  00000260  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002a8  00000000  00000000  000002d1  2**0
+  4 .debug_info   0000027e  00000000  00000000  000002bf  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000178  00000000  00000000  00000579  2**0
+  5 .debug_abbrev 0000016b  00000000  00000000  0000053d  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000046b  00000000  00000000  000006f1  2**0
+  6 .debug_line   00000460  00000000  00000000  000006a8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000b5c  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000b08  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000143  00000000  00000000  00000bdc  2**0
+  8 .debug_str    00000128  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d8  00000000  00000000  00000d1f  2**0
+  9 .debug_loc    00000253  00000000  00000000  00000cb0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000078  00000000  00000000  00000ff7  2**0
+ 10 .debug_ranges 00000078  00000000  00000000  00000f03  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00003e00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,7 +47,7 @@ int main(void) {
     3e04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e06:	81 ff       	sbrs	r24, 1
-    3e08:	f0 d0       	rcall	.+480    	; 0x3fea <appStart>
+    3e08:	e7 d0       	rcall	.+462    	; 0x3fd8 <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -59,16 +59,16 @@ int main(void) {
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
-  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UART_SRA = _BV(U2X0); //Double speed mode USART0
     3e10:	82 e0       	ldi	r24, 0x02	; 2
     3e12:	80 93 c0 00 	sts	0x00C0, r24
-  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
     3e16:	88 e1       	ldi	r24, 0x18	; 24
     3e18:	80 93 c1 00 	sts	0x00C1, r24
-  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
     3e1c:	86 e0       	ldi	r24, 0x06	; 6
     3e1e:	80 93 c2 00 	sts	0x00C2, r24
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
     3e22:	85 e1       	ldi	r24, 0x15	; 21
     3e24:	80 93 c4 00 	sts	0x00C4, r24
 #endif
@@ -77,7 +77,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e28:	8e e0       	ldi	r24, 0x0E	; 14
-    3e2a:	c9 d0       	rcall	.+402    	; 0x3fbe <watchdogConfig>
+    3e2a:	c0 d0       	rcall	.+384    	; 0x3fac <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -126,30 +126,30 @@ void watchdogReset() {
   } while (--count);
     3e48:	81 50       	subi	r24, 0x01	; 1
     3e4a:	a9 f7       	brne	.-22     	; 0x3e36 <main+0x36>
-    3e4c:	cc 24       	eor	r12, r12
-    3e4e:	dd 24       	eor	r13, r13
+    3e4c:	ee 24       	eor	r14, r14
+    3e4e:	ff 24       	eor	r15, r15
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e50:	88 24       	eor	r8, r8
-    3e52:	83 94       	inc	r8
+    3e50:	aa 24       	eor	r10, r10
+    3e52:	a3 94       	inc	r10
         addrPtr += 2;
       } while (--ch);
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e54:	b5 e0       	ldi	r27, 0x05	; 5
-    3e56:	ab 2e       	mov	r10, r27
+    3e56:	cb 2e       	mov	r12, r27
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e58:	a1 e1       	ldi	r26, 0x11	; 17
-    3e5a:	9a 2e       	mov	r9, r26
+    3e5a:	ba 2e       	mov	r11, r26
       do *bufPtr++ = getch();
       while (--length);
 
@@ -157,442 +157,425 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3e5c:	f3 e0       	ldi	r31, 0x03	; 3
-    3e5e:	bf 2e       	mov	r11, r31
+    3e5e:	df 2e       	mov	r13, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e60:	a2 d0       	rcall	.+324    	; 0x3fa6 <getch>
+    3e60:	99 d0       	rcall	.+306    	; 0x3f94 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e62:	81 34       	cpi	r24, 0x41	; 65
-    3e64:	61 f4       	brne	.+24     	; 0x3e7e <main+0x7e>
+    3e64:	69 f4       	brne	.+26     	; 0x3e80 <main+0x80>
       unsigned char which = getch();
-    3e66:	9f d0       	rcall	.+318    	; 0x3fa6 <getch>
+    3e66:	96 d0       	rcall	.+300    	; 0x3f94 <getch>
     3e68:	08 2f       	mov	r16, r24
       verifySpace();
-    3e6a:	af d0       	rcall	.+350    	; 0x3fca <verifySpace>
+    3e6a:	a6 d0       	rcall	.+332    	; 0x3fb8 <verifySpace>
       if (which == 0x82) {
     3e6c:	02 38       	cpi	r16, 0x82	; 130
-    3e6e:	11 f0       	breq	.+4      	; 0x3e74 <main+0x74>
+    3e6e:	09 f4       	brne	.+2      	; 0x3e72 <main+0x72>
+    3e70:	7f c0       	rjmp	.+254    	; 0x3f70 <main+0x170>
 	/*
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
       } else if (which == 0x81) {
-    3e70:	01 38       	cpi	r16, 0x81	; 129
-    3e72:	11 f4       	brne	.+4      	; 0x3e78 <main+0x78>
+    3e72:	01 38       	cpi	r16, 0x81	; 129
+    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(OPTIBOOT_MAJVER);
-    3e74:	84 e0       	ldi	r24, 0x04	; 4
-    3e76:	01 c0       	rjmp	.+2      	; 0x3e7a <main+0x7a>
+    3e76:	84 e0       	ldi	r24, 0x04	; 4
+    3e78:	01 c0       	rjmp	.+2      	; 0x3e7c <main+0x7c>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    3e78:	83 e0       	ldi	r24, 0x03	; 3
-    3e7a:	8d d0       	rcall	.+282    	; 0x3f96 <putch>
-    3e7c:	89 c0       	rjmp	.+274    	; 0x3f90 <main+0x190>
+    3e7a:	83 e0       	ldi	r24, 0x03	; 3
+    3e7c:	83 d0       	rcall	.+262    	; 0x3f84 <putch>
+    3e7e:	7f c0       	rjmp	.+254    	; 0x3f7e <main+0x17e>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    3e7e:	82 34       	cpi	r24, 0x42	; 66
-    3e80:	11 f4       	brne	.+4      	; 0x3e86 <main+0x86>
+    3e80:	82 34       	cpi	r24, 0x42	; 66
+    3e82:	11 f4       	brne	.+4      	; 0x3e88 <main+0x88>
       // SET DEVICE is ignored
       getNch(20);
-    3e82:	84 e1       	ldi	r24, 0x14	; 20
-    3e84:	03 c0       	rjmp	.+6      	; 0x3e8c <main+0x8c>
+    3e84:	84 e1       	ldi	r24, 0x14	; 20
+    3e86:	03 c0       	rjmp	.+6      	; 0x3e8e <main+0x8e>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e86:	85 34       	cpi	r24, 0x45	; 69
-    3e88:	19 f4       	brne	.+6      	; 0x3e90 <main+0x90>
+    3e88:	85 34       	cpi	r24, 0x45	; 69
+    3e8a:	19 f4       	brne	.+6      	; 0x3e92 <main+0x92>
       // SET DEVICE EXT is ignored
       getNch(5);
-    3e8a:	85 e0       	ldi	r24, 0x05	; 5
-    3e8c:	a6 d0       	rcall	.+332    	; 0x3fda <getNch>
-    3e8e:	80 c0       	rjmp	.+256    	; 0x3f90 <main+0x190>
+    3e8c:	85 e0       	ldi	r24, 0x05	; 5
+    3e8e:	9c d0       	rcall	.+312    	; 0x3fc8 <getNch>
+    3e90:	76 c0       	rjmp	.+236    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    3e90:	85 35       	cpi	r24, 0x55	; 85
-    3e92:	79 f4       	brne	.+30     	; 0x3eb2 <main+0xb2>
+    3e92:	85 35       	cpi	r24, 0x55	; 85
+    3e94:	79 f4       	brne	.+30     	; 0x3eb4 <main+0xb4>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e94:	88 d0       	rcall	.+272    	; 0x3fa6 <getch>
+    3e96:	7e d0       	rcall	.+252    	; 0x3f94 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e96:	e8 2e       	mov	r14, r24
-    3e98:	ff 24       	eor	r15, r15
-    3e9a:	85 d0       	rcall	.+266    	; 0x3fa6 <getch>
-    3e9c:	08 2f       	mov	r16, r24
-    3e9e:	10 e0       	ldi	r17, 0x00	; 0
-    3ea0:	10 2f       	mov	r17, r16
-    3ea2:	00 27       	eor	r16, r16
-    3ea4:	0e 29       	or	r16, r14
-    3ea6:	1f 29       	or	r17, r15
+    3e98:	e8 2e       	mov	r14, r24
+    3e9a:	ff 24       	eor	r15, r15
+    3e9c:	7b d0       	rcall	.+246    	; 0x3f94 <getch>
+    3e9e:	08 2f       	mov	r16, r24
+    3ea0:	10 e0       	ldi	r17, 0x00	; 0
+    3ea2:	10 2f       	mov	r17, r16
+    3ea4:	00 27       	eor	r16, r16
+    3ea6:	0e 29       	or	r16, r14
+    3ea8:	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
-    3ea8:	00 0f       	add	r16, r16
-    3eaa:	11 1f       	adc	r17, r17
+    3eaa:	00 0f       	add	r16, r16
+    3eac:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eac:	8e d0       	rcall	.+284    	; 0x3fca <verifySpace>
-    3eae:	68 01       	movw	r12, r16
-    3eb0:	6f c0       	rjmp	.+222    	; 0x3f90 <main+0x190>
+    3eae:	84 d0       	rcall	.+264    	; 0x3fb8 <verifySpace>
+    3eb0:	78 01       	movw	r14, r16
+    3eb2:	65 c0       	rjmp	.+202    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_UNIVERSAL) {
-    3eb2:	86 35       	cpi	r24, 0x56	; 86
-    3eb4:	21 f4       	brne	.+8      	; 0x3ebe <main+0xbe>
+    3eb4:	86 35       	cpi	r24, 0x56	; 86
+    3eb6:	21 f4       	brne	.+8      	; 0x3ec0 <main+0xc0>
       // UNIVERSAL command is ignored
       getNch(4);
-    3eb6:	84 e0       	ldi	r24, 0x04	; 4
-    3eb8:	90 d0       	rcall	.+288    	; 0x3fda <getNch>
+    3eb8:	84 e0       	ldi	r24, 0x04	; 4
+    3eba:	86 d0       	rcall	.+268    	; 0x3fc8 <getNch>
       putch(0x00);
-    3eba:	80 e0       	ldi	r24, 0x00	; 0
-    3ebc:	de cf       	rjmp	.-68     	; 0x3e7a <main+0x7a>
+    3ebc:	80 e0       	ldi	r24, 0x00	; 0
+    3ebe:	de cf       	rjmp	.-68     	; 0x3e7c <main+0x7c>
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    3ebe:	84 36       	cpi	r24, 0x64	; 100
-    3ec0:	09 f0       	breq	.+2      	; 0x3ec4 <main+0xc4>
-    3ec2:	40 c0       	rjmp	.+128    	; 0x3f44 <main+0x144>
+    3ec0:	84 36       	cpi	r24, 0x64	; 100
+    3ec2:	09 f0       	breq	.+2      	; 0x3ec6 <main+0xc6>
+    3ec4:	40 c0       	rjmp	.+128    	; 0x3f46 <main+0x146>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    3ec4:	70 d0       	rcall	.+224    	; 0x3fa6 <getch>
+    3ec6:	66 d0       	rcall	.+204    	; 0x3f94 <getch>
       length = getch();
-    3ec6:	6f d0       	rcall	.+222    	; 0x3fa6 <getch>
-    3ec8:	08 2f       	mov	r16, r24
+    3ec8:	65 d0       	rcall	.+202    	; 0x3f94 <getch>
+    3eca:	08 2f       	mov	r16, r24
       getch();
-    3eca:	6d d0       	rcall	.+218    	; 0x3fa6 <getch>
+    3ecc:	63 d0       	rcall	.+198    	; 0x3f94 <getch>
 
       // If we are in RWW section, immediately start page erase
       if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ecc:	80 e0       	ldi	r24, 0x00	; 0
-    3ece:	c8 16       	cp	r12, r24
-    3ed0:	88 e3       	ldi	r24, 0x38	; 56
-    3ed2:	d8 06       	cpc	r13, r24
-    3ed4:	18 f4       	brcc	.+6      	; 0x3edc <main+0xdc>
-    3ed6:	f6 01       	movw	r30, r12
-    3ed8:	b7 be       	out	0x37, r11	; 55
-    3eda:	e8 95       	spm
-    3edc:	c0 e0       	ldi	r28, 0x00	; 0
-    3ede:	d1 e0       	ldi	r29, 0x01	; 1
+    3ece:	80 e0       	ldi	r24, 0x00	; 0
+    3ed0:	e8 16       	cp	r14, r24
+    3ed2:	88 e3       	ldi	r24, 0x38	; 56
+    3ed4:	f8 06       	cpc	r15, r24
+    3ed6:	18 f4       	brcc	.+6      	; 0x3ede <main+0xde>
+    3ed8:	f7 01       	movw	r30, r14
+    3eda:	d7 be       	out	0x37, r13	; 55
+    3edc:	e8 95       	spm
+    3ede:	c0 e0       	ldi	r28, 0x00	; 0
+    3ee0:	d1 e0       	ldi	r29, 0x01	; 1
 
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee0:	62 d0       	rcall	.+196    	; 0x3fa6 <getch>
-    3ee2:	89 93       	st	Y+, r24
+    3ee2:	58 d0       	rcall	.+176    	; 0x3f94 <getch>
+    3ee4:	89 93       	st	Y+, r24
       while (--length);
-    3ee4:	0c 17       	cp	r16, r28
-    3ee6:	e1 f7       	brne	.-8      	; 0x3ee0 <main+0xe0>
+    3ee6:	0c 17       	cp	r16, r28
+    3ee8:	e1 f7       	brne	.-8      	; 0x3ee2 <main+0xe2>
 
       // If we are in NRWW section, page erase has to be delayed until now.
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ee8:	f0 e0       	ldi	r31, 0x00	; 0
-    3eea:	cf 16       	cp	r12, r31
-    3eec:	f8 e3       	ldi	r31, 0x38	; 56
-    3eee:	df 06       	cpc	r13, r31
-    3ef0:	18 f0       	brcs	.+6      	; 0x3ef8 <main+0xf8>
-    3ef2:	f6 01       	movw	r30, r12
-    3ef4:	b7 be       	out	0x37, r11	; 55
-    3ef6:	e8 95       	spm
+    3eea:	f0 e0       	ldi	r31, 0x00	; 0
+    3eec:	ef 16       	cp	r14, r31
+    3eee:	f8 e3       	ldi	r31, 0x38	; 56
+    3ef0:	ff 06       	cpc	r15, r31
+    3ef2:	18 f0       	brcs	.+6      	; 0x3efa <main+0xfa>
+    3ef4:	f7 01       	movw	r30, r14
+    3ef6:	d7 be       	out	0x37, r13	; 55
+    3ef8:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ef8:	68 d0       	rcall	.+208    	; 0x3fca <verifySpace>
+    3efa:	5e d0       	rcall	.+188    	; 0x3fb8 <verifySpace>
 
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3efa:	07 b6       	in	r0, 0x37	; 55
-    3efc:	00 fc       	sbrc	r0, 0
-    3efe:	fd cf       	rjmp	.-6      	; 0x3efa <main+0xfa>
-    3f00:	a6 01       	movw	r20, r12
-    3f02:	a0 e0       	ldi	r26, 0x00	; 0
-    3f04:	b1 e0       	ldi	r27, 0x01	; 1
+    3efc:	07 b6       	in	r0, 0x37	; 55
+    3efe:	00 fc       	sbrc	r0, 0
+    3f00:	fd cf       	rjmp	.-6      	; 0x3efc <main+0xfc>
+    3f02:	a7 01       	movw	r20, r14
+    3f04:	a0 e0       	ldi	r26, 0x00	; 0
+    3f06:	b1 e0       	ldi	r27, 0x01	; 1
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3f06:	2c 91       	ld	r18, X
-    3f08:	30 e0       	ldi	r19, 0x00	; 0
+    3f08:	2c 91       	ld	r18, X
+    3f0a:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3f0a:	11 96       	adiw	r26, 0x01	; 1
-    3f0c:	8c 91       	ld	r24, X
-    3f0e:	11 97       	sbiw	r26, 0x01	; 1
-    3f10:	90 e0       	ldi	r25, 0x00	; 0
-    3f12:	98 2f       	mov	r25, r24
-    3f14:	88 27       	eor	r24, r24
-    3f16:	82 2b       	or	r24, r18
-    3f18:	93 2b       	or	r25, r19
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    3f0c:	11 96       	adiw	r26, 0x01	; 1
+    3f0e:	8c 91       	ld	r24, X
+    3f10:	11 97       	sbiw	r26, 0x01	; 1
+    3f12:	90 e0       	ldi	r25, 0x00	; 0
+    3f14:	98 2f       	mov	r25, r24
+    3f16:	88 27       	eor	r24, r24
+    3f18:	82 2b       	or	r24, r18
+    3f1a:	93 2b       	or	r25, r19
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
 int main(void) {
-    3f1a:	12 96       	adiw	r26, 0x02	; 2
+    3f1c:	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);
-    3f1c:	fa 01       	movw	r30, r20
-    3f1e:	0c 01       	movw	r0, r24
-    3f20:	87 be       	out	0x37, r8	; 55
-    3f22:	e8 95       	spm
-    3f24:	11 24       	eor	r1, r1
+    3f1e:	fa 01       	movw	r30, r20
+    3f20:	0c 01       	movw	r0, r24
+    3f22:	a7 be       	out	0x37, r10	; 55
+    3f24:	e8 95       	spm
+    3f26:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f26:	4e 5f       	subi	r20, 0xFE	; 254
-    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f28:	4e 5f       	subi	r20, 0xFE	; 254
+    3f2a:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f2a:	f1 e0       	ldi	r31, 0x01	; 1
-    3f2c:	a0 38       	cpi	r26, 0x80	; 128
-    3f2e:	bf 07       	cpc	r27, r31
-    3f30:	51 f7       	brne	.-44     	; 0x3f06 <main+0x106>
+    3f2c:	f1 e0       	ldi	r31, 0x01	; 1
+    3f2e:	a0 38       	cpi	r26, 0x80	; 128
+    3f30:	bf 07       	cpc	r27, r31
+    3f32:	51 f7       	brne	.-44     	; 0x3f08 <main+0x108>
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f32:	f6 01       	movw	r30, r12
-    3f34:	a7 be       	out	0x37, r10	; 55
-    3f36:	e8 95       	spm
+    3f34:	f7 01       	movw	r30, r14
+    3f36:	c7 be       	out	0x37, r12	; 55
+    3f38:	e8 95       	spm
       boot_spm_busy_wait();
-    3f38:	07 b6       	in	r0, 0x37	; 55
-    3f3a:	00 fc       	sbrc	r0, 0
-    3f3c:	fd cf       	rjmp	.-6      	; 0x3f38 <main+0x138>
+    3f3a:	07 b6       	in	r0, 0x37	; 55
+    3f3c:	00 fc       	sbrc	r0, 0
+    3f3e:	fd cf       	rjmp	.-6      	; 0x3f3a <main+0x13a>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
-    3f42:	26 c0       	rjmp	.+76     	; 0x3f90 <main+0x190>
+    3f40:	b7 be       	out	0x37, r11	; 55
+    3f42:	e8 95       	spm
+    3f44:	1c c0       	rjmp	.+56     	; 0x3f7e <main+0x17e>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f44:	84 37       	cpi	r24, 0x74	; 116
-    3f46:	b1 f4       	brne	.+44     	; 0x3f74 <main+0x174>
+    3f46:	84 37       	cpi	r24, 0x74	; 116
+    3f48:	61 f4       	brne	.+24     	; 0x3f62 <main+0x162>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    3f48:	2e d0       	rcall	.+92     	; 0x3fa6 <getch>
+    3f4a:	24 d0       	rcall	.+72     	; 0x3f94 <getch>
       length = getch();
-    3f4a:	2d d0       	rcall	.+90     	; 0x3fa6 <getch>
-    3f4c:	f8 2e       	mov	r15, r24
+    3f4c:	23 d0       	rcall	.+70     	; 0x3f94 <getch>
+    3f4e:	08 2f       	mov	r16, r24
       getch();
-    3f4e:	2b d0       	rcall	.+86     	; 0x3fa6 <getch>
+    3f50:	21 d0       	rcall	.+66     	; 0x3f94 <getch>
 
       verifySpace();
-    3f50:	3c d0       	rcall	.+120    	; 0x3fca <verifySpace>
-    3f52:	f6 01       	movw	r30, r12
-    3f54:	ef 2c       	mov	r14, r15
-        putch(result);
-        address++;
-      }
-      while (--length);
+    3f52:	32 d0       	rcall	.+100    	; 0x3fb8 <verifySpace>
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-    3f56:	8f 01       	movw	r16, r30
-    3f58:	0f 5f       	subi	r16, 0xFF	; 255
-    3f5a:	1f 4f       	sbci	r17, 0xFF	; 255
-    3f5c:	84 91       	lpm	r24, Z+
-    3f5e:	1b d0       	rcall	.+54     	; 0x3f96 <putch>
-      while (--length);
-    3f60:	ea 94       	dec	r14
-    3f62:	f8 01       	movw	r30, r16
-    3f64:	c1 f7       	brne	.-16     	; 0x3f56 <main+0x156>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-/* main program starts here */
-int main(void) {
-    3f66:	08 94       	sec
-    3f68:	c1 1c       	adc	r12, r1
-    3f6a:	d1 1c       	adc	r13, r1
-    3f6c:	fa 94       	dec	r15
-    3f6e:	cf 0c       	add	r12, r15
-    3f70:	d1 1c       	adc	r13, r1
-    3f72:	0e c0       	rjmp	.+28     	; 0x3f90 <main+0x190>
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+    3f54:	f7 01       	movw	r30, r14
+    3f56:	85 91       	lpm	r24, Z+
+    3f58:	7f 01       	movw	r14, r30
+    3f5a:	14 d0       	rcall	.+40     	; 0x3f84 <putch>
+      } while (--length);
+    3f5c:	01 50       	subi	r16, 0x01	; 1
+    3f5e:	d1 f7       	brne	.-12     	; 0x3f54 <main+0x154>
+    3f60:	0e c0       	rjmp	.+28     	; 0x3f7e <main+0x17e>
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f74:	85 37       	cpi	r24, 0x75	; 117
-    3f76:	39 f4       	brne	.+14     	; 0x3f86 <main+0x186>
+    3f62:	85 37       	cpi	r24, 0x75	; 117
+    3f64:	39 f4       	brne	.+14     	; 0x3f74 <main+0x174>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f78:	28 d0       	rcall	.+80     	; 0x3fca <verifySpace>
+    3f66:	28 d0       	rcall	.+80     	; 0x3fb8 <verifySpace>
       putch(SIGNATURE_0);
-    3f7a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7c:	0c d0       	rcall	.+24     	; 0x3f96 <putch>
+    3f68:	8e e1       	ldi	r24, 0x1E	; 30
+    3f6a:	0c d0       	rcall	.+24     	; 0x3f84 <putch>
       putch(SIGNATURE_1);
-    3f7e:	84 e9       	ldi	r24, 0x94	; 148
-    3f80:	0a d0       	rcall	.+20     	; 0x3f96 <putch>
+    3f6c:	84 e9       	ldi	r24, 0x94	; 148
+    3f6e:	0a d0       	rcall	.+20     	; 0x3f84 <putch>
       putch(SIGNATURE_2);
-    3f82:	86 e0       	ldi	r24, 0x06	; 6
-    3f84:	7a cf       	rjmp	.-268    	; 0x3e7a <main+0x7a>
+    3f70:	86 e0       	ldi	r24, 0x06	; 6
+    3f72:	84 cf       	rjmp	.-248    	; 0x3e7c <main+0x7c>
     }
-    else if (ch == 'Q') {
-    3f86:	81 35       	cpi	r24, 0x51	; 81
-    3f88:	11 f4       	brne	.+4      	; 0x3f8e <main+0x18e>
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+    3f74:	81 35       	cpi	r24, 0x51	; 81
+    3f76:	11 f4       	brne	.+4      	; 0x3f7c <main+0x17c>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8a:	88 e0       	ldi	r24, 0x08	; 8
-    3f8c:	18 d0       	rcall	.+48     	; 0x3fbe <watchdogConfig>
+    3f78:	88 e0       	ldi	r24, 0x08	; 8
+    3f7a:	18 d0       	rcall	.+48     	; 0x3fac <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f8e:	1d d0       	rcall	.+58     	; 0x3fca <verifySpace>
+    3f7c:	1d d0       	rcall	.+58     	; 0x3fb8 <verifySpace>
     }
     putch(STK_OK);
-    3f90:	80 e1       	ldi	r24, 0x10	; 16
-    3f92:	01 d0       	rcall	.+2      	; 0x3f96 <putch>
-    3f94:	65 cf       	rjmp	.-310    	; 0x3e60 <main+0x60>
+    3f7e:	80 e1       	ldi	r24, 0x10	; 16
+    3f80:	01 d0       	rcall	.+2      	; 0x3f84 <putch>
+    3f82:	6e cf       	rjmp	.-292    	; 0x3e60 <main+0x60>
 
-00003f96 <putch>:
+00003f84 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f96:	98 2f       	mov	r25, r24
+    3f84:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-    3f98:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9c:	85 ff       	sbrs	r24, 5
-    3f9e:	fc cf       	rjmp	.-8      	; 0x3f98 <putch+0x2>
-  UDR0 = ch;
-    3fa0:	90 93 c6 00 	sts	0x00C6, r25
+  while (!(UART_SRA & _BV(UDRE0)));
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	85 ff       	sbrs	r24, 5
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <putch+0x2>
+  UART_UDR = ch;
+    3f8e:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa4:	08 95       	ret
+    3f92:	08 95       	ret
 
-00003fa6 <getch>:
+00003f94 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
-  while(!(UCSR0A & _BV(RXC0)))
-    3fa6:	80 91 c0 00 	lds	r24, 0x00C0
-    3faa:	87 ff       	sbrs	r24, 7
-    3fac:	fc cf       	rjmp	.-8      	; 0x3fa6 <getch>
+  while(!(UART_SRA & _BV(RXC0)))
+    3f94:	80 91 c0 00 	lds	r24, 0x00C0
+    3f98:	87 ff       	sbrs	r24, 7
+    3f9a:	fc cf       	rjmp	.-8      	; 0x3f94 <getch>
     ;
-  if (!(UCSR0A & _BV(FE0))) {
-    3fae:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb2:	84 fd       	sbrc	r24, 4
-    3fb4:	01 c0       	rjmp	.+2      	; 0x3fb8 <getch+0x12>
+  if (!(UART_SRA & _BV(FE0))) {
+    3f9c:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa0:	84 fd       	sbrc	r24, 4
+    3fa2:	01 c0       	rjmp	.+2      	; 0x3fa6 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb6:	a8 95       	wdr
+    3fa4:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
-  ch = UDR0;
-    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
+  ch = UART_UDR;
+    3fa6:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbc:	08 95       	ret
+    3faa:	08 95       	ret
 
-00003fbe <watchdogConfig>:
+00003fac <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fbe:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc2:	98 e1       	ldi	r25, 0x18	; 24
-    3fc4:	90 83       	st	Z, r25
+    3fac:	e0 e6       	ldi	r30, 0x60	; 96
+    3fae:	f0 e0       	ldi	r31, 0x00	; 0
+    3fb0:	98 e1       	ldi	r25, 0x18	; 24
+    3fb2:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc6:	80 83       	st	Z, r24
+    3fb4:	80 83       	st	Z, r24
 }
-    3fc8:	08 95       	ret
+    3fb6:	08 95       	ret
 
-00003fca <verifySpace>:
+00003fb8 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fca:	ed df       	rcall	.-38     	; 0x3fa6 <getch>
-    3fcc:	80 32       	cpi	r24, 0x20	; 32
-    3fce:	19 f0       	breq	.+6      	; 0x3fd6 <verifySpace+0xc>
+    3fb8:	ed df       	rcall	.-38     	; 0x3f94 <getch>
+    3fba:	80 32       	cpi	r24, 0x20	; 32
+    3fbc:	19 f0       	breq	.+6      	; 0x3fc4 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd0:	88 e0       	ldi	r24, 0x08	; 8
-    3fd2:	f5 df       	rcall	.-22     	; 0x3fbe <watchdogConfig>
-    3fd4:	ff cf       	rjmp	.-2      	; 0x3fd4 <verifySpace+0xa>
+    3fbe:	88 e0       	ldi	r24, 0x08	; 8
+    3fc0:	f5 df       	rcall	.-22     	; 0x3fac <watchdogConfig>
+    3fc2:	ff cf       	rjmp	.-2      	; 0x3fc2 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd6:	84 e1       	ldi	r24, 0x14	; 20
+    3fc4:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fd8:	de cf       	rjmp	.-68     	; 0x3f96 <putch>
+    3fc6:	de cf       	rjmp	.-68     	; 0x3f84 <putch>
 
-00003fda <getNch>:
+00003fc8 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fda:	1f 93       	push	r17
-    3fdc:	18 2f       	mov	r17, r24
+    3fc8:	1f 93       	push	r17
+    3fca:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fde:	e3 df       	rcall	.-58     	; 0x3fa6 <getch>
-    3fe0:	11 50       	subi	r17, 0x01	; 1
-    3fe2:	e9 f7       	brne	.-6      	; 0x3fde <getNch+0x4>
+    3fcc:	e3 df       	rcall	.-58     	; 0x3f94 <getch>
+    3fce:	11 50       	subi	r17, 0x01	; 1
+    3fd0:	e9 f7       	brne	.-6      	; 0x3fcc <getNch+0x4>
   verifySpace();
-    3fe4:	f2 df       	rcall	.-28     	; 0x3fca <verifySpace>
+    3fd2:	f2 df       	rcall	.-28     	; 0x3fb8 <verifySpace>
 }
-    3fe6:	1f 91       	pop	r17
-    3fe8:	08 95       	ret
+    3fd4:	1f 91       	pop	r17
+    3fd6:	08 95       	ret
 
-00003fea <appStart>:
+00003fd8 <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fea:	80 e0       	ldi	r24, 0x00	; 0
-    3fec:	e8 df       	rcall	.-48     	; 0x3fbe <watchdogConfig>
+    3fd8:	80 e0       	ldi	r24, 0x00	; 0
+    3fda:	e8 df       	rcall	.-48     	; 0x3fac <watchdogConfig>
   __asm__ __volatile__ (
-    3fee:	ee 27       	eor	r30, r30
-    3ff0:	ff 27       	eor	r31, r31
-    3ff2:	09 94       	ijmp
+    3fdc:	ee 27       	eor	r30, r30
+    3fde:	ff 27       	eor	r31, r31
+    3fe0:	09 94       	ijmp

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

@@ -1,35 +1,34 @@
-:103E0000112484B714BE81FFF0D085E08093810037
+:103E0000112484B714BE81FFE7D085E08093810040
 :103E100082E08093C00088E18093C10086E08093B7
-:103E2000C20088E08093C4008EE0C9D0259A86E065
+:103E2000C20088E08093C4008EE0C0D0259A86E06E
 :103E300028E13EEF91E0309385002093840096BB0B
-:103E4000B09BFECF1D9AA8958150A9F7CC24DD2404
-:103E500088248394B5E0AB2EA1E19A2EF3E0BF2E27
-:103E6000A2D0813461F49FD0082FAFD0023811F076
-:103E7000013811F484E001C083E08DD089C0823420
-:103E800011F484E103C0853419F485E0A6D080C024
-:103E9000853579F488D0E82EFF2485D0082F10E0EE
-:103EA000102F00270E291F29000F111F8ED0680127
-:103EB0006FC0863521F484E090D080E0DECF843678
-:103EC00009F040C070D06FD0082F6DD080E0C816C8
-:103ED00088E3D80618F4F601B7BEE895C0E0D1E053
-:103EE00062D089930C17E1F7F0E0CF16F8E3DF0614
-:103EF00018F0F601B7BEE89568D007B600FCFDCF14
-:103F0000A601A0E0B1E02C9130E011968C911197C0
-:103F100090E0982F8827822B932B1296FA010C01A0
-:103F200087BEE89511244E5F5F4FF1E0A038BF07D0
-:103F300051F7F601A7BEE89507B600FCFDCF97BE86
-:103F4000E89526C08437B1F42ED02DD0F82E2BD092
-:103F50003CD0F601EF2C8F010F5F1F4F84911BD0D7
-:103F6000EA94F801C1F70894C11CD11CFA94CF0C53
-:103F7000D11C0EC0853739F428D08EE10CD084E9ED
-:103F80000AD086E07ACF813511F488E018D01DD0B0
-:103F900080E101D065CF982F8091C00085FFFCCFD4
-:103FA0009093C60008958091C00087FFFCCF809158
-:103FB000C00084FD01C0A8958091C6000895E0E688
-:103FC000F0E098E1908380830895EDDF803219F06E
-:103FD00088E0F5DFFFCF84E1DECF1F93182FE3DF0A
-:103FE0001150E9F7F2DF1F91089580E0E8DFEE2736
-:043FF000FF2709940A
-:023FFE000404B9
+:103E4000B09BFECF1D9AA8958150A9F7EE24FF24C0
+:103E5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2E85
+:103E600099D0813469F496D0082FA6D0023809F48D
+:103E70007FC0013811F484E001C083E083D07FC0AB
+:103E8000823411F484E103C0853419F485E09CD0B8
+:103E900076C0853579F47ED0E82EFF247BD0082FBC
+:103EA00010E0102F00270E291F29000F111F84D0AA
+:103EB000780165C0863521F484E086D080E0DECFCD
+:103EC000843609F040C066D065D0082F63D080E00A
+:103ED000E81688E3F80618F4F701D7BEE895C0E0C5
+:103EE000D1E058D089930C17E1F7F0E0EF16F8E332
+:103EF000FF0618F0F701D7BEE8955ED007B600FCC4
+:103F0000FDCFA701A0E0B1E02C9130E011968C919B
+:103F1000119790E0982F8827822B932B1296FA0105
+:103F20000C01A7BEE89511244E5F5F4FF1E0A03869
+:103F3000BF0751F7F701C7BEE89507B600FCFDCFF4
+:103F4000B7BEE8951CC0843761F424D023D0082F75
+:103F500021D032D0F70185917F0114D00150D1F7E3
+:103F60000EC0853739F428D08EE10CD084E90AD010
+:103F700086E084CF813511F488E018D01DD080E12F
+:103F800001D06ECF982F8091C00085FFFCCF909319
+:103F9000C60008958091C00087FFFCCF8091C000CB
+:103FA00084FD01C0A8958091C6000895E0E6F0E088
+:103FB00098E1908380830895EDDF803219F088E0E6
+:103FC000F5DFFFCF84E1DECF1F93182FE3DF115021
+:103FD000E9F7F2DF1F91089580E0E8DFEE27FF2781
+:023FE000099442
+:023FFE000604B7
 :0400000300003E00BB
 :00000001FF

+ 230 - 247
optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst

@@ -3,34 +3,34 @@ optiboot_pro_8MHz.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001f4  00003e00  00003e00  00000054  2**1
+  0 .text         000001e2  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  00000248  2**0
+  1 .version      00000002  00003ffe  00003ffe  00000236  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  0000024a  2**0
+  2 .debug_aranges 00000028  00000000  00000000  00000238  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000005f  00000000  00000000  00000272  2**0
+  3 .debug_pubnames 0000005f  00000000  00000000  00000260  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000002a8  00000000  00000000  000002d1  2**0
+  4 .debug_info   0000027e  00000000  00000000  000002bf  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 00000178  00000000  00000000  00000579  2**0
+  5 .debug_abbrev 0000016b  00000000  00000000  0000053d  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000046b  00000000  00000000  000006f1  2**0
+  6 .debug_line   00000460  00000000  00000000  000006a8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000b5c  2**2
+  7 .debug_frame  00000080  00000000  00000000  00000b08  2**2
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000143  00000000  00000000  00000bdc  2**0
+  8 .debug_str    00000128  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    000002d8  00000000  00000000  00000d1f  2**0
+  9 .debug_loc    00000253  00000000  00000000  00000cb0  2**0
                   CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000078  00000000  00000000  00000ff7  2**0
+ 10 .debug_ranges 00000078  00000000  00000000  00000f03  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00003e00 <main>:
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
@@ -47,7 +47,7 @@ int main(void) {
     3e04:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e06:	81 ff       	sbrs	r24, 1
-    3e08:	f0 d0       	rcall	.+480    	; 0x3fea <appStart>
+    3e08:	e7 d0       	rcall	.+462    	; 0x3fd8 <appStart>
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
@@ -59,16 +59,16 @@ int main(void) {
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
-  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UART_SRA = _BV(U2X0); //Double speed mode USART0
     3e10:	82 e0       	ldi	r24, 0x02	; 2
     3e12:	80 93 c0 00 	sts	0x00C0, r24
-  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
     3e16:	88 e1       	ldi	r24, 0x18	; 24
     3e18:	80 93 c1 00 	sts	0x00C1, r24
-  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
     3e1c:	86 e0       	ldi	r24, 0x06	; 6
     3e1e:	80 93 c2 00 	sts	0x00C2, r24
-  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
     3e22:	88 e0       	ldi	r24, 0x08	; 8
     3e24:	80 93 c4 00 	sts	0x00C4, r24
 #endif
@@ -77,7 +77,7 @@ int main(void) {
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_1S);
     3e28:	8e e0       	ldi	r24, 0x0E	; 14
-    3e2a:	c9 d0       	rcall	.+402    	; 0x3fbe <watchdogConfig>
+    3e2a:	c0 d0       	rcall	.+384    	; 0x3fac <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -126,30 +126,30 @@ void watchdogReset() {
   } while (--count);
     3e48:	81 50       	subi	r24, 0x01	; 1
     3e4a:	a9 f7       	brne	.-22     	; 0x3e36 <main+0x36>
-    3e4c:	cc 24       	eor	r12, r12
-    3e4e:	dd 24       	eor	r13, r13
+    3e4c:	ee 24       	eor	r14, r14
+    3e4e:	ff 24       	eor	r15, r15
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e50:	88 24       	eor	r8, r8
-    3e52:	83 94       	inc	r8
+    3e50:	aa 24       	eor	r10, r10
+    3e52:	a3 94       	inc	r10
         addrPtr += 2;
       } while (--ch);
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e54:	b5 e0       	ldi	r27, 0x05	; 5
-    3e56:	ab 2e       	mov	r10, r27
+    3e56:	cb 2e       	mov	r12, r27
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e58:	a1 e1       	ldi	r26, 0x11	; 17
-    3e5a:	9a 2e       	mov	r9, r26
+    3e5a:	ba 2e       	mov	r11, r26
       do *bufPtr++ = getch();
       while (--length);
 
@@ -157,442 +157,425 @@ void watchdogReset() {
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3e5c:	f3 e0       	ldi	r31, 0x03	; 3
-    3e5e:	bf 2e       	mov	r11, r31
+    3e5e:	df 2e       	mov	r13, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e60:	a2 d0       	rcall	.+324    	; 0x3fa6 <getch>
+    3e60:	99 d0       	rcall	.+306    	; 0x3f94 <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e62:	81 34       	cpi	r24, 0x41	; 65
-    3e64:	61 f4       	brne	.+24     	; 0x3e7e <main+0x7e>
+    3e64:	69 f4       	brne	.+26     	; 0x3e80 <main+0x80>
       unsigned char which = getch();
-    3e66:	9f d0       	rcall	.+318    	; 0x3fa6 <getch>
+    3e66:	96 d0       	rcall	.+300    	; 0x3f94 <getch>
     3e68:	08 2f       	mov	r16, r24
       verifySpace();
-    3e6a:	af d0       	rcall	.+350    	; 0x3fca <verifySpace>
+    3e6a:	a6 d0       	rcall	.+332    	; 0x3fb8 <verifySpace>
       if (which == 0x82) {
     3e6c:	02 38       	cpi	r16, 0x82	; 130
-    3e6e:	11 f0       	breq	.+4      	; 0x3e74 <main+0x74>
+    3e6e:	09 f4       	brne	.+2      	; 0x3e72 <main+0x72>
+    3e70:	7f c0       	rjmp	.+254    	; 0x3f70 <main+0x170>
 	/*
 	 * Send optiboot version as "minor SW version"
 	 */
 	putch(OPTIBOOT_MINVER);
       } else if (which == 0x81) {
-    3e70:	01 38       	cpi	r16, 0x81	; 129
-    3e72:	11 f4       	brne	.+4      	; 0x3e78 <main+0x78>
+    3e72:	01 38       	cpi	r16, 0x81	; 129
+    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
 	  putch(OPTIBOOT_MAJVER);
-    3e74:	84 e0       	ldi	r24, 0x04	; 4
-    3e76:	01 c0       	rjmp	.+2      	; 0x3e7a <main+0x7a>
+    3e76:	84 e0       	ldi	r24, 0x04	; 4
+    3e78:	01 c0       	rjmp	.+2      	; 0x3e7c <main+0x7c>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    3e78:	83 e0       	ldi	r24, 0x03	; 3
-    3e7a:	8d d0       	rcall	.+282    	; 0x3f96 <putch>
-    3e7c:	89 c0       	rjmp	.+274    	; 0x3f90 <main+0x190>
+    3e7a:	83 e0       	ldi	r24, 0x03	; 3
+    3e7c:	83 d0       	rcall	.+262    	; 0x3f84 <putch>
+    3e7e:	7f c0       	rjmp	.+254    	; 0x3f7e <main+0x17e>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    3e7e:	82 34       	cpi	r24, 0x42	; 66
-    3e80:	11 f4       	brne	.+4      	; 0x3e86 <main+0x86>
+    3e80:	82 34       	cpi	r24, 0x42	; 66
+    3e82:	11 f4       	brne	.+4      	; 0x3e88 <main+0x88>
       // SET DEVICE is ignored
       getNch(20);
-    3e82:	84 e1       	ldi	r24, 0x14	; 20
-    3e84:	03 c0       	rjmp	.+6      	; 0x3e8c <main+0x8c>
+    3e84:	84 e1       	ldi	r24, 0x14	; 20
+    3e86:	03 c0       	rjmp	.+6      	; 0x3e8e <main+0x8e>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e86:	85 34       	cpi	r24, 0x45	; 69
-    3e88:	19 f4       	brne	.+6      	; 0x3e90 <main+0x90>
+    3e88:	85 34       	cpi	r24, 0x45	; 69
+    3e8a:	19 f4       	brne	.+6      	; 0x3e92 <main+0x92>
       // SET DEVICE EXT is ignored
       getNch(5);
-    3e8a:	85 e0       	ldi	r24, 0x05	; 5
-    3e8c:	a6 d0       	rcall	.+332    	; 0x3fda <getNch>
-    3e8e:	80 c0       	rjmp	.+256    	; 0x3f90 <main+0x190>
+    3e8c:	85 e0       	ldi	r24, 0x05	; 5
+    3e8e:	9c d0       	rcall	.+312    	; 0x3fc8 <getNch>
+    3e90:	76 c0       	rjmp	.+236    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    3e90:	85 35       	cpi	r24, 0x55	; 85
-    3e92:	79 f4       	brne	.+30     	; 0x3eb2 <main+0xb2>
+    3e92:	85 35       	cpi	r24, 0x55	; 85
+    3e94:	79 f4       	brne	.+30     	; 0x3eb4 <main+0xb4>
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e94:	88 d0       	rcall	.+272    	; 0x3fa6 <getch>
+    3e96:	7e d0       	rcall	.+252    	; 0x3f94 <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e96:	e8 2e       	mov	r14, r24
-    3e98:	ff 24       	eor	r15, r15
-    3e9a:	85 d0       	rcall	.+266    	; 0x3fa6 <getch>
-    3e9c:	08 2f       	mov	r16, r24
-    3e9e:	10 e0       	ldi	r17, 0x00	; 0
-    3ea0:	10 2f       	mov	r17, r16
-    3ea2:	00 27       	eor	r16, r16
-    3ea4:	0e 29       	or	r16, r14
-    3ea6:	1f 29       	or	r17, r15
+    3e98:	e8 2e       	mov	r14, r24
+    3e9a:	ff 24       	eor	r15, r15
+    3e9c:	7b d0       	rcall	.+246    	; 0x3f94 <getch>
+    3e9e:	08 2f       	mov	r16, r24
+    3ea0:	10 e0       	ldi	r17, 0x00	; 0
+    3ea2:	10 2f       	mov	r17, r16
+    3ea4:	00 27       	eor	r16, r16
+    3ea6:	0e 29       	or	r16, r14
+    3ea8:	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
-    3ea8:	00 0f       	add	r16, r16
-    3eaa:	11 1f       	adc	r17, r17
+    3eaa:	00 0f       	add	r16, r16
+    3eac:	11 1f       	adc	r17, r17
       address = newAddress;
       verifySpace();
-    3eac:	8e d0       	rcall	.+284    	; 0x3fca <verifySpace>
-    3eae:	68 01       	movw	r12, r16
-    3eb0:	6f c0       	rjmp	.+222    	; 0x3f90 <main+0x190>
+    3eae:	84 d0       	rcall	.+264    	; 0x3fb8 <verifySpace>
+    3eb0:	78 01       	movw	r14, r16
+    3eb2:	65 c0       	rjmp	.+202    	; 0x3f7e <main+0x17e>
     }
     else if(ch == STK_UNIVERSAL) {
-    3eb2:	86 35       	cpi	r24, 0x56	; 86
-    3eb4:	21 f4       	brne	.+8      	; 0x3ebe <main+0xbe>
+    3eb4:	86 35       	cpi	r24, 0x56	; 86
+    3eb6:	21 f4       	brne	.+8      	; 0x3ec0 <main+0xc0>
       // UNIVERSAL command is ignored
       getNch(4);
-    3eb6:	84 e0       	ldi	r24, 0x04	; 4
-    3eb8:	90 d0       	rcall	.+288    	; 0x3fda <getNch>
+    3eb8:	84 e0       	ldi	r24, 0x04	; 4
+    3eba:	86 d0       	rcall	.+268    	; 0x3fc8 <getNch>
       putch(0x00);
-    3eba:	80 e0       	ldi	r24, 0x00	; 0
-    3ebc:	de cf       	rjmp	.-68     	; 0x3e7a <main+0x7a>
+    3ebc:	80 e0       	ldi	r24, 0x00	; 0
+    3ebe:	de cf       	rjmp	.-68     	; 0x3e7c <main+0x7c>
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    3ebe:	84 36       	cpi	r24, 0x64	; 100
-    3ec0:	09 f0       	breq	.+2      	; 0x3ec4 <main+0xc4>
-    3ec2:	40 c0       	rjmp	.+128    	; 0x3f44 <main+0x144>
+    3ec0:	84 36       	cpi	r24, 0x64	; 100
+    3ec2:	09 f0       	breq	.+2      	; 0x3ec6 <main+0xc6>
+    3ec4:	40 c0       	rjmp	.+128    	; 0x3f46 <main+0x146>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getch();			/* getlen() */
-    3ec4:	70 d0       	rcall	.+224    	; 0x3fa6 <getch>
+    3ec6:	66 d0       	rcall	.+204    	; 0x3f94 <getch>
       length = getch();
-    3ec6:	6f d0       	rcall	.+222    	; 0x3fa6 <getch>
-    3ec8:	08 2f       	mov	r16, r24
+    3ec8:	65 d0       	rcall	.+202    	; 0x3f94 <getch>
+    3eca:	08 2f       	mov	r16, r24
       getch();
-    3eca:	6d d0       	rcall	.+218    	; 0x3fa6 <getch>
+    3ecc:	63 d0       	rcall	.+198    	; 0x3f94 <getch>
 
       // If we are in RWW section, immediately start page erase
       if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ecc:	80 e0       	ldi	r24, 0x00	; 0
-    3ece:	c8 16       	cp	r12, r24
-    3ed0:	88 e3       	ldi	r24, 0x38	; 56
-    3ed2:	d8 06       	cpc	r13, r24
-    3ed4:	18 f4       	brcc	.+6      	; 0x3edc <main+0xdc>
-    3ed6:	f6 01       	movw	r30, r12
-    3ed8:	b7 be       	out	0x37, r11	; 55
-    3eda:	e8 95       	spm
-    3edc:	c0 e0       	ldi	r28, 0x00	; 0
-    3ede:	d1 e0       	ldi	r29, 0x01	; 1
+    3ece:	80 e0       	ldi	r24, 0x00	; 0
+    3ed0:	e8 16       	cp	r14, r24
+    3ed2:	88 e3       	ldi	r24, 0x38	; 56
+    3ed4:	f8 06       	cpc	r15, r24
+    3ed6:	18 f4       	brcc	.+6      	; 0x3ede <main+0xde>
+    3ed8:	f7 01       	movw	r30, r14
+    3eda:	d7 be       	out	0x37, r13	; 55
+    3edc:	e8 95       	spm
+    3ede:	c0 e0       	ldi	r28, 0x00	; 0
+    3ee0:	d1 e0       	ldi	r29, 0x01	; 1
 
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ee0:	62 d0       	rcall	.+196    	; 0x3fa6 <getch>
-    3ee2:	89 93       	st	Y+, r24
+    3ee2:	58 d0       	rcall	.+176    	; 0x3f94 <getch>
+    3ee4:	89 93       	st	Y+, r24
       while (--length);
-    3ee4:	0c 17       	cp	r16, r28
-    3ee6:	e1 f7       	brne	.-8      	; 0x3ee0 <main+0xe0>
+    3ee6:	0c 17       	cp	r16, r28
+    3ee8:	e1 f7       	brne	.-8      	; 0x3ee2 <main+0xe2>
 
       // If we are in NRWW section, page erase has to be delayed until now.
       // Todo: Take RAMPZ into account
       if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    3ee8:	f0 e0       	ldi	r31, 0x00	; 0
-    3eea:	cf 16       	cp	r12, r31
-    3eec:	f8 e3       	ldi	r31, 0x38	; 56
-    3eee:	df 06       	cpc	r13, r31
-    3ef0:	18 f0       	brcs	.+6      	; 0x3ef8 <main+0xf8>
-    3ef2:	f6 01       	movw	r30, r12
-    3ef4:	b7 be       	out	0x37, r11	; 55
-    3ef6:	e8 95       	spm
+    3eea:	f0 e0       	ldi	r31, 0x00	; 0
+    3eec:	ef 16       	cp	r14, r31
+    3eee:	f8 e3       	ldi	r31, 0x38	; 56
+    3ef0:	ff 06       	cpc	r15, r31
+    3ef2:	18 f0       	brcs	.+6      	; 0x3efa <main+0xfa>
+    3ef4:	f7 01       	movw	r30, r14
+    3ef6:	d7 be       	out	0x37, r13	; 55
+    3ef8:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ef8:	68 d0       	rcall	.+208    	; 0x3fca <verifySpace>
+    3efa:	5e d0       	rcall	.+188    	; 0x3fb8 <verifySpace>
 
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3efa:	07 b6       	in	r0, 0x37	; 55
-    3efc:	00 fc       	sbrc	r0, 0
-    3efe:	fd cf       	rjmp	.-6      	; 0x3efa <main+0xfa>
-    3f00:	a6 01       	movw	r20, r12
-    3f02:	a0 e0       	ldi	r26, 0x00	; 0
-    3f04:	b1 e0       	ldi	r27, 0x01	; 1
+    3efc:	07 b6       	in	r0, 0x37	; 55
+    3efe:	00 fc       	sbrc	r0, 0
+    3f00:	fd cf       	rjmp	.-6      	; 0x3efc <main+0xfc>
+    3f02:	a7 01       	movw	r20, r14
+    3f04:	a0 e0       	ldi	r26, 0x00	; 0
+    3f06:	b1 e0       	ldi	r27, 0x01	; 1
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3f06:	2c 91       	ld	r18, X
-    3f08:	30 e0       	ldi	r19, 0x00	; 0
+    3f08:	2c 91       	ld	r18, X
+    3f0a:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3f0a:	11 96       	adiw	r26, 0x01	; 1
-    3f0c:	8c 91       	ld	r24, X
-    3f0e:	11 97       	sbiw	r26, 0x01	; 1
-    3f10:	90 e0       	ldi	r25, 0x00	; 0
-    3f12:	98 2f       	mov	r25, r24
-    3f14:	88 27       	eor	r24, r24
-    3f16:	82 2b       	or	r24, r18
-    3f18:	93 2b       	or	r25, r19
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+    3f0c:	11 96       	adiw	r26, 0x01	; 1
+    3f0e:	8c 91       	ld	r24, X
+    3f10:	11 97       	sbiw	r26, 0x01	; 1
+    3f12:	90 e0       	ldi	r25, 0x00	; 0
+    3f14:	98 2f       	mov	r25, r24
+    3f16:	88 27       	eor	r24, r24
+    3f18:	82 2b       	or	r24, r18
+    3f1a:	93 2b       	or	r25, r19
+# define UART_SRL UBRR3L
+# define UART_UDR UDR3
 #endif
 
 /* main program starts here */
 int main(void) {
-    3f1a:	12 96       	adiw	r26, 0x02	; 2
+    3f1c:	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);
-    3f1c:	fa 01       	movw	r30, r20
-    3f1e:	0c 01       	movw	r0, r24
-    3f20:	87 be       	out	0x37, r8	; 55
-    3f22:	e8 95       	spm
-    3f24:	11 24       	eor	r1, r1
+    3f1e:	fa 01       	movw	r30, r20
+    3f20:	0c 01       	movw	r0, r24
+    3f22:	a7 be       	out	0x37, r10	; 55
+    3f24:	e8 95       	spm
+    3f26:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f26:	4e 5f       	subi	r20, 0xFE	; 254
-    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f28:	4e 5f       	subi	r20, 0xFE	; 254
+    3f2a:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f2a:	f1 e0       	ldi	r31, 0x01	; 1
-    3f2c:	a0 38       	cpi	r26, 0x80	; 128
-    3f2e:	bf 07       	cpc	r27, r31
-    3f30:	51 f7       	brne	.-44     	; 0x3f06 <main+0x106>
+    3f2c:	f1 e0       	ldi	r31, 0x01	; 1
+    3f2e:	a0 38       	cpi	r26, 0x80	; 128
+    3f30:	bf 07       	cpc	r27, r31
+    3f32:	51 f7       	brne	.-44     	; 0x3f08 <main+0x108>
 
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f32:	f6 01       	movw	r30, r12
-    3f34:	a7 be       	out	0x37, r10	; 55
-    3f36:	e8 95       	spm
+    3f34:	f7 01       	movw	r30, r14
+    3f36:	c7 be       	out	0x37, r12	; 55
+    3f38:	e8 95       	spm
       boot_spm_busy_wait();
-    3f38:	07 b6       	in	r0, 0x37	; 55
-    3f3a:	00 fc       	sbrc	r0, 0
-    3f3c:	fd cf       	rjmp	.-6      	; 0x3f38 <main+0x138>
+    3f3a:	07 b6       	in	r0, 0x37	; 55
+    3f3c:	00 fc       	sbrc	r0, 0
+    3f3e:	fd cf       	rjmp	.-6      	; 0x3f3a <main+0x13a>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f3e:	97 be       	out	0x37, r9	; 55
-    3f40:	e8 95       	spm
-    3f42:	26 c0       	rjmp	.+76     	; 0x3f90 <main+0x190>
+    3f40:	b7 be       	out	0x37, r11	; 55
+    3f42:	e8 95       	spm
+    3f44:	1c c0       	rjmp	.+56     	; 0x3f7e <main+0x17e>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f44:	84 37       	cpi	r24, 0x74	; 116
-    3f46:	b1 f4       	brne	.+44     	; 0x3f74 <main+0x174>
+    3f46:	84 37       	cpi	r24, 0x74	; 116
+    3f48:	61 f4       	brne	.+24     	; 0x3f62 <main+0x162>
       // READ PAGE - we only read flash
       getch();			/* getlen() */
-    3f48:	2e d0       	rcall	.+92     	; 0x3fa6 <getch>
+    3f4a:	24 d0       	rcall	.+72     	; 0x3f94 <getch>
       length = getch();
-    3f4a:	2d d0       	rcall	.+90     	; 0x3fa6 <getch>
-    3f4c:	f8 2e       	mov	r15, r24
+    3f4c:	23 d0       	rcall	.+70     	; 0x3f94 <getch>
+    3f4e:	08 2f       	mov	r16, r24
       getch();
-    3f4e:	2b d0       	rcall	.+86     	; 0x3fa6 <getch>
+    3f50:	21 d0       	rcall	.+66     	; 0x3f94 <getch>
 
       verifySpace();
-    3f50:	3c d0       	rcall	.+120    	; 0x3fca <verifySpace>
-    3f52:	f6 01       	movw	r30, r12
-    3f54:	ef 2c       	mov	r14, r15
-        putch(result);
-        address++;
-      }
-      while (--length);
+    3f52:	32 d0       	rcall	.+100    	; 0x3fb8 <verifySpace>
+        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #else
-      do putch(pgm_read_byte_near(address++));
-    3f56:	8f 01       	movw	r16, r30
-    3f58:	0f 5f       	subi	r16, 0xFF	; 255
-    3f5a:	1f 4f       	sbci	r17, 0xFF	; 255
-    3f5c:	84 91       	lpm	r24, Z+
-    3f5e:	1b d0       	rcall	.+54     	; 0x3f96 <putch>
-      while (--length);
-    3f60:	ea 94       	dec	r14
-    3f62:	f8 01       	movw	r30, r16
-    3f64:	c1 f7       	brne	.-16     	; 0x3f56 <main+0x156>
-#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-/* main program starts here */
-int main(void) {
-    3f66:	08 94       	sec
-    3f68:	c1 1c       	adc	r12, r1
-    3f6a:	d1 1c       	adc	r13, r1
-    3f6c:	fa 94       	dec	r15
-    3f6e:	cf 0c       	add	r12, r15
-    3f70:	d1 1c       	adc	r13, r1
-    3f72:	0e c0       	rjmp	.+28     	; 0x3f90 <main+0x190>
-#endif
+        // read a Flash byte and increment the address
+        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
 #endif
+        putch(ch);
+    3f54:	f7 01       	movw	r30, r14
+    3f56:	85 91       	lpm	r24, Z+
+    3f58:	7f 01       	movw	r14, r30
+    3f5a:	14 d0       	rcall	.+40     	; 0x3f84 <putch>
+      } while (--length);
+    3f5c:	01 50       	subi	r16, 0x01	; 1
+    3f5e:	d1 f7       	brne	.-12     	; 0x3f54 <main+0x154>
+    3f60:	0e c0       	rjmp	.+28     	; 0x3f7e <main+0x17e>
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f74:	85 37       	cpi	r24, 0x75	; 117
-    3f76:	39 f4       	brne	.+14     	; 0x3f86 <main+0x186>
+    3f62:	85 37       	cpi	r24, 0x75	; 117
+    3f64:	39 f4       	brne	.+14     	; 0x3f74 <main+0x174>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f78:	28 d0       	rcall	.+80     	; 0x3fca <verifySpace>
+    3f66:	28 d0       	rcall	.+80     	; 0x3fb8 <verifySpace>
       putch(SIGNATURE_0);
-    3f7a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f7c:	0c d0       	rcall	.+24     	; 0x3f96 <putch>
+    3f68:	8e e1       	ldi	r24, 0x1E	; 30
+    3f6a:	0c d0       	rcall	.+24     	; 0x3f84 <putch>
       putch(SIGNATURE_1);
-    3f7e:	84 e9       	ldi	r24, 0x94	; 148
-    3f80:	0a d0       	rcall	.+20     	; 0x3f96 <putch>
+    3f6c:	84 e9       	ldi	r24, 0x94	; 148
+    3f6e:	0a d0       	rcall	.+20     	; 0x3f84 <putch>
       putch(SIGNATURE_2);
-    3f82:	86 e0       	ldi	r24, 0x06	; 6
-    3f84:	7a cf       	rjmp	.-268    	; 0x3e7a <main+0x7a>
+    3f70:	86 e0       	ldi	r24, 0x06	; 6
+    3f72:	84 cf       	rjmp	.-248    	; 0x3e7c <main+0x7c>
     }
-    else if (ch == 'Q') {
-    3f86:	81 35       	cpi	r24, 0x51	; 81
-    3f88:	11 f4       	brne	.+4      	; 0x3f8e <main+0x18e>
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+    3f74:	81 35       	cpi	r24, 0x51	; 81
+    3f76:	11 f4       	brne	.+4      	; 0x3f7c <main+0x17c>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f8a:	88 e0       	ldi	r24, 0x08	; 8
-    3f8c:	18 d0       	rcall	.+48     	; 0x3fbe <watchdogConfig>
+    3f78:	88 e0       	ldi	r24, 0x08	; 8
+    3f7a:	18 d0       	rcall	.+48     	; 0x3fac <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f8e:	1d d0       	rcall	.+58     	; 0x3fca <verifySpace>
+    3f7c:	1d d0       	rcall	.+58     	; 0x3fb8 <verifySpace>
     }
     putch(STK_OK);
-    3f90:	80 e1       	ldi	r24, 0x10	; 16
-    3f92:	01 d0       	rcall	.+2      	; 0x3f96 <putch>
-    3f94:	65 cf       	rjmp	.-310    	; 0x3e60 <main+0x60>
+    3f7e:	80 e1       	ldi	r24, 0x10	; 16
+    3f80:	01 d0       	rcall	.+2      	; 0x3f84 <putch>
+    3f82:	6e cf       	rjmp	.-292    	; 0x3e60 <main+0x60>
 
-00003f96 <putch>:
+00003f84 <putch>:
   }
 }
 
 void putch(char ch) {
-    3f96:	98 2f       	mov	r25, r24
+    3f84:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
-  while (!(UCSR0A & _BV(UDRE0)));
-    3f98:	80 91 c0 00 	lds	r24, 0x00C0
-    3f9c:	85 ff       	sbrs	r24, 5
-    3f9e:	fc cf       	rjmp	.-8      	; 0x3f98 <putch+0x2>
-  UDR0 = ch;
-    3fa0:	90 93 c6 00 	sts	0x00C6, r25
+  while (!(UART_SRA & _BV(UDRE0)));
+    3f86:	80 91 c0 00 	lds	r24, 0x00C0
+    3f8a:	85 ff       	sbrs	r24, 5
+    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <putch+0x2>
+  UART_UDR = ch;
+    3f8e:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3fa4:	08 95       	ret
+    3f92:	08 95       	ret
 
-00003fa6 <getch>:
+00003f94 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
-  while(!(UCSR0A & _BV(RXC0)))
-    3fa6:	80 91 c0 00 	lds	r24, 0x00C0
-    3faa:	87 ff       	sbrs	r24, 7
-    3fac:	fc cf       	rjmp	.-8      	; 0x3fa6 <getch>
+  while(!(UART_SRA & _BV(RXC0)))
+    3f94:	80 91 c0 00 	lds	r24, 0x00C0
+    3f98:	87 ff       	sbrs	r24, 7
+    3f9a:	fc cf       	rjmp	.-8      	; 0x3f94 <getch>
     ;
-  if (!(UCSR0A & _BV(FE0))) {
-    3fae:	80 91 c0 00 	lds	r24, 0x00C0
-    3fb2:	84 fd       	sbrc	r24, 4
-    3fb4:	01 c0       	rjmp	.+2      	; 0x3fb8 <getch+0x12>
+  if (!(UART_SRA & _BV(FE0))) {
+    3f9c:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa0:	84 fd       	sbrc	r24, 4
+    3fa2:	01 c0       	rjmp	.+2      	; 0x3fa6 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3fb6:	a8 95       	wdr
+    3fa4:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
   
-  ch = UDR0;
-    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
+  ch = UART_UDR;
+    3fa6:	80 91 c6 00 	lds	r24, 0x00C6
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3fbc:	08 95       	ret
+    3faa:	08 95       	ret
 
-00003fbe <watchdogConfig>:
+00003fac <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fbe:	e0 e6       	ldi	r30, 0x60	; 96
-    3fc0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fc2:	98 e1       	ldi	r25, 0x18	; 24
-    3fc4:	90 83       	st	Z, r25
+    3fac:	e0 e6       	ldi	r30, 0x60	; 96
+    3fae:	f0 e0       	ldi	r31, 0x00	; 0
+    3fb0:	98 e1       	ldi	r25, 0x18	; 24
+    3fb2:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fc6:	80 83       	st	Z, r24
+    3fb4:	80 83       	st	Z, r24
 }
-    3fc8:	08 95       	ret
+    3fb6:	08 95       	ret
 
-00003fca <verifySpace>:
+00003fb8 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3fca:	ed df       	rcall	.-38     	; 0x3fa6 <getch>
-    3fcc:	80 32       	cpi	r24, 0x20	; 32
-    3fce:	19 f0       	breq	.+6      	; 0x3fd6 <verifySpace+0xc>
+    3fb8:	ed df       	rcall	.-38     	; 0x3f94 <getch>
+    3fba:	80 32       	cpi	r24, 0x20	; 32
+    3fbc:	19 f0       	breq	.+6      	; 0x3fc4 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fd0:	88 e0       	ldi	r24, 0x08	; 8
-    3fd2:	f5 df       	rcall	.-22     	; 0x3fbe <watchdogConfig>
-    3fd4:	ff cf       	rjmp	.-2      	; 0x3fd4 <verifySpace+0xa>
+    3fbe:	88 e0       	ldi	r24, 0x08	; 8
+    3fc0:	f5 df       	rcall	.-22     	; 0x3fac <watchdogConfig>
+    3fc2:	ff cf       	rjmp	.-2      	; 0x3fc2 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fd6:	84 e1       	ldi	r24, 0x14	; 20
+    3fc4:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fd8:	de cf       	rjmp	.-68     	; 0x3f96 <putch>
+    3fc6:	de cf       	rjmp	.-68     	; 0x3f84 <putch>
 
-00003fda <getNch>:
+00003fc8 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fda:	1f 93       	push	r17
-    3fdc:	18 2f       	mov	r17, r24
+    3fc8:	1f 93       	push	r17
+    3fca:	18 2f       	mov	r17, r24
   do getch(); while (--count);
-    3fde:	e3 df       	rcall	.-58     	; 0x3fa6 <getch>
-    3fe0:	11 50       	subi	r17, 0x01	; 1
-    3fe2:	e9 f7       	brne	.-6      	; 0x3fde <getNch+0x4>
+    3fcc:	e3 df       	rcall	.-58     	; 0x3f94 <getch>
+    3fce:	11 50       	subi	r17, 0x01	; 1
+    3fd0:	e9 f7       	brne	.-6      	; 0x3fcc <getNch+0x4>
   verifySpace();
-    3fe4:	f2 df       	rcall	.-28     	; 0x3fca <verifySpace>
+    3fd2:	f2 df       	rcall	.-28     	; 0x3fb8 <verifySpace>
 }
-    3fe6:	1f 91       	pop	r17
-    3fe8:	08 95       	ret
+    3fd4:	1f 91       	pop	r17
+    3fd6:	08 95       	ret
 
-00003fea <appStart>:
+00003fd8 <appStart>:
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = x;
 }
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fea:	80 e0       	ldi	r24, 0x00	; 0
-    3fec:	e8 df       	rcall	.-48     	; 0x3fbe <watchdogConfig>
+    3fd8:	80 e0       	ldi	r24, 0x00	; 0
+    3fda:	e8 df       	rcall	.-48     	; 0x3fac <watchdogConfig>
   __asm__ __volatile__ (
-    3fee:	ee 27       	eor	r30, r30
-    3ff0:	ff 27       	eor	r31, r31
-    3ff2:	09 94       	ijmp
+    3fdc:	ee 27       	eor	r30, r30
+    3fde:	ff 27       	eor	r31, r31
+    3fe0:	09 94       	ijmp