Browse Source

Handle writing to NRWW locations correctly.

cathedrow 15 years ago
parent
commit
c49b9cc7b3
24 changed files with 2138 additions and 1920 deletions
  1. 10 0
      optiboot/bootloaders/optiboot/Makefile
  2. 18 3
      optiboot/bootloaders/optiboot/optiboot.c
  3. 28 26
      optiboot/bootloaders/optiboot/optiboot_atmega1280.hex
  4. 184 167
      optiboot/bootloaders/optiboot/optiboot_atmega1280.lst
  5. 27 25
      optiboot/bootloaders/optiboot/optiboot_atmega328.hex
  6. 181 164
      optiboot/bootloaders/optiboot/optiboot_atmega328.lst
  7. 27 25
      optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex
  8. 181 164
      optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst
  9. 27 25
      optiboot/bootloaders/optiboot/optiboot_atmega644p.hex
  10. 181 164
      optiboot/bootloaders/optiboot/optiboot_atmega644p.lst
  11. 27 25
      optiboot/bootloaders/optiboot/optiboot_diecimila.hex
  12. 181 164
      optiboot/bootloaders/optiboot/optiboot_diecimila.lst
  13. 27 25
      optiboot/bootloaders/optiboot/optiboot_lilypad.hex
  14. 181 164
      optiboot/bootloaders/optiboot/optiboot_lilypad.lst
  15. 27 25
      optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.hex
  16. 181 164
      optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.lst
  17. 3 3
      optiboot/bootloaders/optiboot/optiboot_luminet.hex
  18. 23 20
      optiboot/bootloaders/optiboot/optiboot_luminet.lst
  19. 27 25
      optiboot/bootloaders/optiboot/optiboot_pro_16MHz.hex
  20. 181 164
      optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst
  21. 27 25
      optiboot/bootloaders/optiboot/optiboot_pro_20mhz.hex
  22. 181 164
      optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst
  23. 27 25
      optiboot/bootloaders/optiboot/optiboot_pro_8MHz.hex
  24. 181 164
      optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst

+ 10 - 0
optiboot/bootloaders/optiboot/Makefile

@@ -63,6 +63,16 @@ override LDFLAGS       = -Wl,$(LDSECTION) -Wl,--relax -nostartfiles
 OBJCOPY        = avr-objcopy
 OBJDUMP        = avr-objdump
 
+# Test platforms
+# Virtual boot block test
+virboot328: TARGET = atmega328
+virboot328: MCU_TARGET = atmega328p
+virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT
+virboot328: AVR_FREQ = 16000000L
+virboot328: LDSECTION  = --section-start=.text=0x7e00
+virboot328: $(PROGRAM)_atmega328.hex
+virboot328: $(PROGRAM)_atmega328.lst
+
 # 20MHz clocked platforms
 #
 # These are capable of 230400 baud, or 115200 baud on PC (Arduino Avrdude issue)

+ 18 - 3
optiboot/bootloaders/optiboot/optiboot.c

@@ -184,10 +184,21 @@ void uartDelay() __attribute__ ((naked));
 #endif
 void appStart() __attribute__ ((naked));
 
-#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || (__AVR_ATmega644P__) || defined(__AVR_ATtiny84__)
+#if defined(__AVR_ATmega168__)
 #define RAMSTART (0x100)
+#define NRWWSTART (0x3800)
+#elif defined(__AVR_ATmega328P__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0x7000)
+#elif defined (__AVR_ATmega644P__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0xE000)
+#elif defined(__AVR_ATtiny84__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0x0000)
 #elif defined(__AVR_ATmega1280__)
 #define RAMSTART (0x200)
+#define NRWWSTART (0xE000)
 #endif
 
 /* C zero initialises all global variables. However, that requires */
@@ -293,14 +304,18 @@ int main(void) {
 
       getLen();
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // 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();
       while (--length);
 
+      // 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);
+
       // Read command terminator, start reply
       verifySpace();
       

+ 28 - 26
optiboot/bootloaders/optiboot/optiboot_atmega1280.hex

@@ -1,34 +1,36 @@
 :020000021000EC
 :10FC000085E08093810082E08093C00088E180934A
 :10FC1000C10086E08093C20080E18093C40084B775
-:10FC200014BE81FFCFD08DE0C7D0279A86E020E3B5
+:10FC200014BE81FFDED08DE0D6D0279A86E020E397
 :10FC30003CEF91E0309385002093840096BBB09B0D
-:10FC4000FECF1F9AA8958150A9F7DD24D394A5E093
-:10FC5000EA2EF1E1FF2EA3D0813419F481E0BDD06A
-:10FC60008CC0823411F484E103C0853419F485E03A
-:10FC7000B4D08AC08535A9F492D0082F10E08FD077
+:10FC4000FECF1F9AA8958150A9F7EE24E394A5E072
+:10FC5000DA2EF1E1FF2EB2D0813419F481E0CCD05C
+:10FC60009BC0823411F484E103C0853419F485E02B
+:10FC7000C3D099C08535A9F4A1D0082F10E09ED03B
 :10FC800090E0982F8827802B912B292F221F222745
 :10FC9000221F2BBF880F991F9093010480930004AB
-:10FCA00072C0863529F484E098D080E070D06CC0B2
-:10FCB000843609F03FC07BD0E0910004F09101044C
-:10FCC00083E087BFE895C0E0D2E069D08993809156
-:10FCD00002048150809302048823B9F778D007B6D4
-:10FCE00000FCFDCF4091000450910104A0E0B2E07F
-:10FCF0002C9130E011968C91119790E0982F8827E5
-:10FD0000822B932B1296FA010C01D7BEE895112491
-:10FD10004E5F5F4FF3E0A030BF0751F7E091000462
-:10FD2000F0910104E7BEE89507B600FCFDCFF7BEF1
-:10FD3000E8952AC08437D1F43AD049D0E091000444
-:10FD4000F0910104E6918E2F22D0809100049091D1
-:10FD500001040196909301048093000480910204B1
-:10FD6000815080930204882349F70EC0853739F407
-:10FD70002ED08EE10CD087E90AD083E097CF813571
-:10FD800011F488E019D023D080E101D064CF982FFE
-:10FD90008091C00085FFFCCF9093C6000895A89580
-:10FDA0008091C00087FFFCCF8091C6000895F7DFE7
-:10FDB000F6DF80930204F3CFE0E6F0E098E1908371
-:10FDC0008083089580E0F8DFEE27FF270994E7DFBE
-:10FDD000803209F0F7DF84E1DACF1F93182FDFDFDD
-:0AFDE0001150E9F7F4DF1F910895B8
+:10FCA00081C0863529F484E0A7D080E07FD07BC076
+:10FCB000843609F04EC08AD0E0910004F09101042E
+:10FCC00080EEE030F80718F483E087BFE895C0E0E5
+:10FCD000D2E074D089938091020481508093020411
+:10FCE0008823B9F7E0910004F091010480EEE03040
+:10FCF000F80718F083E087BFE89578D007B600FCD6
+:10FD0000FDCF4091000450910104A0E0B2E02C919D
+:10FD100030E011968C91119790E0982F8827822BD4
+:10FD2000932B1296FA010C01E7BEE89511244E5F61
+:10FD30005F4FF3E0A030BF0751F7E0910004F0916E
+:10FD40000104D7BEE89507B600FCFDCFF7BEE895E5
+:10FD50002AC08437D1F43AD049D0E0910004F09120
+:10FD60000104E6918E2F22D080910004909101042D
+:10FD700001969093010480930004809102048150C5
+:10FD800080930204882349F70EC0853739F42ED0BA
+:10FD90008EE10CD087E90AD083E088CF813511F459
+:10FDA00088E019D023D080E101D055CF982F8091E1
+:10FDB000C00085FFFCCF9093C6000895A895809160
+:10FDC000C00087FFFCCF8091C6000895F7DFF6DF03
+:10FDD00080930204F3CFE0E6F0E098E19083808323
+:10FDE000089580E0F8DFEE27FF270994E7DF8032EF
+:10FDF00009F0F7DF84E1DACF1F93182FDFDF11500E
+:08FE0000E9F7F4DF1F910895FA
 :040000031000FC00ED
 :00000001FF

+ 184 - 167
optiboot/bootloaders/optiboot/optiboot_atmega1280.lst

@@ -3,25 +3,25 @@ optiboot_atmega1280.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001ea  0001fc00  0001fc00  00000054  2**1
+  0 .text         00000208  0001fc00  0001fc00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  0000023e  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000025c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000266  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000284  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000277  00000000  00000000  000002d0  2**0
+  3 .debug_info   00000278  00000000  00000000  000002ee  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a1  00000000  00000000  00000547  2**0
+  4 .debug_abbrev 000001a1  00000000  00000000  00000566  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003eb  00000000  00000000  000006e8  2**0
+  5 .debug_line   000003f3  00000000  00000000  00000707  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad4  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000afc  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000135  00000000  00000000  00000b64  2**0
+  7 .debug_str    00000135  00000000  00000000  00000b8c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001b1  00000000  00000000  00000c99  2**0
+  8 .debug_loc    000001b1  00000000  00000000  00000cc1  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e4a  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000e72  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
    1fc20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
    1fc22:	81 ff       	sbrs	r24, 1
-   1fc24:	cf d0       	rcall	.+414    	; 0x1fdc4 <appStart>
+   1fc24:	de d0       	rcall	.+444    	; 0x1fde2 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
    1fc26:	8d e0       	ldi	r24, 0x0D	; 13
-   1fc28:	c7 d0       	rcall	.+398    	; 0x1fdb8 <watchdogConfig>
+   1fc28:	d6 d0       	rcall	.+428    	; 0x1fdd6 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -118,8 +118,8 @@ void watchdogReset() {
     if(ch == STK_GET_PARAMETER) {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
-   1fc4a:	dd 24       	eor	r13, r13
-   1fc4c:	d3 94       	inc	r13
+   1fc4a:	ee 24       	eor	r14, r14
+   1fc4c:	e3 94       	inc	r14
         __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
         addrPtr += 2;
       } while (--ch);
@@ -127,7 +127,7 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
    1fc4e:	a5 e0       	ldi	r26, 0x05	; 5
-   1fc50:	ea 2e       	mov	r14, r26
+   1fc50:	da 2e       	mov	r13, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
@@ -141,7 +141,7 @@ void watchdogReset() {
   for (;;) {
     /* get character from UART */
     ch = getch();
-   1fc56:	a3 d0       	rcall	.+326    	; 0x1fd9e <getch>
+   1fc56:	b2 d0       	rcall	.+356    	; 0x1fdbc <getch>
 
     if(ch == STK_GET_PARAMETER) {
    1fc58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,8 +149,8 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
    1fc5c:	81 e0       	ldi	r24, 0x01	; 1
-   1fc5e:	bd d0       	rcall	.+378    	; 0x1fdda <verifySpace+0xc>
-   1fc60:	8c c0       	rjmp	.+280    	; 0x1fd7a <main+0x17a>
+   1fc5e:	cc d0       	rcall	.+408    	; 0x1fdf8 <verifySpace+0xc>
+   1fc60:	9b c0       	rjmp	.+310    	; 0x1fd98 <main+0x198>
       putch(0x03);
     }
     else if(ch == STK_SET_DEVICE) {
@@ -167,8 +167,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
    1fc6e:	85 e0       	ldi	r24, 0x05	; 5
-   1fc70:	b4 d0       	rcall	.+360    	; 0x1fdda <verifySpace+0xc>
-   1fc72:	8a c0       	rjmp	.+276    	; 0x1fd88 <main+0x188>
+   1fc70:	c3 d0       	rcall	.+390    	; 0x1fdf8 <verifySpace+0xc>
+   1fc72:	99 c0       	rjmp	.+306    	; 0x1fda6 <main+0x1a6>
     }
     else if(ch == STK_LOAD_ADDRESS) {
    1fc74:	85 35       	cpi	r24, 0x55	; 85
@@ -176,11 +176,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-   1fc78:	92 d0       	rcall	.+292    	; 0x1fd9e <getch>
+   1fc78:	a1 d0       	rcall	.+322    	; 0x1fdbc <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
    1fc7a:	08 2f       	mov	r16, r24
    1fc7c:	10 e0       	ldi	r17, 0x00	; 0
-   1fc7e:	8f d0       	rcall	.+286    	; 0x1fd9e <getch>
+   1fc7e:	9e d0       	rcall	.+316    	; 0x1fdbc <getch>
    1fc80:	90 e0       	ldi	r25, 0x00	; 0
    1fc82:	98 2f       	mov	r25, r24
    1fc84:	88 27       	eor	r24, r24
@@ -201,7 +201,7 @@ void watchdogReset() {
       address = newAddress;
    1fc98:	90 93 01 04 	sts	0x0401, r25
    1fc9c:	80 93 00 04 	sts	0x0400, r24
-   1fca0:	72 c0       	rjmp	.+228    	; 0x1fd86 <main+0x186>
+   1fca0:	81 c0       	rjmp	.+258    	; 0x1fda4 <main+0x1a4>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -210,324 +210,341 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
    1fca6:	84 e0       	ldi	r24, 0x04	; 4
-   1fca8:	98 d0       	rcall	.+304    	; 0x1fdda <verifySpace+0xc>
+   1fca8:	a7 d0       	rcall	.+334    	; 0x1fdf8 <verifySpace+0xc>
       putch(0x00);
    1fcaa:	80 e0       	ldi	r24, 0x00	; 0
-   1fcac:	70 d0       	rcall	.+224    	; 0x1fd8e <putch>
-   1fcae:	6c c0       	rjmp	.+216    	; 0x1fd88 <main+0x188>
+   1fcac:	7f d0       	rcall	.+254    	; 0x1fdac <putch>
+   1fcae:	7b c0       	rjmp	.+246    	; 0x1fda6 <main+0x1a6>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
    1fcb0:	84 36       	cpi	r24, 0x64	; 100
    1fcb2:	09 f0       	breq	.+2      	; 0x1fcb6 <main+0xb6>
-   1fcb4:	3f c0       	rjmp	.+126    	; 0x1fd34 <main+0x134>
+   1fcb4:	4e c0       	rjmp	.+156    	; 0x1fd52 <main+0x152>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-   1fcb6:	7b d0       	rcall	.+246    	; 0x1fdae <getLen>
+   1fcb6:	8a d0       	rcall	.+276    	; 0x1fdcc <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
    1fcb8:	e0 91 00 04 	lds	r30, 0x0400
    1fcbc:	f0 91 01 04 	lds	r31, 0x0401
-   1fcc0:	83 e0       	ldi	r24, 0x03	; 3
-   1fcc2:	87 bf       	out	0x37, r24	; 55
-   1fcc4:	e8 95       	spm
-   1fcc6:	c0 e0       	ldi	r28, 0x00	; 0
-   1fcc8:	d2 e0       	ldi	r29, 0x02	; 2
+   1fcc0:	80 ee       	ldi	r24, 0xE0	; 224
+   1fcc2:	e0 30       	cpi	r30, 0x00	; 0
+   1fcc4:	f8 07       	cpc	r31, r24
+   1fcc6:	18 f4       	brcc	.+6      	; 0x1fcce <main+0xce>
+   1fcc8:	83 e0       	ldi	r24, 0x03	; 3
+   1fcca:	87 bf       	out	0x37, r24	; 55
+   1fccc:	e8 95       	spm
+   1fcce:	c0 e0       	ldi	r28, 0x00	; 0
+   1fcd0:	d2 e0       	ldi	r29, 0x02	; 2
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-   1fcca:	69 d0       	rcall	.+210    	; 0x1fd9e <getch>
-   1fccc:	89 93       	st	Y+, r24
+   1fcd2:	74 d0       	rcall	.+232    	; 0x1fdbc <getch>
+   1fcd4:	89 93       	st	Y+, r24
       while (--length);
-   1fcce:	80 91 02 04 	lds	r24, 0x0402
-   1fcd2:	81 50       	subi	r24, 0x01	; 1
-   1fcd4:	80 93 02 04 	sts	0x0402, r24
-   1fcd8:	88 23       	and	r24, r24
-   1fcda:	b9 f7       	brne	.-18     	; 0x1fcca <main+0xca>
+   1fcd6:	80 91 02 04 	lds	r24, 0x0402
+   1fcda:	81 50       	subi	r24, 0x01	; 1
+   1fcdc:	80 93 02 04 	sts	0x0402, r24
+   1fce0:	88 23       	and	r24, r24
+   1fce2:	b9 f7       	brne	.-18     	; 0x1fcd2 <main+0xd2>
+
+      // 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);
+   1fce4:	e0 91 00 04 	lds	r30, 0x0400
+   1fce8:	f0 91 01 04 	lds	r31, 0x0401
+   1fcec:	80 ee       	ldi	r24, 0xE0	; 224
+   1fcee:	e0 30       	cpi	r30, 0x00	; 0
+   1fcf0:	f8 07       	cpc	r31, r24
+   1fcf2:	18 f0       	brcs	.+6      	; 0x1fcfa <main+0xfa>
+   1fcf4:	83 e0       	ldi	r24, 0x03	; 3
+   1fcf6:	87 bf       	out	0x37, r24	; 55
+   1fcf8:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-   1fcdc:	78 d0       	rcall	.+240    	; 0x1fdce <verifySpace>
+   1fcfa:	78 d0       	rcall	.+240    	; 0x1fdec <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-   1fcde:	07 b6       	in	r0, 0x37	; 55
-   1fce0:	00 fc       	sbrc	r0, 0
-   1fce2:	fd cf       	rjmp	.-6      	; 0x1fcde <main+0xde>
+   1fcfc:	07 b6       	in	r0, 0x37	; 55
+   1fcfe:	00 fc       	sbrc	r0, 0
+   1fd00:	fd cf       	rjmp	.-6      	; 0x1fcfc <main+0xfc>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-   1fce4:	40 91 00 04 	lds	r20, 0x0400
-   1fce8:	50 91 01 04 	lds	r21, 0x0401
-   1fcec:	a0 e0       	ldi	r26, 0x00	; 0
-   1fcee:	b2 e0       	ldi	r27, 0x02	; 2
+   1fd02:	40 91 00 04 	lds	r20, 0x0400
+   1fd06:	50 91 01 04 	lds	r21, 0x0401
+   1fd0a:	a0 e0       	ldi	r26, 0x00	; 0
+   1fd0c:	b2 e0       	ldi	r27, 0x02	; 2
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-   1fcf0:	2c 91       	ld	r18, X
-   1fcf2:	30 e0       	ldi	r19, 0x00	; 0
+   1fd0e:	2c 91       	ld	r18, X
+   1fd10:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-   1fcf4:	11 96       	adiw	r26, 0x01	; 1
-   1fcf6:	8c 91       	ld	r24, X
-   1fcf8:	11 97       	sbiw	r26, 0x01	; 1
-   1fcfa:	90 e0       	ldi	r25, 0x00	; 0
-   1fcfc:	98 2f       	mov	r25, r24
-   1fcfe:	88 27       	eor	r24, r24
-   1fd00:	82 2b       	or	r24, r18
-   1fd02:	93 2b       	or	r25, r19
+   1fd12:	11 96       	adiw	r26, 0x01	; 1
+   1fd14:	8c 91       	ld	r24, X
+   1fd16:	11 97       	sbiw	r26, 0x01	; 1
+   1fd18:	90 e0       	ldi	r25, 0x00	; 0
+   1fd1a:	98 2f       	mov	r25, r24
+   1fd1c:	88 27       	eor	r24, r24
+   1fd1e:	82 2b       	or	r24, r18
+   1fd20:	93 2b       	or	r25, r19
 #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) {
-   1fd04:	12 96       	adiw	r26, 0x02	; 2
+   1fd22:	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);
-   1fd06:	fa 01       	movw	r30, r20
-   1fd08:	0c 01       	movw	r0, r24
-   1fd0a:	d7 be       	out	0x37, r13	; 55
-   1fd0c:	e8 95       	spm
-   1fd0e:	11 24       	eor	r1, r1
+   1fd24:	fa 01       	movw	r30, r20
+   1fd26:	0c 01       	movw	r0, r24
+   1fd28:	e7 be       	out	0x37, r14	; 55
+   1fd2a:	e8 95       	spm
+   1fd2c:	11 24       	eor	r1, r1
         addrPtr += 2;
-   1fd10:	4e 5f       	subi	r20, 0xFE	; 254
-   1fd12:	5f 4f       	sbci	r21, 0xFF	; 255
+   1fd2e:	4e 5f       	subi	r20, 0xFE	; 254
+   1fd30:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-   1fd14:	f3 e0       	ldi	r31, 0x03	; 3
-   1fd16:	a0 30       	cpi	r26, 0x00	; 0
-   1fd18:	bf 07       	cpc	r27, r31
-   1fd1a:	51 f7       	brne	.-44     	; 0x1fcf0 <main+0xf0>
+   1fd32:	f3 e0       	ldi	r31, 0x03	; 3
+   1fd34:	a0 30       	cpi	r26, 0x00	; 0
+   1fd36:	bf 07       	cpc	r27, r31
+   1fd38:	51 f7       	brne	.-44     	; 0x1fd0e <main+0x10e>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-   1fd1c:	e0 91 00 04 	lds	r30, 0x0400
-   1fd20:	f0 91 01 04 	lds	r31, 0x0401
-   1fd24:	e7 be       	out	0x37, r14	; 55
-   1fd26:	e8 95       	spm
+   1fd3a:	e0 91 00 04 	lds	r30, 0x0400
+   1fd3e:	f0 91 01 04 	lds	r31, 0x0401
+   1fd42:	d7 be       	out	0x37, r13	; 55
+   1fd44:	e8 95       	spm
       boot_spm_busy_wait();
-   1fd28:	07 b6       	in	r0, 0x37	; 55
-   1fd2a:	00 fc       	sbrc	r0, 0
-   1fd2c:	fd cf       	rjmp	.-6      	; 0x1fd28 <main+0x128>
+   1fd46:	07 b6       	in	r0, 0x37	; 55
+   1fd48:	00 fc       	sbrc	r0, 0
+   1fd4a:	fd cf       	rjmp	.-6      	; 0x1fd46 <main+0x146>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-   1fd2e:	f7 be       	out	0x37, r15	; 55
-   1fd30:	e8 95       	spm
-   1fd32:	2a c0       	rjmp	.+84     	; 0x1fd88 <main+0x188>
+   1fd4c:	f7 be       	out	0x37, r15	; 55
+   1fd4e:	e8 95       	spm
+   1fd50:	2a c0       	rjmp	.+84     	; 0x1fda6 <main+0x1a6>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-   1fd34:	84 37       	cpi	r24, 0x74	; 116
-   1fd36:	d1 f4       	brne	.+52     	; 0x1fd6c <main+0x16c>
+   1fd52:	84 37       	cpi	r24, 0x74	; 116
+   1fd54:	d1 f4       	brne	.+52     	; 0x1fd8a <main+0x18a>
       // READ PAGE - we only read flash
       getLen();
-   1fd38:	3a d0       	rcall	.+116    	; 0x1fdae <getLen>
+   1fd56:	3a d0       	rcall	.+116    	; 0x1fdcc <getLen>
       verifySpace();
-   1fd3a:	49 d0       	rcall	.+146    	; 0x1fdce <verifySpace>
+   1fd58:	49 d0       	rcall	.+146    	; 0x1fdec <verifySpace>
 #ifdef __AVR_ATmega1280__
 //      do putch(pgm_read_byte_near(address++));
 //      while (--length);
       do {
         uint8_t result;
         __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address));
-   1fd3c:	e0 91 00 04 	lds	r30, 0x0400
-   1fd40:	f0 91 01 04 	lds	r31, 0x0401
-   1fd44:	e6 91       	elpm	r30, Z+
+   1fd5a:	e0 91 00 04 	lds	r30, 0x0400
+   1fd5e:	f0 91 01 04 	lds	r31, 0x0401
+   1fd62:	e6 91       	elpm	r30, Z+
         putch(result);
-   1fd46:	8e 2f       	mov	r24, r30
-   1fd48:	22 d0       	rcall	.+68     	; 0x1fd8e <putch>
+   1fd64:	8e 2f       	mov	r24, r30
+   1fd66:	22 d0       	rcall	.+68     	; 0x1fdac <putch>
         address++;
-   1fd4a:	80 91 00 04 	lds	r24, 0x0400
-   1fd4e:	90 91 01 04 	lds	r25, 0x0401
-   1fd52:	01 96       	adiw	r24, 0x01	; 1
-   1fd54:	90 93 01 04 	sts	0x0401, r25
-   1fd58:	80 93 00 04 	sts	0x0400, r24
+   1fd68:	80 91 00 04 	lds	r24, 0x0400
+   1fd6c:	90 91 01 04 	lds	r25, 0x0401
+   1fd70:	01 96       	adiw	r24, 0x01	; 1
+   1fd72:	90 93 01 04 	sts	0x0401, r25
+   1fd76:	80 93 00 04 	sts	0x0400, r24
       }
       while (--length);
-   1fd5c:	80 91 02 04 	lds	r24, 0x0402
-   1fd60:	81 50       	subi	r24, 0x01	; 1
-   1fd62:	80 93 02 04 	sts	0x0402, r24
-   1fd66:	88 23       	and	r24, r24
-   1fd68:	49 f7       	brne	.-46     	; 0x1fd3c <main+0x13c>
-   1fd6a:	0e c0       	rjmp	.+28     	; 0x1fd88 <main+0x188>
+   1fd7a:	80 91 02 04 	lds	r24, 0x0402
+   1fd7e:	81 50       	subi	r24, 0x01	; 1
+   1fd80:	80 93 02 04 	sts	0x0402, r24
+   1fd84:	88 23       	and	r24, r24
+   1fd86:	49 f7       	brne	.-46     	; 0x1fd5a <main+0x15a>
+   1fd88:	0e c0       	rjmp	.+28     	; 0x1fda6 <main+0x1a6>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-   1fd6c:	85 37       	cpi	r24, 0x75	; 117
-   1fd6e:	39 f4       	brne	.+14     	; 0x1fd7e <main+0x17e>
+   1fd8a:	85 37       	cpi	r24, 0x75	; 117
+   1fd8c:	39 f4       	brne	.+14     	; 0x1fd9c <main+0x19c>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-   1fd70:	2e d0       	rcall	.+92     	; 0x1fdce <verifySpace>
+   1fd8e:	2e d0       	rcall	.+92     	; 0x1fdec <verifySpace>
       putch(SIGNATURE_0);
-   1fd72:	8e e1       	ldi	r24, 0x1E	; 30
-   1fd74:	0c d0       	rcall	.+24     	; 0x1fd8e <putch>
+   1fd90:	8e e1       	ldi	r24, 0x1E	; 30
+   1fd92:	0c d0       	rcall	.+24     	; 0x1fdac <putch>
       putch(SIGNATURE_1);
-   1fd76:	87 e9       	ldi	r24, 0x97	; 151
-   1fd78:	0a d0       	rcall	.+20     	; 0x1fd8e <putch>
+   1fd94:	87 e9       	ldi	r24, 0x97	; 151
+   1fd96:	0a d0       	rcall	.+20     	; 0x1fdac <putch>
       putch(SIGNATURE_2);
-   1fd7a:	83 e0       	ldi	r24, 0x03	; 3
-   1fd7c:	97 cf       	rjmp	.-210    	; 0x1fcac <main+0xac>
+   1fd98:	83 e0       	ldi	r24, 0x03	; 3
+   1fd9a:	88 cf       	rjmp	.-240    	; 0x1fcac <main+0xac>
     }
     else if (ch == 'Q') {
-   1fd7e:	81 35       	cpi	r24, 0x51	; 81
-   1fd80:	11 f4       	brne	.+4      	; 0x1fd86 <main+0x186>
+   1fd9c:	81 35       	cpi	r24, 0x51	; 81
+   1fd9e:	11 f4       	brne	.+4      	; 0x1fda4 <main+0x1a4>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-   1fd82:	88 e0       	ldi	r24, 0x08	; 8
-   1fd84:	19 d0       	rcall	.+50     	; 0x1fdb8 <watchdogConfig>
+   1fda0:	88 e0       	ldi	r24, 0x08	; 8
+   1fda2:	19 d0       	rcall	.+50     	; 0x1fdd6 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-   1fd86:	23 d0       	rcall	.+70     	; 0x1fdce <verifySpace>
+   1fda4:	23 d0       	rcall	.+70     	; 0x1fdec <verifySpace>
     }
     putch(STK_OK);
-   1fd88:	80 e1       	ldi	r24, 0x10	; 16
-   1fd8a:	01 d0       	rcall	.+2      	; 0x1fd8e <putch>
-   1fd8c:	64 cf       	rjmp	.-312    	; 0x1fc56 <main+0x56>
+   1fda6:	80 e1       	ldi	r24, 0x10	; 16
+   1fda8:	01 d0       	rcall	.+2      	; 0x1fdac <putch>
+   1fdaa:	55 cf       	rjmp	.-342    	; 0x1fc56 <main+0x56>
 
-0001fd8e <putch>:
+0001fdac <putch>:
   }
 }
 
 void putch(char ch) {
-   1fd8e:	98 2f       	mov	r25, r24
+   1fdac:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-   1fd90:	80 91 c0 00 	lds	r24, 0x00C0
-   1fd94:	85 ff       	sbrs	r24, 5
-   1fd96:	fc cf       	rjmp	.-8      	; 0x1fd90 <putch+0x2>
+   1fdae:	80 91 c0 00 	lds	r24, 0x00C0
+   1fdb2:	85 ff       	sbrs	r24, 5
+   1fdb4:	fc cf       	rjmp	.-8      	; 0x1fdae <putch+0x2>
   UDR0 = ch;
-   1fd98:	90 93 c6 00 	sts	0x00C6, r25
+   1fdb6:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-   1fd9c:	08 95       	ret
+   1fdba:	08 95       	ret
 
-0001fd9e <getch>:
+0001fdbc <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-   1fd9e:	a8 95       	wdr
+   1fdbc:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-   1fda0:	80 91 c0 00 	lds	r24, 0x00C0
-   1fda4:	87 ff       	sbrs	r24, 7
-   1fda6:	fc cf       	rjmp	.-8      	; 0x1fda0 <getch+0x2>
+   1fdbe:	80 91 c0 00 	lds	r24, 0x00C0
+   1fdc2:	87 ff       	sbrs	r24, 7
+   1fdc4:	fc cf       	rjmp	.-8      	; 0x1fdbe <getch+0x2>
   ch = UDR0;
-   1fda8:	80 91 c6 00 	lds	r24, 0x00C6
+   1fdc6:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-   1fdac:	08 95       	ret
+   1fdca:	08 95       	ret
 
-0001fdae <getLen>:
+0001fdcc <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-   1fdae:	f7 df       	rcall	.-18     	; 0x1fd9e <getch>
+   1fdcc:	f7 df       	rcall	.-18     	; 0x1fdbc <getch>
   length = getch();
-   1fdb0:	f6 df       	rcall	.-20     	; 0x1fd9e <getch>
-   1fdb2:	80 93 02 04 	sts	0x0402, r24
+   1fdce:	f6 df       	rcall	.-20     	; 0x1fdbc <getch>
+   1fdd0:	80 93 02 04 	sts	0x0402, r24
   return getch();
 }
-   1fdb6:	f3 cf       	rjmp	.-26     	; 0x1fd9e <getch>
+   1fdd4:	f3 cf       	rjmp	.-26     	; 0x1fdbc <getch>
 
-0001fdb8 <watchdogConfig>:
+0001fdd6 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-   1fdb8:	e0 e6       	ldi	r30, 0x60	; 96
-   1fdba:	f0 e0       	ldi	r31, 0x00	; 0
-   1fdbc:	98 e1       	ldi	r25, 0x18	; 24
-   1fdbe:	90 83       	st	Z, r25
+   1fdd6:	e0 e6       	ldi	r30, 0x60	; 96
+   1fdd8:	f0 e0       	ldi	r31, 0x00	; 0
+   1fdda:	98 e1       	ldi	r25, 0x18	; 24
+   1fddc:	90 83       	st	Z, r25
   WDTCSR = x;
-   1fdc0:	80 83       	st	Z, r24
+   1fdde:	80 83       	st	Z, r24
 }
-   1fdc2:	08 95       	ret
+   1fde0:	08 95       	ret
 
-0001fdc4 <appStart>:
+0001fde2 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-   1fdc4:	80 e0       	ldi	r24, 0x00	; 0
-   1fdc6:	f8 df       	rcall	.-16     	; 0x1fdb8 <watchdogConfig>
+   1fde2:	80 e0       	ldi	r24, 0x00	; 0
+   1fde4:	f8 df       	rcall	.-16     	; 0x1fdd6 <watchdogConfig>
   __asm__ __volatile__ (
-   1fdc8:	ee 27       	eor	r30, r30
-   1fdca:	ff 27       	eor	r31, r31
-   1fdcc:	09 94       	ijmp
+   1fde6:	ee 27       	eor	r30, r30
+   1fde8:	ff 27       	eor	r31, r31
+   1fdea:	09 94       	ijmp
 
-0001fdce <verifySpace>:
+0001fdec <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-   1fdce:	e7 df       	rcall	.-50     	; 0x1fd9e <getch>
-   1fdd0:	80 32       	cpi	r24, 0x20	; 32
-   1fdd2:	09 f0       	breq	.+2      	; 0x1fdd6 <verifySpace+0x8>
-   1fdd4:	f7 df       	rcall	.-18     	; 0x1fdc4 <appStart>
+   1fdec:	e7 df       	rcall	.-50     	; 0x1fdbc <getch>
+   1fdee:	80 32       	cpi	r24, 0x20	; 32
+   1fdf0:	09 f0       	breq	.+2      	; 0x1fdf4 <verifySpace+0x8>
+   1fdf2:	f7 df       	rcall	.-18     	; 0x1fde2 <appStart>
   putch(STK_INSYNC);
-   1fdd6:	84 e1       	ldi	r24, 0x14	; 20
+   1fdf4:	84 e1       	ldi	r24, 0x14	; 20
 }
-   1fdd8:	da cf       	rjmp	.-76     	; 0x1fd8e <putch>
+   1fdf6:	da cf       	rjmp	.-76     	; 0x1fdac <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-   1fdda:	1f 93       	push	r17
-   1fddc:	18 2f       	mov	r17, r24
+   1fdf8:	1f 93       	push	r17
+   1fdfa:	18 2f       	mov	r17, r24
 
-0001fdde <getNch>:
+0001fdfc <getNch>:
   do getch(); while (--count);
-   1fdde:	df df       	rcall	.-66     	; 0x1fd9e <getch>
-   1fde0:	11 50       	subi	r17, 0x01	; 1
-   1fde2:	e9 f7       	brne	.-6      	; 0x1fdde <getNch>
+   1fdfc:	df df       	rcall	.-66     	; 0x1fdbc <getch>
+   1fdfe:	11 50       	subi	r17, 0x01	; 1
+   1fe00:	e9 f7       	brne	.-6      	; 0x1fdfc <getNch>
   verifySpace();
-   1fde4:	f4 df       	rcall	.-24     	; 0x1fdce <verifySpace>
+   1fe02:	f4 df       	rcall	.-24     	; 0x1fdec <verifySpace>
 }
-   1fde6:	1f 91       	pop	r17
-   1fde8:	08 95       	ret
+   1fe04:	1f 91       	pop	r17
+   1fe06:	08 95       	ret

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_atmega328.hex

@@ -1,32 +1,34 @@
 :107E000085E08093810082E08093C00088E18093C8
 :107E1000C10086E08093C20080E18093C40084B7F3
-:107E200014BE81FFC8D08DE0C0D0259A86E020E343
+:107E200014BE81FFD7D08DE0CFD0259A86E020E325
 :107E30003CEF91E0309385002093840096BBB09B8B
 :107E4000FECF1D9AA8958150A9F7DD24D394A5E013
-:107E5000FA2EF1E1EF2E9CD0813421F481E0B6D0EE
+:107E5000EA2EF1E1FF2EABD0813421F481E0C5D0D0
 :107E600083E020C0823411F484E103C0853419F426
-:107E700085E0ACD082C0853581F48AD0082F10E02F
-:107E800087D090E0982F8827802B912B880F991FFF
-:107E900090930102809300026FC0863529F484E03C
-:107EA00095D080E06DD069C0843609F03FC078D0AD
-:107EB000E0910002F091010283E087BFE895C0E005
-:107EC000D1E066D0899380910202815080930202B2
-:107ED0008823B9F775D007B600FCFDCF40910002AA
-:107EE00050910102A0E0B1E02C9130E011968C910C
-:107EF000119790E0982F8827822B932B1296FA01E6
-:107F00000C01D7BEE89511244E5F5F4FF1E0A03819
-:107F1000BF0751F7E0910002F0910102F7BEE8952A
-:107F200007B600FCFDCFE7BEE89527C08437B9F45B
-:107F300037D046D0E0910002F09101023196F093E3
-:107F40000102E09300023197E4918E2F19D08091C5
-:107F50000202815080930202882361F70EC08537A8
-:107F600039F42ED08EE10CD085E90AD08FE09ACF7B
-:107F7000813511F488E019D023D080E101D06BCF96
-:107F8000982F8091C00085FFFCCF9093C600089584
-:107F9000A8958091C00087FFFCCF8091C60008950E
-:107FA000F7DFF6DF80930202F3CFE0E6F0E098E13E
-:107FB00090838083089580E0F8DFEE27FF270994FF
-:107FC000E7DF803209F0F7DF84E1DACF1F93182F63
-:0C7FD000DFDF1150E9F7F4DF1F91089586
+:107E700085E0BBD091C0853581F499D0082F10E002
+:107E800096D090E0982F8827802B912B880F991FF0
+:107E900090930102809300027EC0863529F484E02D
+:107EA000A4D080E07CD078C0843609F04EC087D062
+:107EB000E0910002F091010280E7E030F80718F449
+:107EC00083E087BFE895C0E0D1E071D089938091CD
+:107ED00002028150809302028823B9F7E0910002E8
+:107EE000F091010280E7E030F80718F083E087BFE7
+:107EF000E89575D007B600FCFDCF40910002509187
+:107F00000102A0E0B1E02C9130E011968C91119724
+:107F100090E0982F8827822B932B1296FA010C0160
+:107F2000D7BEE89511244E5F5F4FF1E0A038BF0740
+:107F300051F7E0910002F0910102E7BEE89507B623
+:107F400000FCFDCFF7BEE89527C08437B9F437D0E1
+:107F500046D0E0910002F09101023196F0930102C7
+:107F6000E09300023197E4918E2F19D080910202A4
+:107F7000815080930202882361F70EC0853739F45F
+:107F80002ED08EE10CD085E90AD08FE08BCF8135E1
+:107F900011F488E019D023D080E101D05CCF982F74
+:107FA0008091C00085FFFCCF9093C6000895A895EE
+:107FB0008091C00087FFFCCF8091C6000895F7DF55
+:107FC000F6DF80930202F3CFE0E6F0E098E19083E1
+:107FD0008083089580E0F8DFEE27FF270994E7DF2C
+:107FE000803209F0F7DF84E1DACF1F93182FDFDF4B
+:0A7FF0001150E9F7F4DF1F91089526
 :0400000300007E007B
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_atmega328.lst

@@ -3,25 +3,25 @@ optiboot_atmega328.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  00007e00  00007e00  00000054  2**1
+  0 .text         000001fa  00007e00  00007e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     7e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     7e22:	81 ff       	sbrs	r24, 1
-    7e24:	c8 d0       	rcall	.+400    	; 0x7fb6 <appStart>
+    7e24:	d7 d0       	rcall	.+430    	; 0x7fd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     7e26:	8d e0       	ldi	r24, 0x0D	; 13
-    7e28:	c0 d0       	rcall	.+384    	; 0x7faa <watchdogConfig>
+    7e28:	cf d0       	rcall	.+414    	; 0x7fc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     7e4e:	a5 e0       	ldi	r26, 0x05	; 5
-    7e50:	fa 2e       	mov	r15, r26
+    7e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     7e52:	f1 e1       	ldi	r31, 0x11	; 17
-    7e54:	ef 2e       	mov	r14, r31
+    7e54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    7e56:	9c d0       	rcall	.+312    	; 0x7f90 <getch>
+    7e56:	ab d0       	rcall	.+342    	; 0x7fae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     7e58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     7e5c:	81 e0       	ldi	r24, 0x01	; 1
-    7e5e:	b6 d0       	rcall	.+364    	; 0x7fcc <verifySpace+0xc>
+    7e5e:	c5 d0       	rcall	.+394    	; 0x7fea <verifySpace+0xc>
       putch(0x03);
     7e60:	83 e0       	ldi	r24, 0x03	; 3
     7e62:	20 c0       	rjmp	.+64     	; 0x7ea4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     7e70:	85 e0       	ldi	r24, 0x05	; 5
-    7e72:	ac d0       	rcall	.+344    	; 0x7fcc <verifySpace+0xc>
-    7e74:	82 c0       	rjmp	.+260    	; 0x7f7a <main+0x17a>
+    7e72:	bb d0       	rcall	.+374    	; 0x7fea <verifySpace+0xc>
+    7e74:	91 c0       	rjmp	.+290    	; 0x7f98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     7e76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    7e7a:	8a d0       	rcall	.+276    	; 0x7f90 <getch>
+    7e7a:	99 d0       	rcall	.+306    	; 0x7fae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     7e7c:	08 2f       	mov	r16, r24
     7e7e:	10 e0       	ldi	r17, 0x00	; 0
-    7e80:	87 d0       	rcall	.+270    	; 0x7f90 <getch>
+    7e80:	96 d0       	rcall	.+300    	; 0x7fae <getch>
     7e82:	90 e0       	ldi	r25, 0x00	; 0
     7e84:	98 2f       	mov	r25, r24
     7e86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     7e90:	90 93 01 02 	sts	0x0201, r25
     7e94:	80 93 00 02 	sts	0x0200, r24
-    7e98:	6f c0       	rjmp	.+222    	; 0x7f78 <main+0x178>
+    7e98:	7e c0       	rjmp	.+252    	; 0x7f96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     7e9e:	84 e0       	ldi	r24, 0x04	; 4
-    7ea0:	95 d0       	rcall	.+298    	; 0x7fcc <verifySpace+0xc>
+    7ea0:	a4 d0       	rcall	.+328    	; 0x7fea <verifySpace+0xc>
       putch(0x00);
     7ea2:	80 e0       	ldi	r24, 0x00	; 0
-    7ea4:	6d d0       	rcall	.+218    	; 0x7f80 <putch>
-    7ea6:	69 c0       	rjmp	.+210    	; 0x7f7a <main+0x17a>
+    7ea4:	7c d0       	rcall	.+248    	; 0x7f9e <putch>
+    7ea6:	78 c0       	rjmp	.+240    	; 0x7f98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     7ea8:	84 36       	cpi	r24, 0x64	; 100
     7eaa:	09 f0       	breq	.+2      	; 0x7eae <main+0xae>
-    7eac:	3f c0       	rjmp	.+126    	; 0x7f2c <main+0x12c>
+    7eac:	4e c0       	rjmp	.+156    	; 0x7f4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    7eae:	78 d0       	rcall	.+240    	; 0x7fa0 <getLen>
+    7eae:	87 d0       	rcall	.+270    	; 0x7fbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     7eb0:	e0 91 00 02 	lds	r30, 0x0200
     7eb4:	f0 91 01 02 	lds	r31, 0x0201
-    7eb8:	83 e0       	ldi	r24, 0x03	; 3
-    7eba:	87 bf       	out	0x37, r24	; 55
-    7ebc:	e8 95       	spm
-    7ebe:	c0 e0       	ldi	r28, 0x00	; 0
-    7ec0:	d1 e0       	ldi	r29, 0x01	; 1
+    7eb8:	80 e7       	ldi	r24, 0x70	; 112
+    7eba:	e0 30       	cpi	r30, 0x00	; 0
+    7ebc:	f8 07       	cpc	r31, r24
+    7ebe:	18 f4       	brcc	.+6      	; 0x7ec6 <main+0xc6>
+    7ec0:	83 e0       	ldi	r24, 0x03	; 3
+    7ec2:	87 bf       	out	0x37, r24	; 55
+    7ec4:	e8 95       	spm
+    7ec6:	c0 e0       	ldi	r28, 0x00	; 0
+    7ec8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    7ec2:	66 d0       	rcall	.+204    	; 0x7f90 <getch>
-    7ec4:	89 93       	st	Y+, r24
+    7eca:	71 d0       	rcall	.+226    	; 0x7fae <getch>
+    7ecc:	89 93       	st	Y+, r24
       while (--length);
-    7ec6:	80 91 02 02 	lds	r24, 0x0202
-    7eca:	81 50       	subi	r24, 0x01	; 1
-    7ecc:	80 93 02 02 	sts	0x0202, r24
-    7ed0:	88 23       	and	r24, r24
-    7ed2:	b9 f7       	brne	.-18     	; 0x7ec2 <main+0xc2>
+    7ece:	80 91 02 02 	lds	r24, 0x0202
+    7ed2:	81 50       	subi	r24, 0x01	; 1
+    7ed4:	80 93 02 02 	sts	0x0202, r24
+    7ed8:	88 23       	and	r24, r24
+    7eda:	b9 f7       	brne	.-18     	; 0x7eca <main+0xca>
+
+      // 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);
+    7edc:	e0 91 00 02 	lds	r30, 0x0200
+    7ee0:	f0 91 01 02 	lds	r31, 0x0201
+    7ee4:	80 e7       	ldi	r24, 0x70	; 112
+    7ee6:	e0 30       	cpi	r30, 0x00	; 0
+    7ee8:	f8 07       	cpc	r31, r24
+    7eea:	18 f0       	brcs	.+6      	; 0x7ef2 <main+0xf2>
+    7eec:	83 e0       	ldi	r24, 0x03	; 3
+    7eee:	87 bf       	out	0x37, r24	; 55
+    7ef0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    7ed4:	75 d0       	rcall	.+234    	; 0x7fc0 <verifySpace>
+    7ef2:	75 d0       	rcall	.+234    	; 0x7fde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    7ed6:	07 b6       	in	r0, 0x37	; 55
-    7ed8:	00 fc       	sbrc	r0, 0
-    7eda:	fd cf       	rjmp	.-6      	; 0x7ed6 <main+0xd6>
+    7ef4:	07 b6       	in	r0, 0x37	; 55
+    7ef6:	00 fc       	sbrc	r0, 0
+    7ef8:	fd cf       	rjmp	.-6      	; 0x7ef4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    7edc:	40 91 00 02 	lds	r20, 0x0200
-    7ee0:	50 91 01 02 	lds	r21, 0x0201
-    7ee4:	a0 e0       	ldi	r26, 0x00	; 0
-    7ee6:	b1 e0       	ldi	r27, 0x01	; 1
+    7efa:	40 91 00 02 	lds	r20, 0x0200
+    7efe:	50 91 01 02 	lds	r21, 0x0201
+    7f02:	a0 e0       	ldi	r26, 0x00	; 0
+    7f04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    7ee8:	2c 91       	ld	r18, X
-    7eea:	30 e0       	ldi	r19, 0x00	; 0
+    7f06:	2c 91       	ld	r18, X
+    7f08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    7eec:	11 96       	adiw	r26, 0x01	; 1
-    7eee:	8c 91       	ld	r24, X
-    7ef0:	11 97       	sbiw	r26, 0x01	; 1
-    7ef2:	90 e0       	ldi	r25, 0x00	; 0
-    7ef4:	98 2f       	mov	r25, r24
-    7ef6:	88 27       	eor	r24, r24
-    7ef8:	82 2b       	or	r24, r18
-    7efa:	93 2b       	or	r25, r19
+    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))
 #endif
 
 /* main program starts here */
 int main(void) {
-    7efc:	12 96       	adiw	r26, 0x02	; 2
+    7f1a:	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);
-    7efe:	fa 01       	movw	r30, r20
-    7f00:	0c 01       	movw	r0, r24
-    7f02:	d7 be       	out	0x37, r13	; 55
-    7f04:	e8 95       	spm
-    7f06:	11 24       	eor	r1, r1
+    7f1c:	fa 01       	movw	r30, r20
+    7f1e:	0c 01       	movw	r0, r24
+    7f20:	d7 be       	out	0x37, r13	; 55
+    7f22:	e8 95       	spm
+    7f24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    7f08:	4e 5f       	subi	r20, 0xFE	; 254
-    7f0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    7f26:	4e 5f       	subi	r20, 0xFE	; 254
+    7f28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    7f0c:	f1 e0       	ldi	r31, 0x01	; 1
-    7f0e:	a0 38       	cpi	r26, 0x80	; 128
-    7f10:	bf 07       	cpc	r27, r31
-    7f12:	51 f7       	brne	.-44     	; 0x7ee8 <main+0xe8>
+    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>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    7f14:	e0 91 00 02 	lds	r30, 0x0200
-    7f18:	f0 91 01 02 	lds	r31, 0x0201
-    7f1c:	f7 be       	out	0x37, r15	; 55
-    7f1e:	e8 95       	spm
+    7f32:	e0 91 00 02 	lds	r30, 0x0200
+    7f36:	f0 91 01 02 	lds	r31, 0x0201
+    7f3a:	e7 be       	out	0x37, r14	; 55
+    7f3c:	e8 95       	spm
       boot_spm_busy_wait();
-    7f20:	07 b6       	in	r0, 0x37	; 55
-    7f22:	00 fc       	sbrc	r0, 0
-    7f24:	fd cf       	rjmp	.-6      	; 0x7f20 <main+0x120>
+    7f3e:	07 b6       	in	r0, 0x37	; 55
+    7f40:	00 fc       	sbrc	r0, 0
+    7f42:	fd cf       	rjmp	.-6      	; 0x7f3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    7f26:	e7 be       	out	0x37, r14	; 55
-    7f28:	e8 95       	spm
-    7f2a:	27 c0       	rjmp	.+78     	; 0x7f7a <main+0x17a>
+    7f44:	f7 be       	out	0x37, r15	; 55
+    7f46:	e8 95       	spm
+    7f48:	27 c0       	rjmp	.+78     	; 0x7f98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    7f2c:	84 37       	cpi	r24, 0x74	; 116
-    7f2e:	b9 f4       	brne	.+46     	; 0x7f5e <main+0x15e>
+    7f4a:	84 37       	cpi	r24, 0x74	; 116
+    7f4c:	b9 f4       	brne	.+46     	; 0x7f7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    7f30:	37 d0       	rcall	.+110    	; 0x7fa0 <getLen>
+    7f4e:	37 d0       	rcall	.+110    	; 0x7fbe <getLen>
       verifySpace();
-    7f32:	46 d0       	rcall	.+140    	; 0x7fc0 <verifySpace>
+    7f50:	46 d0       	rcall	.+140    	; 0x7fde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    7f34:	e0 91 00 02 	lds	r30, 0x0200
-    7f38:	f0 91 01 02 	lds	r31, 0x0201
-    7f3c:	31 96       	adiw	r30, 0x01	; 1
-    7f3e:	f0 93 01 02 	sts	0x0201, r31
-    7f42:	e0 93 00 02 	sts	0x0200, r30
-    7f46:	31 97       	sbiw	r30, 0x01	; 1
-    7f48:	e4 91       	lpm	r30, Z+
-    7f4a:	8e 2f       	mov	r24, r30
-    7f4c:	19 d0       	rcall	.+50     	; 0x7f80 <putch>
+    7f52:	e0 91 00 02 	lds	r30, 0x0200
+    7f56:	f0 91 01 02 	lds	r31, 0x0201
+    7f5a:	31 96       	adiw	r30, 0x01	; 1
+    7f5c:	f0 93 01 02 	sts	0x0201, r31
+    7f60:	e0 93 00 02 	sts	0x0200, r30
+    7f64:	31 97       	sbiw	r30, 0x01	; 1
+    7f66:	e4 91       	lpm	r30, Z+
+    7f68:	8e 2f       	mov	r24, r30
+    7f6a:	19 d0       	rcall	.+50     	; 0x7f9e <putch>
       while (--length);
-    7f4e:	80 91 02 02 	lds	r24, 0x0202
-    7f52:	81 50       	subi	r24, 0x01	; 1
-    7f54:	80 93 02 02 	sts	0x0202, r24
-    7f58:	88 23       	and	r24, r24
-    7f5a:	61 f7       	brne	.-40     	; 0x7f34 <main+0x134>
-    7f5c:	0e c0       	rjmp	.+28     	; 0x7f7a <main+0x17a>
+    7f6c:	80 91 02 02 	lds	r24, 0x0202
+    7f70:	81 50       	subi	r24, 0x01	; 1
+    7f72:	80 93 02 02 	sts	0x0202, r24
+    7f76:	88 23       	and	r24, r24
+    7f78:	61 f7       	brne	.-40     	; 0x7f52 <main+0x152>
+    7f7a:	0e c0       	rjmp	.+28     	; 0x7f98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    7f5e:	85 37       	cpi	r24, 0x75	; 117
-    7f60:	39 f4       	brne	.+14     	; 0x7f70 <main+0x170>
+    7f7c:	85 37       	cpi	r24, 0x75	; 117
+    7f7e:	39 f4       	brne	.+14     	; 0x7f8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    7f62:	2e d0       	rcall	.+92     	; 0x7fc0 <verifySpace>
+    7f80:	2e d0       	rcall	.+92     	; 0x7fde <verifySpace>
       putch(SIGNATURE_0);
-    7f64:	8e e1       	ldi	r24, 0x1E	; 30
-    7f66:	0c d0       	rcall	.+24     	; 0x7f80 <putch>
+    7f82:	8e e1       	ldi	r24, 0x1E	; 30
+    7f84:	0c d0       	rcall	.+24     	; 0x7f9e <putch>
       putch(SIGNATURE_1);
-    7f68:	85 e9       	ldi	r24, 0x95	; 149
-    7f6a:	0a d0       	rcall	.+20     	; 0x7f80 <putch>
+    7f86:	85 e9       	ldi	r24, 0x95	; 149
+    7f88:	0a d0       	rcall	.+20     	; 0x7f9e <putch>
       putch(SIGNATURE_2);
-    7f6c:	8f e0       	ldi	r24, 0x0F	; 15
-    7f6e:	9a cf       	rjmp	.-204    	; 0x7ea4 <main+0xa4>
+    7f8a:	8f e0       	ldi	r24, 0x0F	; 15
+    7f8c:	8b cf       	rjmp	.-234    	; 0x7ea4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    7f70:	81 35       	cpi	r24, 0x51	; 81
-    7f72:	11 f4       	brne	.+4      	; 0x7f78 <main+0x178>
+    7f8e:	81 35       	cpi	r24, 0x51	; 81
+    7f90:	11 f4       	brne	.+4      	; 0x7f96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    7f74:	88 e0       	ldi	r24, 0x08	; 8
-    7f76:	19 d0       	rcall	.+50     	; 0x7faa <watchdogConfig>
+    7f92:	88 e0       	ldi	r24, 0x08	; 8
+    7f94:	19 d0       	rcall	.+50     	; 0x7fc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    7f78:	23 d0       	rcall	.+70     	; 0x7fc0 <verifySpace>
+    7f96:	23 d0       	rcall	.+70     	; 0x7fde <verifySpace>
     }
     putch(STK_OK);
-    7f7a:	80 e1       	ldi	r24, 0x10	; 16
-    7f7c:	01 d0       	rcall	.+2      	; 0x7f80 <putch>
-    7f7e:	6b cf       	rjmp	.-298    	; 0x7e56 <main+0x56>
+    7f98:	80 e1       	ldi	r24, 0x10	; 16
+    7f9a:	01 d0       	rcall	.+2      	; 0x7f9e <putch>
+    7f9c:	5c cf       	rjmp	.-328    	; 0x7e56 <main+0x56>
 
-00007f80 <putch>:
+00007f9e <putch>:
   }
 }
 
 void putch(char ch) {
-    7f80:	98 2f       	mov	r25, r24
+    7f9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    7f82:	80 91 c0 00 	lds	r24, 0x00C0
-    7f86:	85 ff       	sbrs	r24, 5
-    7f88:	fc cf       	rjmp	.-8      	; 0x7f82 <putch+0x2>
+    7fa0:	80 91 c0 00 	lds	r24, 0x00C0
+    7fa4:	85 ff       	sbrs	r24, 5
+    7fa6:	fc cf       	rjmp	.-8      	; 0x7fa0 <putch+0x2>
   UDR0 = ch;
-    7f8a:	90 93 c6 00 	sts	0x00C6, r25
+    7fa8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    7f8e:	08 95       	ret
+    7fac:	08 95       	ret
 
-00007f90 <getch>:
+00007fae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    7f90:	a8 95       	wdr
+    7fae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    7f92:	80 91 c0 00 	lds	r24, 0x00C0
-    7f96:	87 ff       	sbrs	r24, 7
-    7f98:	fc cf       	rjmp	.-8      	; 0x7f92 <getch+0x2>
+    7fb0:	80 91 c0 00 	lds	r24, 0x00C0
+    7fb4:	87 ff       	sbrs	r24, 7
+    7fb6:	fc cf       	rjmp	.-8      	; 0x7fb0 <getch+0x2>
   ch = UDR0;
-    7f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    7fb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    7f9e:	08 95       	ret
+    7fbc:	08 95       	ret
 
-00007fa0 <getLen>:
+00007fbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    7fa0:	f7 df       	rcall	.-18     	; 0x7f90 <getch>
+    7fbe:	f7 df       	rcall	.-18     	; 0x7fae <getch>
   length = getch();
-    7fa2:	f6 df       	rcall	.-20     	; 0x7f90 <getch>
-    7fa4:	80 93 02 02 	sts	0x0202, r24
+    7fc0:	f6 df       	rcall	.-20     	; 0x7fae <getch>
+    7fc2:	80 93 02 02 	sts	0x0202, r24
   return getch();
 }
-    7fa8:	f3 cf       	rjmp	.-26     	; 0x7f90 <getch>
+    7fc6:	f3 cf       	rjmp	.-26     	; 0x7fae <getch>
 
-00007faa <watchdogConfig>:
+00007fc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7faa:	e0 e6       	ldi	r30, 0x60	; 96
-    7fac:	f0 e0       	ldi	r31, 0x00	; 0
-    7fae:	98 e1       	ldi	r25, 0x18	; 24
-    7fb0:	90 83       	st	Z, r25
+    7fc8:	e0 e6       	ldi	r30, 0x60	; 96
+    7fca:	f0 e0       	ldi	r31, 0x00	; 0
+    7fcc:	98 e1       	ldi	r25, 0x18	; 24
+    7fce:	90 83       	st	Z, r25
   WDTCSR = x;
-    7fb2:	80 83       	st	Z, r24
+    7fd0:	80 83       	st	Z, r24
 }
-    7fb4:	08 95       	ret
+    7fd2:	08 95       	ret
 
-00007fb6 <appStart>:
+00007fd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    7fb6:	80 e0       	ldi	r24, 0x00	; 0
-    7fb8:	f8 df       	rcall	.-16     	; 0x7faa <watchdogConfig>
+    7fd4:	80 e0       	ldi	r24, 0x00	; 0
+    7fd6:	f8 df       	rcall	.-16     	; 0x7fc8 <watchdogConfig>
   __asm__ __volatile__ (
-    7fba:	ee 27       	eor	r30, r30
-    7fbc:	ff 27       	eor	r31, r31
-    7fbe:	09 94       	ijmp
+    7fd8:	ee 27       	eor	r30, r30
+    7fda:	ff 27       	eor	r31, r31
+    7fdc:	09 94       	ijmp
 
-00007fc0 <verifySpace>:
+00007fde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    7fc0:	e7 df       	rcall	.-50     	; 0x7f90 <getch>
-    7fc2:	80 32       	cpi	r24, 0x20	; 32
-    7fc4:	09 f0       	breq	.+2      	; 0x7fc8 <verifySpace+0x8>
-    7fc6:	f7 df       	rcall	.-18     	; 0x7fb6 <appStart>
+    7fde:	e7 df       	rcall	.-50     	; 0x7fae <getch>
+    7fe0:	80 32       	cpi	r24, 0x20	; 32
+    7fe2:	09 f0       	breq	.+2      	; 0x7fe6 <verifySpace+0x8>
+    7fe4:	f7 df       	rcall	.-18     	; 0x7fd4 <appStart>
   putch(STK_INSYNC);
-    7fc8:	84 e1       	ldi	r24, 0x14	; 20
+    7fe6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    7fca:	da cf       	rjmp	.-76     	; 0x7f80 <putch>
+    7fe8:	da cf       	rjmp	.-76     	; 0x7f9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    7fcc:	1f 93       	push	r17
-    7fce:	18 2f       	mov	r17, r24
+    7fea:	1f 93       	push	r17
+    7fec:	18 2f       	mov	r17, r24
 
-00007fd0 <getNch>:
+00007fee <getNch>:
   do getch(); while (--count);
-    7fd0:	df df       	rcall	.-66     	; 0x7f90 <getch>
-    7fd2:	11 50       	subi	r17, 0x01	; 1
-    7fd4:	e9 f7       	brne	.-6      	; 0x7fd0 <getNch>
+    7fee:	df df       	rcall	.-66     	; 0x7fae <getch>
+    7ff0:	11 50       	subi	r17, 0x01	; 1
+    7ff2:	e9 f7       	brne	.-6      	; 0x7fee <getNch>
   verifySpace();
-    7fd6:	f4 df       	rcall	.-24     	; 0x7fc0 <verifySpace>
+    7ff4:	f4 df       	rcall	.-24     	; 0x7fde <verifySpace>
 }
-    7fd8:	1f 91       	pop	r17
-    7fda:	08 95       	ret
+    7ff6:	1f 91       	pop	r17
+    7ff8:	08 95       	ret

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex

@@ -1,32 +1,34 @@
 :107E000085E08093810082E08093C00088E18093C8
 :107E1000C10086E08093C20088E08093C40084B7EC
-:107E200014BE81FFC8D08DE0C0D0259A86E028E13D
+:107E200014BE81FFD7D08DE0CFD0259A86E028E11F
 :107E30003EEF91E0309385002093840096BBB09B89
 :107E4000FECF1D9AA8958150A9F7DD24D394A5E013
-:107E5000FA2EF1E1EF2E9CD0813421F481E0B6D0EE
+:107E5000EA2EF1E1FF2EABD0813421F481E0C5D0D0
 :107E600083E020C0823411F484E103C0853419F426
-:107E700085E0ACD082C0853581F48AD0082F10E02F
-:107E800087D090E0982F8827802B912B880F991FFF
-:107E900090930102809300026FC0863529F484E03C
-:107EA00095D080E06DD069C0843609F03FC078D0AD
-:107EB000E0910002F091010283E087BFE895C0E005
-:107EC000D1E066D0899380910202815080930202B2
-:107ED0008823B9F775D007B600FCFDCF40910002AA
-:107EE00050910102A0E0B1E02C9130E011968C910C
-:107EF000119790E0982F8827822B932B1296FA01E6
-:107F00000C01D7BEE89511244E5F5F4FF1E0A03819
-:107F1000BF0751F7E0910002F0910102F7BEE8952A
-:107F200007B600FCFDCFE7BEE89527C08437B9F45B
-:107F300037D046D0E0910002F09101023196F093E3
-:107F40000102E09300023197E4918E2F19D08091C5
-:107F50000202815080930202882361F70EC08537A8
-:107F600039F42ED08EE10CD085E90AD08FE09ACF7B
-:107F7000813511F488E019D023D080E101D06BCF96
-:107F8000982F8091C00085FFFCCF9093C600089584
-:107F9000A8958091C00087FFFCCF8091C60008950E
-:107FA000F7DFF6DF80930202F3CFE0E6F0E098E13E
-:107FB00090838083089580E0F8DFEE27FF270994FF
-:107FC000E7DF803209F0F7DF84E1DACF1F93182F63
-:0C7FD000DFDF1150E9F7F4DF1F91089586
+:107E700085E0BBD091C0853581F499D0082F10E002
+:107E800096D090E0982F8827802B912B880F991FF0
+:107E900090930102809300027EC0863529F484E02D
+:107EA000A4D080E07CD078C0843609F04EC087D062
+:107EB000E0910002F091010280E7E030F80718F449
+:107EC00083E087BFE895C0E0D1E071D089938091CD
+:107ED00002028150809302028823B9F7E0910002E8
+:107EE000F091010280E7E030F80718F083E087BFE7
+:107EF000E89575D007B600FCFDCF40910002509187
+:107F00000102A0E0B1E02C9130E011968C91119724
+:107F100090E0982F8827822B932B1296FA010C0160
+:107F2000D7BEE89511244E5F5F4FF1E0A038BF0740
+:107F300051F7E0910002F0910102E7BEE89507B623
+:107F400000FCFDCFF7BEE89527C08437B9F437D0E1
+:107F500046D0E0910002F09101023196F0930102C7
+:107F6000E09300023197E4918E2F19D080910202A4
+:107F7000815080930202882361F70EC0853739F45F
+:107F80002ED08EE10CD085E90AD08FE08BCF8135E1
+:107F900011F488E019D023D080E101D05CCF982F74
+:107FA0008091C00085FFFCCF9093C6000895A895EE
+:107FB0008091C00087FFFCCF8091C6000895F7DF55
+:107FC000F6DF80930202F3CFE0E6F0E098E19083E1
+:107FD0008083089580E0F8DFEE27FF270994E7DF2C
+:107FE000803209F0F7DF84E1DACF1F93182FDFDF4B
+:0A7FF0001150E9F7F4DF1F91089526
 :0400000300007E007B
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst

@@ -3,25 +3,25 @@ optiboot_atmega328_pro_8MHz.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  00007e00  00007e00  00000054  2**1
+  0 .text         000001fa  00007e00  00007e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     7e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     7e22:	81 ff       	sbrs	r24, 1
-    7e24:	c8 d0       	rcall	.+400    	; 0x7fb6 <appStart>
+    7e24:	d7 d0       	rcall	.+430    	; 0x7fd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     7e26:	8d e0       	ldi	r24, 0x0D	; 13
-    7e28:	c0 d0       	rcall	.+384    	; 0x7faa <watchdogConfig>
+    7e28:	cf d0       	rcall	.+414    	; 0x7fc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     7e4e:	a5 e0       	ldi	r26, 0x05	; 5
-    7e50:	fa 2e       	mov	r15, r26
+    7e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     7e52:	f1 e1       	ldi	r31, 0x11	; 17
-    7e54:	ef 2e       	mov	r14, r31
+    7e54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    7e56:	9c d0       	rcall	.+312    	; 0x7f90 <getch>
+    7e56:	ab d0       	rcall	.+342    	; 0x7fae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     7e58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     7e5c:	81 e0       	ldi	r24, 0x01	; 1
-    7e5e:	b6 d0       	rcall	.+364    	; 0x7fcc <verifySpace+0xc>
+    7e5e:	c5 d0       	rcall	.+394    	; 0x7fea <verifySpace+0xc>
       putch(0x03);
     7e60:	83 e0       	ldi	r24, 0x03	; 3
     7e62:	20 c0       	rjmp	.+64     	; 0x7ea4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     7e70:	85 e0       	ldi	r24, 0x05	; 5
-    7e72:	ac d0       	rcall	.+344    	; 0x7fcc <verifySpace+0xc>
-    7e74:	82 c0       	rjmp	.+260    	; 0x7f7a <main+0x17a>
+    7e72:	bb d0       	rcall	.+374    	; 0x7fea <verifySpace+0xc>
+    7e74:	91 c0       	rjmp	.+290    	; 0x7f98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     7e76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    7e7a:	8a d0       	rcall	.+276    	; 0x7f90 <getch>
+    7e7a:	99 d0       	rcall	.+306    	; 0x7fae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     7e7c:	08 2f       	mov	r16, r24
     7e7e:	10 e0       	ldi	r17, 0x00	; 0
-    7e80:	87 d0       	rcall	.+270    	; 0x7f90 <getch>
+    7e80:	96 d0       	rcall	.+300    	; 0x7fae <getch>
     7e82:	90 e0       	ldi	r25, 0x00	; 0
     7e84:	98 2f       	mov	r25, r24
     7e86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     7e90:	90 93 01 02 	sts	0x0201, r25
     7e94:	80 93 00 02 	sts	0x0200, r24
-    7e98:	6f c0       	rjmp	.+222    	; 0x7f78 <main+0x178>
+    7e98:	7e c0       	rjmp	.+252    	; 0x7f96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     7e9e:	84 e0       	ldi	r24, 0x04	; 4
-    7ea0:	95 d0       	rcall	.+298    	; 0x7fcc <verifySpace+0xc>
+    7ea0:	a4 d0       	rcall	.+328    	; 0x7fea <verifySpace+0xc>
       putch(0x00);
     7ea2:	80 e0       	ldi	r24, 0x00	; 0
-    7ea4:	6d d0       	rcall	.+218    	; 0x7f80 <putch>
-    7ea6:	69 c0       	rjmp	.+210    	; 0x7f7a <main+0x17a>
+    7ea4:	7c d0       	rcall	.+248    	; 0x7f9e <putch>
+    7ea6:	78 c0       	rjmp	.+240    	; 0x7f98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     7ea8:	84 36       	cpi	r24, 0x64	; 100
     7eaa:	09 f0       	breq	.+2      	; 0x7eae <main+0xae>
-    7eac:	3f c0       	rjmp	.+126    	; 0x7f2c <main+0x12c>
+    7eac:	4e c0       	rjmp	.+156    	; 0x7f4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    7eae:	78 d0       	rcall	.+240    	; 0x7fa0 <getLen>
+    7eae:	87 d0       	rcall	.+270    	; 0x7fbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     7eb0:	e0 91 00 02 	lds	r30, 0x0200
     7eb4:	f0 91 01 02 	lds	r31, 0x0201
-    7eb8:	83 e0       	ldi	r24, 0x03	; 3
-    7eba:	87 bf       	out	0x37, r24	; 55
-    7ebc:	e8 95       	spm
-    7ebe:	c0 e0       	ldi	r28, 0x00	; 0
-    7ec0:	d1 e0       	ldi	r29, 0x01	; 1
+    7eb8:	80 e7       	ldi	r24, 0x70	; 112
+    7eba:	e0 30       	cpi	r30, 0x00	; 0
+    7ebc:	f8 07       	cpc	r31, r24
+    7ebe:	18 f4       	brcc	.+6      	; 0x7ec6 <main+0xc6>
+    7ec0:	83 e0       	ldi	r24, 0x03	; 3
+    7ec2:	87 bf       	out	0x37, r24	; 55
+    7ec4:	e8 95       	spm
+    7ec6:	c0 e0       	ldi	r28, 0x00	; 0
+    7ec8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    7ec2:	66 d0       	rcall	.+204    	; 0x7f90 <getch>
-    7ec4:	89 93       	st	Y+, r24
+    7eca:	71 d0       	rcall	.+226    	; 0x7fae <getch>
+    7ecc:	89 93       	st	Y+, r24
       while (--length);
-    7ec6:	80 91 02 02 	lds	r24, 0x0202
-    7eca:	81 50       	subi	r24, 0x01	; 1
-    7ecc:	80 93 02 02 	sts	0x0202, r24
-    7ed0:	88 23       	and	r24, r24
-    7ed2:	b9 f7       	brne	.-18     	; 0x7ec2 <main+0xc2>
+    7ece:	80 91 02 02 	lds	r24, 0x0202
+    7ed2:	81 50       	subi	r24, 0x01	; 1
+    7ed4:	80 93 02 02 	sts	0x0202, r24
+    7ed8:	88 23       	and	r24, r24
+    7eda:	b9 f7       	brne	.-18     	; 0x7eca <main+0xca>
+
+      // 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);
+    7edc:	e0 91 00 02 	lds	r30, 0x0200
+    7ee0:	f0 91 01 02 	lds	r31, 0x0201
+    7ee4:	80 e7       	ldi	r24, 0x70	; 112
+    7ee6:	e0 30       	cpi	r30, 0x00	; 0
+    7ee8:	f8 07       	cpc	r31, r24
+    7eea:	18 f0       	brcs	.+6      	; 0x7ef2 <main+0xf2>
+    7eec:	83 e0       	ldi	r24, 0x03	; 3
+    7eee:	87 bf       	out	0x37, r24	; 55
+    7ef0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    7ed4:	75 d0       	rcall	.+234    	; 0x7fc0 <verifySpace>
+    7ef2:	75 d0       	rcall	.+234    	; 0x7fde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    7ed6:	07 b6       	in	r0, 0x37	; 55
-    7ed8:	00 fc       	sbrc	r0, 0
-    7eda:	fd cf       	rjmp	.-6      	; 0x7ed6 <main+0xd6>
+    7ef4:	07 b6       	in	r0, 0x37	; 55
+    7ef6:	00 fc       	sbrc	r0, 0
+    7ef8:	fd cf       	rjmp	.-6      	; 0x7ef4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    7edc:	40 91 00 02 	lds	r20, 0x0200
-    7ee0:	50 91 01 02 	lds	r21, 0x0201
-    7ee4:	a0 e0       	ldi	r26, 0x00	; 0
-    7ee6:	b1 e0       	ldi	r27, 0x01	; 1
+    7efa:	40 91 00 02 	lds	r20, 0x0200
+    7efe:	50 91 01 02 	lds	r21, 0x0201
+    7f02:	a0 e0       	ldi	r26, 0x00	; 0
+    7f04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    7ee8:	2c 91       	ld	r18, X
-    7eea:	30 e0       	ldi	r19, 0x00	; 0
+    7f06:	2c 91       	ld	r18, X
+    7f08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    7eec:	11 96       	adiw	r26, 0x01	; 1
-    7eee:	8c 91       	ld	r24, X
-    7ef0:	11 97       	sbiw	r26, 0x01	; 1
-    7ef2:	90 e0       	ldi	r25, 0x00	; 0
-    7ef4:	98 2f       	mov	r25, r24
-    7ef6:	88 27       	eor	r24, r24
-    7ef8:	82 2b       	or	r24, r18
-    7efa:	93 2b       	or	r25, r19
+    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))
 #endif
 
 /* main program starts here */
 int main(void) {
-    7efc:	12 96       	adiw	r26, 0x02	; 2
+    7f1a:	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);
-    7efe:	fa 01       	movw	r30, r20
-    7f00:	0c 01       	movw	r0, r24
-    7f02:	d7 be       	out	0x37, r13	; 55
-    7f04:	e8 95       	spm
-    7f06:	11 24       	eor	r1, r1
+    7f1c:	fa 01       	movw	r30, r20
+    7f1e:	0c 01       	movw	r0, r24
+    7f20:	d7 be       	out	0x37, r13	; 55
+    7f22:	e8 95       	spm
+    7f24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    7f08:	4e 5f       	subi	r20, 0xFE	; 254
-    7f0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    7f26:	4e 5f       	subi	r20, 0xFE	; 254
+    7f28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    7f0c:	f1 e0       	ldi	r31, 0x01	; 1
-    7f0e:	a0 38       	cpi	r26, 0x80	; 128
-    7f10:	bf 07       	cpc	r27, r31
-    7f12:	51 f7       	brne	.-44     	; 0x7ee8 <main+0xe8>
+    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>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    7f14:	e0 91 00 02 	lds	r30, 0x0200
-    7f18:	f0 91 01 02 	lds	r31, 0x0201
-    7f1c:	f7 be       	out	0x37, r15	; 55
-    7f1e:	e8 95       	spm
+    7f32:	e0 91 00 02 	lds	r30, 0x0200
+    7f36:	f0 91 01 02 	lds	r31, 0x0201
+    7f3a:	e7 be       	out	0x37, r14	; 55
+    7f3c:	e8 95       	spm
       boot_spm_busy_wait();
-    7f20:	07 b6       	in	r0, 0x37	; 55
-    7f22:	00 fc       	sbrc	r0, 0
-    7f24:	fd cf       	rjmp	.-6      	; 0x7f20 <main+0x120>
+    7f3e:	07 b6       	in	r0, 0x37	; 55
+    7f40:	00 fc       	sbrc	r0, 0
+    7f42:	fd cf       	rjmp	.-6      	; 0x7f3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    7f26:	e7 be       	out	0x37, r14	; 55
-    7f28:	e8 95       	spm
-    7f2a:	27 c0       	rjmp	.+78     	; 0x7f7a <main+0x17a>
+    7f44:	f7 be       	out	0x37, r15	; 55
+    7f46:	e8 95       	spm
+    7f48:	27 c0       	rjmp	.+78     	; 0x7f98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    7f2c:	84 37       	cpi	r24, 0x74	; 116
-    7f2e:	b9 f4       	brne	.+46     	; 0x7f5e <main+0x15e>
+    7f4a:	84 37       	cpi	r24, 0x74	; 116
+    7f4c:	b9 f4       	brne	.+46     	; 0x7f7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    7f30:	37 d0       	rcall	.+110    	; 0x7fa0 <getLen>
+    7f4e:	37 d0       	rcall	.+110    	; 0x7fbe <getLen>
       verifySpace();
-    7f32:	46 d0       	rcall	.+140    	; 0x7fc0 <verifySpace>
+    7f50:	46 d0       	rcall	.+140    	; 0x7fde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    7f34:	e0 91 00 02 	lds	r30, 0x0200
-    7f38:	f0 91 01 02 	lds	r31, 0x0201
-    7f3c:	31 96       	adiw	r30, 0x01	; 1
-    7f3e:	f0 93 01 02 	sts	0x0201, r31
-    7f42:	e0 93 00 02 	sts	0x0200, r30
-    7f46:	31 97       	sbiw	r30, 0x01	; 1
-    7f48:	e4 91       	lpm	r30, Z+
-    7f4a:	8e 2f       	mov	r24, r30
-    7f4c:	19 d0       	rcall	.+50     	; 0x7f80 <putch>
+    7f52:	e0 91 00 02 	lds	r30, 0x0200
+    7f56:	f0 91 01 02 	lds	r31, 0x0201
+    7f5a:	31 96       	adiw	r30, 0x01	; 1
+    7f5c:	f0 93 01 02 	sts	0x0201, r31
+    7f60:	e0 93 00 02 	sts	0x0200, r30
+    7f64:	31 97       	sbiw	r30, 0x01	; 1
+    7f66:	e4 91       	lpm	r30, Z+
+    7f68:	8e 2f       	mov	r24, r30
+    7f6a:	19 d0       	rcall	.+50     	; 0x7f9e <putch>
       while (--length);
-    7f4e:	80 91 02 02 	lds	r24, 0x0202
-    7f52:	81 50       	subi	r24, 0x01	; 1
-    7f54:	80 93 02 02 	sts	0x0202, r24
-    7f58:	88 23       	and	r24, r24
-    7f5a:	61 f7       	brne	.-40     	; 0x7f34 <main+0x134>
-    7f5c:	0e c0       	rjmp	.+28     	; 0x7f7a <main+0x17a>
+    7f6c:	80 91 02 02 	lds	r24, 0x0202
+    7f70:	81 50       	subi	r24, 0x01	; 1
+    7f72:	80 93 02 02 	sts	0x0202, r24
+    7f76:	88 23       	and	r24, r24
+    7f78:	61 f7       	brne	.-40     	; 0x7f52 <main+0x152>
+    7f7a:	0e c0       	rjmp	.+28     	; 0x7f98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    7f5e:	85 37       	cpi	r24, 0x75	; 117
-    7f60:	39 f4       	brne	.+14     	; 0x7f70 <main+0x170>
+    7f7c:	85 37       	cpi	r24, 0x75	; 117
+    7f7e:	39 f4       	brne	.+14     	; 0x7f8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    7f62:	2e d0       	rcall	.+92     	; 0x7fc0 <verifySpace>
+    7f80:	2e d0       	rcall	.+92     	; 0x7fde <verifySpace>
       putch(SIGNATURE_0);
-    7f64:	8e e1       	ldi	r24, 0x1E	; 30
-    7f66:	0c d0       	rcall	.+24     	; 0x7f80 <putch>
+    7f82:	8e e1       	ldi	r24, 0x1E	; 30
+    7f84:	0c d0       	rcall	.+24     	; 0x7f9e <putch>
       putch(SIGNATURE_1);
-    7f68:	85 e9       	ldi	r24, 0x95	; 149
-    7f6a:	0a d0       	rcall	.+20     	; 0x7f80 <putch>
+    7f86:	85 e9       	ldi	r24, 0x95	; 149
+    7f88:	0a d0       	rcall	.+20     	; 0x7f9e <putch>
       putch(SIGNATURE_2);
-    7f6c:	8f e0       	ldi	r24, 0x0F	; 15
-    7f6e:	9a cf       	rjmp	.-204    	; 0x7ea4 <main+0xa4>
+    7f8a:	8f e0       	ldi	r24, 0x0F	; 15
+    7f8c:	8b cf       	rjmp	.-234    	; 0x7ea4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    7f70:	81 35       	cpi	r24, 0x51	; 81
-    7f72:	11 f4       	brne	.+4      	; 0x7f78 <main+0x178>
+    7f8e:	81 35       	cpi	r24, 0x51	; 81
+    7f90:	11 f4       	brne	.+4      	; 0x7f96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    7f74:	88 e0       	ldi	r24, 0x08	; 8
-    7f76:	19 d0       	rcall	.+50     	; 0x7faa <watchdogConfig>
+    7f92:	88 e0       	ldi	r24, 0x08	; 8
+    7f94:	19 d0       	rcall	.+50     	; 0x7fc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    7f78:	23 d0       	rcall	.+70     	; 0x7fc0 <verifySpace>
+    7f96:	23 d0       	rcall	.+70     	; 0x7fde <verifySpace>
     }
     putch(STK_OK);
-    7f7a:	80 e1       	ldi	r24, 0x10	; 16
-    7f7c:	01 d0       	rcall	.+2      	; 0x7f80 <putch>
-    7f7e:	6b cf       	rjmp	.-298    	; 0x7e56 <main+0x56>
+    7f98:	80 e1       	ldi	r24, 0x10	; 16
+    7f9a:	01 d0       	rcall	.+2      	; 0x7f9e <putch>
+    7f9c:	5c cf       	rjmp	.-328    	; 0x7e56 <main+0x56>
 
-00007f80 <putch>:
+00007f9e <putch>:
   }
 }
 
 void putch(char ch) {
-    7f80:	98 2f       	mov	r25, r24
+    7f9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    7f82:	80 91 c0 00 	lds	r24, 0x00C0
-    7f86:	85 ff       	sbrs	r24, 5
-    7f88:	fc cf       	rjmp	.-8      	; 0x7f82 <putch+0x2>
+    7fa0:	80 91 c0 00 	lds	r24, 0x00C0
+    7fa4:	85 ff       	sbrs	r24, 5
+    7fa6:	fc cf       	rjmp	.-8      	; 0x7fa0 <putch+0x2>
   UDR0 = ch;
-    7f8a:	90 93 c6 00 	sts	0x00C6, r25
+    7fa8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    7f8e:	08 95       	ret
+    7fac:	08 95       	ret
 
-00007f90 <getch>:
+00007fae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    7f90:	a8 95       	wdr
+    7fae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    7f92:	80 91 c0 00 	lds	r24, 0x00C0
-    7f96:	87 ff       	sbrs	r24, 7
-    7f98:	fc cf       	rjmp	.-8      	; 0x7f92 <getch+0x2>
+    7fb0:	80 91 c0 00 	lds	r24, 0x00C0
+    7fb4:	87 ff       	sbrs	r24, 7
+    7fb6:	fc cf       	rjmp	.-8      	; 0x7fb0 <getch+0x2>
   ch = UDR0;
-    7f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    7fb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    7f9e:	08 95       	ret
+    7fbc:	08 95       	ret
 
-00007fa0 <getLen>:
+00007fbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    7fa0:	f7 df       	rcall	.-18     	; 0x7f90 <getch>
+    7fbe:	f7 df       	rcall	.-18     	; 0x7fae <getch>
   length = getch();
-    7fa2:	f6 df       	rcall	.-20     	; 0x7f90 <getch>
-    7fa4:	80 93 02 02 	sts	0x0202, r24
+    7fc0:	f6 df       	rcall	.-20     	; 0x7fae <getch>
+    7fc2:	80 93 02 02 	sts	0x0202, r24
   return getch();
 }
-    7fa8:	f3 cf       	rjmp	.-26     	; 0x7f90 <getch>
+    7fc6:	f3 cf       	rjmp	.-26     	; 0x7fae <getch>
 
-00007faa <watchdogConfig>:
+00007fc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7faa:	e0 e6       	ldi	r30, 0x60	; 96
-    7fac:	f0 e0       	ldi	r31, 0x00	; 0
-    7fae:	98 e1       	ldi	r25, 0x18	; 24
-    7fb0:	90 83       	st	Z, r25
+    7fc8:	e0 e6       	ldi	r30, 0x60	; 96
+    7fca:	f0 e0       	ldi	r31, 0x00	; 0
+    7fcc:	98 e1       	ldi	r25, 0x18	; 24
+    7fce:	90 83       	st	Z, r25
   WDTCSR = x;
-    7fb2:	80 83       	st	Z, r24
+    7fd0:	80 83       	st	Z, r24
 }
-    7fb4:	08 95       	ret
+    7fd2:	08 95       	ret
 
-00007fb6 <appStart>:
+00007fd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    7fb6:	80 e0       	ldi	r24, 0x00	; 0
-    7fb8:	f8 df       	rcall	.-16     	; 0x7faa <watchdogConfig>
+    7fd4:	80 e0       	ldi	r24, 0x00	; 0
+    7fd6:	f8 df       	rcall	.-16     	; 0x7fc8 <watchdogConfig>
   __asm__ __volatile__ (
-    7fba:	ee 27       	eor	r30, r30
-    7fbc:	ff 27       	eor	r31, r31
-    7fbe:	09 94       	ijmp
+    7fd8:	ee 27       	eor	r30, r30
+    7fda:	ff 27       	eor	r31, r31
+    7fdc:	09 94       	ijmp
 
-00007fc0 <verifySpace>:
+00007fde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    7fc0:	e7 df       	rcall	.-50     	; 0x7f90 <getch>
-    7fc2:	80 32       	cpi	r24, 0x20	; 32
-    7fc4:	09 f0       	breq	.+2      	; 0x7fc8 <verifySpace+0x8>
-    7fc6:	f7 df       	rcall	.-18     	; 0x7fb6 <appStart>
+    7fde:	e7 df       	rcall	.-50     	; 0x7fae <getch>
+    7fe0:	80 32       	cpi	r24, 0x20	; 32
+    7fe2:	09 f0       	breq	.+2      	; 0x7fe6 <verifySpace+0x8>
+    7fe4:	f7 df       	rcall	.-18     	; 0x7fd4 <appStart>
   putch(STK_INSYNC);
-    7fc8:	84 e1       	ldi	r24, 0x14	; 20
+    7fe6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    7fca:	da cf       	rjmp	.-76     	; 0x7f80 <putch>
+    7fe8:	da cf       	rjmp	.-76     	; 0x7f9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    7fcc:	1f 93       	push	r17
-    7fce:	18 2f       	mov	r17, r24
+    7fea:	1f 93       	push	r17
+    7fec:	18 2f       	mov	r17, r24
 
-00007fd0 <getNch>:
+00007fee <getNch>:
   do getch(); while (--count);
-    7fd0:	df df       	rcall	.-66     	; 0x7f90 <getch>
-    7fd2:	11 50       	subi	r17, 0x01	; 1
-    7fd4:	e9 f7       	brne	.-6      	; 0x7fd0 <getNch>
+    7fee:	df df       	rcall	.-66     	; 0x7fae <getch>
+    7ff0:	11 50       	subi	r17, 0x01	; 1
+    7ff2:	e9 f7       	brne	.-6      	; 0x7fee <getNch>
   verifySpace();
-    7fd6:	f4 df       	rcall	.-24     	; 0x7fc0 <verifySpace>
+    7ff4:	f4 df       	rcall	.-24     	; 0x7fde <verifySpace>
 }
-    7fd8:	1f 91       	pop	r17
-    7fda:	08 95       	ret
+    7ff6:	1f 91       	pop	r17
+    7ff8:	08 95       	ret

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_atmega644p.hex

@@ -1,32 +1,34 @@
 :10FC000085E08093810082E08093C00088E180934A
 :10FC1000C10086E08093C20080E18093C40084B775
-:10FC200014BE81FFC8D08DE0C0D0209A86E020E3CA
+:10FC200014BE81FFD7D08DE0CFD0209A86E020E3AC
 :10FC30003CEF91E0309385002093840096BBB09B0D
 :10FC4000FECF189AA8958150A9F7DD24D394A5E09A
-:10FC5000FA2EF1E1EF2E9CD0813421F481E0B6D070
+:10FC5000EA2EF1E1FF2EABD0813421F481E0C5D052
 :10FC600083E020C0823411F484E103C0853419F4A8
-:10FC700085E0ACD082C0853581F48AD0082F10E0B1
-:10FC800087D090E0982F8827802B912B880F991F81
-:10FC900090930103809300036FC0863529F484E0BC
-:10FCA00095D080E06DD069C0843609F03FC078D02F
-:10FCB000E0910003F091010383E087BFE895C0E085
-:10FCC000D1E066D089938091020381508093020332
-:10FCD0008823B9F775D007B600FCFDCF409100032B
-:10FCE00050910103A0E0B1E02C9130E011968C918D
-:10FCF000119790E0982F8827822B932B1296FA0168
-:10FD00000C01D7BEE89511244E5F5F4FF2E0A030A2
-:10FD1000BF0751F7E0910003F0910103F7BEE895AA
-:10FD200007B600FCFDCFE7BEE89527C08437B9F4DD
-:10FD300037D046D0E0910003F09101033196F09363
-:10FD40000103E09300033197E4918E2F19D0809145
-:10FD50000203815080930203882361F70EC0853728
-:10FD600039F42ED08EE10CD086E90AD08AE09ACF01
-:10FD7000813511F488E019D023D080E101D06BCF18
-:10FD8000982F8091C00085FFFCCF9093C600089506
-:10FD9000A8958091C00087FFFCCF8091C600089590
-:10FDA000F7DFF6DF80930203F3CFE0E6F0E098E1BF
-:10FDB00090838083089580E0F8DFEE27FF27099481
-:10FDC000E7DF803209F0F7DF84E1DACF1F93182FE5
-:0CFDD000DFDF1150E9F7F4DF1F91089508
+:10FC700085E0BBD091C0853581F499D0082F10E084
+:10FC800096D090E0982F8827802B912B880F991F72
+:10FC900090930103809300037EC0863529F484E0AD
+:10FCA000A4D080E07CD078C0843609F04EC087D0E4
+:10FCB000E0910003F091010380EEE030F80718F4C2
+:10FCC00083E087BFE895C0E0D1E071D0899380914F
+:10FCD00002038150809302038823B9F7E091000367
+:10FCE000F091010380EEE030F80718F083E087BF61
+:10FCF000E89575D007B600FCFDCF40910003509108
+:10FD00000103A0E0B1E02C9130E011968C911197A5
+:10FD100090E0982F8827822B932B1296FA010C01E2
+:10FD2000D7BEE89511244E5F5F4FF2E0A030BF07C9
+:10FD300051F7E0910003F0910103E7BEE89507B6A3
+:10FD400000FCFDCFF7BEE89527C08437B9F437D063
+:10FD500046D0E0910003F09101033196F093010346
+:10FD6000E09300033197E4918E2F19D08091020324
+:10FD7000815080930203882361F70EC0853739F4E0
+:10FD80002ED08EE10CD086E90AD08AE08BCF813567
+:10FD900011F488E019D023D080E101D05CCF982FF6
+:10FDA0008091C00085FFFCCF9093C6000895A89570
+:10FDB0008091C00087FFFCCF8091C6000895F7DFD7
+:10FDC000F6DF80930203F3CFE0E6F0E098E1908362
+:10FDD0008083089580E0F8DFEE27FF270994E7DFAE
+:10FDE000803209F0F7DF84E1DACF1F93182FDFDFCD
+:0AFDF0001150E9F7F4DF1F910895A8
 :040000030000FC00FD
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_atmega644p.lst

@@ -3,25 +3,25 @@ optiboot_atmega644p.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  0000fc00  0000fc00  00000054  2**1
+  0 .text         000001fa  0000fc00  0000fc00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     fc20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     fc22:	81 ff       	sbrs	r24, 1
-    fc24:	c8 d0       	rcall	.+400    	; 0xfdb6 <appStart>
+    fc24:	d7 d0       	rcall	.+430    	; 0xfdd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     fc26:	8d e0       	ldi	r24, 0x0D	; 13
-    fc28:	c0 d0       	rcall	.+384    	; 0xfdaa <watchdogConfig>
+    fc28:	cf d0       	rcall	.+414    	; 0xfdc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     fc4e:	a5 e0       	ldi	r26, 0x05	; 5
-    fc50:	fa 2e       	mov	r15, r26
+    fc50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     fc52:	f1 e1       	ldi	r31, 0x11	; 17
-    fc54:	ef 2e       	mov	r14, r31
+    fc54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    fc56:	9c d0       	rcall	.+312    	; 0xfd90 <getch>
+    fc56:	ab d0       	rcall	.+342    	; 0xfdae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     fc58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     fc5c:	81 e0       	ldi	r24, 0x01	; 1
-    fc5e:	b6 d0       	rcall	.+364    	; 0xfdcc <verifySpace+0xc>
+    fc5e:	c5 d0       	rcall	.+394    	; 0xfdea <verifySpace+0xc>
       putch(0x03);
     fc60:	83 e0       	ldi	r24, 0x03	; 3
     fc62:	20 c0       	rjmp	.+64     	; 0xfca4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     fc70:	85 e0       	ldi	r24, 0x05	; 5
-    fc72:	ac d0       	rcall	.+344    	; 0xfdcc <verifySpace+0xc>
-    fc74:	82 c0       	rjmp	.+260    	; 0xfd7a <main+0x17a>
+    fc72:	bb d0       	rcall	.+374    	; 0xfdea <verifySpace+0xc>
+    fc74:	91 c0       	rjmp	.+290    	; 0xfd98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     fc76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    fc7a:	8a d0       	rcall	.+276    	; 0xfd90 <getch>
+    fc7a:	99 d0       	rcall	.+306    	; 0xfdae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     fc7c:	08 2f       	mov	r16, r24
     fc7e:	10 e0       	ldi	r17, 0x00	; 0
-    fc80:	87 d0       	rcall	.+270    	; 0xfd90 <getch>
+    fc80:	96 d0       	rcall	.+300    	; 0xfdae <getch>
     fc82:	90 e0       	ldi	r25, 0x00	; 0
     fc84:	98 2f       	mov	r25, r24
     fc86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     fc90:	90 93 01 03 	sts	0x0301, r25
     fc94:	80 93 00 03 	sts	0x0300, r24
-    fc98:	6f c0       	rjmp	.+222    	; 0xfd78 <main+0x178>
+    fc98:	7e c0       	rjmp	.+252    	; 0xfd96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     fc9e:	84 e0       	ldi	r24, 0x04	; 4
-    fca0:	95 d0       	rcall	.+298    	; 0xfdcc <verifySpace+0xc>
+    fca0:	a4 d0       	rcall	.+328    	; 0xfdea <verifySpace+0xc>
       putch(0x00);
     fca2:	80 e0       	ldi	r24, 0x00	; 0
-    fca4:	6d d0       	rcall	.+218    	; 0xfd80 <putch>
-    fca6:	69 c0       	rjmp	.+210    	; 0xfd7a <main+0x17a>
+    fca4:	7c d0       	rcall	.+248    	; 0xfd9e <putch>
+    fca6:	78 c0       	rjmp	.+240    	; 0xfd98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     fca8:	84 36       	cpi	r24, 0x64	; 100
     fcaa:	09 f0       	breq	.+2      	; 0xfcae <main+0xae>
-    fcac:	3f c0       	rjmp	.+126    	; 0xfd2c <main+0x12c>
+    fcac:	4e c0       	rjmp	.+156    	; 0xfd4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    fcae:	78 d0       	rcall	.+240    	; 0xfda0 <getLen>
+    fcae:	87 d0       	rcall	.+270    	; 0xfdbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     fcb0:	e0 91 00 03 	lds	r30, 0x0300
     fcb4:	f0 91 01 03 	lds	r31, 0x0301
-    fcb8:	83 e0       	ldi	r24, 0x03	; 3
-    fcba:	87 bf       	out	0x37, r24	; 55
-    fcbc:	e8 95       	spm
-    fcbe:	c0 e0       	ldi	r28, 0x00	; 0
-    fcc0:	d1 e0       	ldi	r29, 0x01	; 1
+    fcb8:	80 ee       	ldi	r24, 0xE0	; 224
+    fcba:	e0 30       	cpi	r30, 0x00	; 0
+    fcbc:	f8 07       	cpc	r31, r24
+    fcbe:	18 f4       	brcc	.+6      	; 0xfcc6 <main+0xc6>
+    fcc0:	83 e0       	ldi	r24, 0x03	; 3
+    fcc2:	87 bf       	out	0x37, r24	; 55
+    fcc4:	e8 95       	spm
+    fcc6:	c0 e0       	ldi	r28, 0x00	; 0
+    fcc8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    fcc2:	66 d0       	rcall	.+204    	; 0xfd90 <getch>
-    fcc4:	89 93       	st	Y+, r24
+    fcca:	71 d0       	rcall	.+226    	; 0xfdae <getch>
+    fccc:	89 93       	st	Y+, r24
       while (--length);
-    fcc6:	80 91 02 03 	lds	r24, 0x0302
-    fcca:	81 50       	subi	r24, 0x01	; 1
-    fccc:	80 93 02 03 	sts	0x0302, r24
-    fcd0:	88 23       	and	r24, r24
-    fcd2:	b9 f7       	brne	.-18     	; 0xfcc2 <main+0xc2>
+    fcce:	80 91 02 03 	lds	r24, 0x0302
+    fcd2:	81 50       	subi	r24, 0x01	; 1
+    fcd4:	80 93 02 03 	sts	0x0302, r24
+    fcd8:	88 23       	and	r24, r24
+    fcda:	b9 f7       	brne	.-18     	; 0xfcca <main+0xca>
+
+      // 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);
+    fcdc:	e0 91 00 03 	lds	r30, 0x0300
+    fce0:	f0 91 01 03 	lds	r31, 0x0301
+    fce4:	80 ee       	ldi	r24, 0xE0	; 224
+    fce6:	e0 30       	cpi	r30, 0x00	; 0
+    fce8:	f8 07       	cpc	r31, r24
+    fcea:	18 f0       	brcs	.+6      	; 0xfcf2 <main+0xf2>
+    fcec:	83 e0       	ldi	r24, 0x03	; 3
+    fcee:	87 bf       	out	0x37, r24	; 55
+    fcf0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    fcd4:	75 d0       	rcall	.+234    	; 0xfdc0 <verifySpace>
+    fcf2:	75 d0       	rcall	.+234    	; 0xfdde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    fcd6:	07 b6       	in	r0, 0x37	; 55
-    fcd8:	00 fc       	sbrc	r0, 0
-    fcda:	fd cf       	rjmp	.-6      	; 0xfcd6 <main+0xd6>
+    fcf4:	07 b6       	in	r0, 0x37	; 55
+    fcf6:	00 fc       	sbrc	r0, 0
+    fcf8:	fd cf       	rjmp	.-6      	; 0xfcf4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    fcdc:	40 91 00 03 	lds	r20, 0x0300
-    fce0:	50 91 01 03 	lds	r21, 0x0301
-    fce4:	a0 e0       	ldi	r26, 0x00	; 0
-    fce6:	b1 e0       	ldi	r27, 0x01	; 1
+    fcfa:	40 91 00 03 	lds	r20, 0x0300
+    fcfe:	50 91 01 03 	lds	r21, 0x0301
+    fd02:	a0 e0       	ldi	r26, 0x00	; 0
+    fd04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    fce8:	2c 91       	ld	r18, X
-    fcea:	30 e0       	ldi	r19, 0x00	; 0
+    fd06:	2c 91       	ld	r18, X
+    fd08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    fcec:	11 96       	adiw	r26, 0x01	; 1
-    fcee:	8c 91       	ld	r24, X
-    fcf0:	11 97       	sbiw	r26, 0x01	; 1
-    fcf2:	90 e0       	ldi	r25, 0x00	; 0
-    fcf4:	98 2f       	mov	r25, r24
-    fcf6:	88 27       	eor	r24, r24
-    fcf8:	82 2b       	or	r24, r18
-    fcfa:	93 2b       	or	r25, r19
+    fd0a:	11 96       	adiw	r26, 0x01	; 1
+    fd0c:	8c 91       	ld	r24, X
+    fd0e:	11 97       	sbiw	r26, 0x01	; 1
+    fd10:	90 e0       	ldi	r25, 0x00	; 0
+    fd12:	98 2f       	mov	r25, r24
+    fd14:	88 27       	eor	r24, r24
+    fd16:	82 2b       	or	r24, r18
+    fd18:	93 2b       	or	r25, r19
 #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) {
-    fcfc:	12 96       	adiw	r26, 0x02	; 2
+    fd1a:	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);
-    fcfe:	fa 01       	movw	r30, r20
-    fd00:	0c 01       	movw	r0, r24
-    fd02:	d7 be       	out	0x37, r13	; 55
-    fd04:	e8 95       	spm
-    fd06:	11 24       	eor	r1, r1
+    fd1c:	fa 01       	movw	r30, r20
+    fd1e:	0c 01       	movw	r0, r24
+    fd20:	d7 be       	out	0x37, r13	; 55
+    fd22:	e8 95       	spm
+    fd24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    fd08:	4e 5f       	subi	r20, 0xFE	; 254
-    fd0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    fd26:	4e 5f       	subi	r20, 0xFE	; 254
+    fd28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    fd0c:	f2 e0       	ldi	r31, 0x02	; 2
-    fd0e:	a0 30       	cpi	r26, 0x00	; 0
-    fd10:	bf 07       	cpc	r27, r31
-    fd12:	51 f7       	brne	.-44     	; 0xfce8 <main+0xe8>
+    fd2a:	f2 e0       	ldi	r31, 0x02	; 2
+    fd2c:	a0 30       	cpi	r26, 0x00	; 0
+    fd2e:	bf 07       	cpc	r27, r31
+    fd30:	51 f7       	brne	.-44     	; 0xfd06 <main+0x106>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    fd14:	e0 91 00 03 	lds	r30, 0x0300
-    fd18:	f0 91 01 03 	lds	r31, 0x0301
-    fd1c:	f7 be       	out	0x37, r15	; 55
-    fd1e:	e8 95       	spm
+    fd32:	e0 91 00 03 	lds	r30, 0x0300
+    fd36:	f0 91 01 03 	lds	r31, 0x0301
+    fd3a:	e7 be       	out	0x37, r14	; 55
+    fd3c:	e8 95       	spm
       boot_spm_busy_wait();
-    fd20:	07 b6       	in	r0, 0x37	; 55
-    fd22:	00 fc       	sbrc	r0, 0
-    fd24:	fd cf       	rjmp	.-6      	; 0xfd20 <main+0x120>
+    fd3e:	07 b6       	in	r0, 0x37	; 55
+    fd40:	00 fc       	sbrc	r0, 0
+    fd42:	fd cf       	rjmp	.-6      	; 0xfd3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    fd26:	e7 be       	out	0x37, r14	; 55
-    fd28:	e8 95       	spm
-    fd2a:	27 c0       	rjmp	.+78     	; 0xfd7a <main+0x17a>
+    fd44:	f7 be       	out	0x37, r15	; 55
+    fd46:	e8 95       	spm
+    fd48:	27 c0       	rjmp	.+78     	; 0xfd98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    fd2c:	84 37       	cpi	r24, 0x74	; 116
-    fd2e:	b9 f4       	brne	.+46     	; 0xfd5e <main+0x15e>
+    fd4a:	84 37       	cpi	r24, 0x74	; 116
+    fd4c:	b9 f4       	brne	.+46     	; 0xfd7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    fd30:	37 d0       	rcall	.+110    	; 0xfda0 <getLen>
+    fd4e:	37 d0       	rcall	.+110    	; 0xfdbe <getLen>
       verifySpace();
-    fd32:	46 d0       	rcall	.+140    	; 0xfdc0 <verifySpace>
+    fd50:	46 d0       	rcall	.+140    	; 0xfdde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    fd34:	e0 91 00 03 	lds	r30, 0x0300
-    fd38:	f0 91 01 03 	lds	r31, 0x0301
-    fd3c:	31 96       	adiw	r30, 0x01	; 1
-    fd3e:	f0 93 01 03 	sts	0x0301, r31
-    fd42:	e0 93 00 03 	sts	0x0300, r30
-    fd46:	31 97       	sbiw	r30, 0x01	; 1
-    fd48:	e4 91       	lpm	r30, Z+
-    fd4a:	8e 2f       	mov	r24, r30
-    fd4c:	19 d0       	rcall	.+50     	; 0xfd80 <putch>
+    fd52:	e0 91 00 03 	lds	r30, 0x0300
+    fd56:	f0 91 01 03 	lds	r31, 0x0301
+    fd5a:	31 96       	adiw	r30, 0x01	; 1
+    fd5c:	f0 93 01 03 	sts	0x0301, r31
+    fd60:	e0 93 00 03 	sts	0x0300, r30
+    fd64:	31 97       	sbiw	r30, 0x01	; 1
+    fd66:	e4 91       	lpm	r30, Z+
+    fd68:	8e 2f       	mov	r24, r30
+    fd6a:	19 d0       	rcall	.+50     	; 0xfd9e <putch>
       while (--length);
-    fd4e:	80 91 02 03 	lds	r24, 0x0302
-    fd52:	81 50       	subi	r24, 0x01	; 1
-    fd54:	80 93 02 03 	sts	0x0302, r24
-    fd58:	88 23       	and	r24, r24
-    fd5a:	61 f7       	brne	.-40     	; 0xfd34 <main+0x134>
-    fd5c:	0e c0       	rjmp	.+28     	; 0xfd7a <main+0x17a>
+    fd6c:	80 91 02 03 	lds	r24, 0x0302
+    fd70:	81 50       	subi	r24, 0x01	; 1
+    fd72:	80 93 02 03 	sts	0x0302, r24
+    fd76:	88 23       	and	r24, r24
+    fd78:	61 f7       	brne	.-40     	; 0xfd52 <main+0x152>
+    fd7a:	0e c0       	rjmp	.+28     	; 0xfd98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    fd5e:	85 37       	cpi	r24, 0x75	; 117
-    fd60:	39 f4       	brne	.+14     	; 0xfd70 <main+0x170>
+    fd7c:	85 37       	cpi	r24, 0x75	; 117
+    fd7e:	39 f4       	brne	.+14     	; 0xfd8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    fd62:	2e d0       	rcall	.+92     	; 0xfdc0 <verifySpace>
+    fd80:	2e d0       	rcall	.+92     	; 0xfdde <verifySpace>
       putch(SIGNATURE_0);
-    fd64:	8e e1       	ldi	r24, 0x1E	; 30
-    fd66:	0c d0       	rcall	.+24     	; 0xfd80 <putch>
+    fd82:	8e e1       	ldi	r24, 0x1E	; 30
+    fd84:	0c d0       	rcall	.+24     	; 0xfd9e <putch>
       putch(SIGNATURE_1);
-    fd68:	86 e9       	ldi	r24, 0x96	; 150
-    fd6a:	0a d0       	rcall	.+20     	; 0xfd80 <putch>
+    fd86:	86 e9       	ldi	r24, 0x96	; 150
+    fd88:	0a d0       	rcall	.+20     	; 0xfd9e <putch>
       putch(SIGNATURE_2);
-    fd6c:	8a e0       	ldi	r24, 0x0A	; 10
-    fd6e:	9a cf       	rjmp	.-204    	; 0xfca4 <main+0xa4>
+    fd8a:	8a e0       	ldi	r24, 0x0A	; 10
+    fd8c:	8b cf       	rjmp	.-234    	; 0xfca4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    fd70:	81 35       	cpi	r24, 0x51	; 81
-    fd72:	11 f4       	brne	.+4      	; 0xfd78 <main+0x178>
+    fd8e:	81 35       	cpi	r24, 0x51	; 81
+    fd90:	11 f4       	brne	.+4      	; 0xfd96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    fd74:	88 e0       	ldi	r24, 0x08	; 8
-    fd76:	19 d0       	rcall	.+50     	; 0xfdaa <watchdogConfig>
+    fd92:	88 e0       	ldi	r24, 0x08	; 8
+    fd94:	19 d0       	rcall	.+50     	; 0xfdc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    fd78:	23 d0       	rcall	.+70     	; 0xfdc0 <verifySpace>
+    fd96:	23 d0       	rcall	.+70     	; 0xfdde <verifySpace>
     }
     putch(STK_OK);
-    fd7a:	80 e1       	ldi	r24, 0x10	; 16
-    fd7c:	01 d0       	rcall	.+2      	; 0xfd80 <putch>
-    fd7e:	6b cf       	rjmp	.-298    	; 0xfc56 <main+0x56>
+    fd98:	80 e1       	ldi	r24, 0x10	; 16
+    fd9a:	01 d0       	rcall	.+2      	; 0xfd9e <putch>
+    fd9c:	5c cf       	rjmp	.-328    	; 0xfc56 <main+0x56>
 
-0000fd80 <putch>:
+0000fd9e <putch>:
   }
 }
 
 void putch(char ch) {
-    fd80:	98 2f       	mov	r25, r24
+    fd9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    fd82:	80 91 c0 00 	lds	r24, 0x00C0
-    fd86:	85 ff       	sbrs	r24, 5
-    fd88:	fc cf       	rjmp	.-8      	; 0xfd82 <putch+0x2>
+    fda0:	80 91 c0 00 	lds	r24, 0x00C0
+    fda4:	85 ff       	sbrs	r24, 5
+    fda6:	fc cf       	rjmp	.-8      	; 0xfda0 <putch+0x2>
   UDR0 = ch;
-    fd8a:	90 93 c6 00 	sts	0x00C6, r25
+    fda8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    fd8e:	08 95       	ret
+    fdac:	08 95       	ret
 
-0000fd90 <getch>:
+0000fdae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    fd90:	a8 95       	wdr
+    fdae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    fd92:	80 91 c0 00 	lds	r24, 0x00C0
-    fd96:	87 ff       	sbrs	r24, 7
-    fd98:	fc cf       	rjmp	.-8      	; 0xfd92 <getch+0x2>
+    fdb0:	80 91 c0 00 	lds	r24, 0x00C0
+    fdb4:	87 ff       	sbrs	r24, 7
+    fdb6:	fc cf       	rjmp	.-8      	; 0xfdb0 <getch+0x2>
   ch = UDR0;
-    fd9a:	80 91 c6 00 	lds	r24, 0x00C6
+    fdb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    fd9e:	08 95       	ret
+    fdbc:	08 95       	ret
 
-0000fda0 <getLen>:
+0000fdbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    fda0:	f7 df       	rcall	.-18     	; 0xfd90 <getch>
+    fdbe:	f7 df       	rcall	.-18     	; 0xfdae <getch>
   length = getch();
-    fda2:	f6 df       	rcall	.-20     	; 0xfd90 <getch>
-    fda4:	80 93 02 03 	sts	0x0302, r24
+    fdc0:	f6 df       	rcall	.-20     	; 0xfdae <getch>
+    fdc2:	80 93 02 03 	sts	0x0302, r24
   return getch();
 }
-    fda8:	f3 cf       	rjmp	.-26     	; 0xfd90 <getch>
+    fdc6:	f3 cf       	rjmp	.-26     	; 0xfdae <getch>
 
-0000fdaa <watchdogConfig>:
+0000fdc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    fdaa:	e0 e6       	ldi	r30, 0x60	; 96
-    fdac:	f0 e0       	ldi	r31, 0x00	; 0
-    fdae:	98 e1       	ldi	r25, 0x18	; 24
-    fdb0:	90 83       	st	Z, r25
+    fdc8:	e0 e6       	ldi	r30, 0x60	; 96
+    fdca:	f0 e0       	ldi	r31, 0x00	; 0
+    fdcc:	98 e1       	ldi	r25, 0x18	; 24
+    fdce:	90 83       	st	Z, r25
   WDTCSR = x;
-    fdb2:	80 83       	st	Z, r24
+    fdd0:	80 83       	st	Z, r24
 }
-    fdb4:	08 95       	ret
+    fdd2:	08 95       	ret
 
-0000fdb6 <appStart>:
+0000fdd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    fdb6:	80 e0       	ldi	r24, 0x00	; 0
-    fdb8:	f8 df       	rcall	.-16     	; 0xfdaa <watchdogConfig>
+    fdd4:	80 e0       	ldi	r24, 0x00	; 0
+    fdd6:	f8 df       	rcall	.-16     	; 0xfdc8 <watchdogConfig>
   __asm__ __volatile__ (
-    fdba:	ee 27       	eor	r30, r30
-    fdbc:	ff 27       	eor	r31, r31
-    fdbe:	09 94       	ijmp
+    fdd8:	ee 27       	eor	r30, r30
+    fdda:	ff 27       	eor	r31, r31
+    fddc:	09 94       	ijmp
 
-0000fdc0 <verifySpace>:
+0000fdde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    fdc0:	e7 df       	rcall	.-50     	; 0xfd90 <getch>
-    fdc2:	80 32       	cpi	r24, 0x20	; 32
-    fdc4:	09 f0       	breq	.+2      	; 0xfdc8 <verifySpace+0x8>
-    fdc6:	f7 df       	rcall	.-18     	; 0xfdb6 <appStart>
+    fdde:	e7 df       	rcall	.-50     	; 0xfdae <getch>
+    fde0:	80 32       	cpi	r24, 0x20	; 32
+    fde2:	09 f0       	breq	.+2      	; 0xfde6 <verifySpace+0x8>
+    fde4:	f7 df       	rcall	.-18     	; 0xfdd4 <appStart>
   putch(STK_INSYNC);
-    fdc8:	84 e1       	ldi	r24, 0x14	; 20
+    fde6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    fdca:	da cf       	rjmp	.-76     	; 0xfd80 <putch>
+    fde8:	da cf       	rjmp	.-76     	; 0xfd9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    fdcc:	1f 93       	push	r17
-    fdce:	18 2f       	mov	r17, r24
+    fdea:	1f 93       	push	r17
+    fdec:	18 2f       	mov	r17, r24
 
-0000fdd0 <getNch>:
+0000fdee <getNch>:
   do getch(); while (--count);
-    fdd0:	df df       	rcall	.-66     	; 0xfd90 <getch>
-    fdd2:	11 50       	subi	r17, 0x01	; 1
-    fdd4:	e9 f7       	brne	.-6      	; 0xfdd0 <getNch>
+    fdee:	df df       	rcall	.-66     	; 0xfdae <getch>
+    fdf0:	11 50       	subi	r17, 0x01	; 1
+    fdf2:	e9 f7       	brne	.-6      	; 0xfdee <getNch>
   verifySpace();
-    fdd6:	f4 df       	rcall	.-24     	; 0xfdc0 <verifySpace>
+    fdf4:	f4 df       	rcall	.-24     	; 0xfdde <verifySpace>
 }
-    fdd8:	1f 91       	pop	r17
-    fdda:	08 95       	ret
+    fdf6:	1f 91       	pop	r17
+    fdf8:	08 95       	ret

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_diecimila.hex

@@ -1,32 +1,34 @@
 :103E000085E08093810082E08093C00088E1809308
 :103E1000C10086E08093C20080E18093C40084B733
-:103E200014BE81FFC8D08DE0C0D0259A86E020E383
+:103E200014BE81FFD7D08DE0CFD0259A86E020E365
 :103E30003CEF91E0309385002093840096BBB09BCB
 :103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000FA2EF1E1EF2E9CD0813421F481E0B6D02E
+:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010
 :103E600083E020C0823411F484E103C0853419F466
-:103E700085E0ACD082C0853581F48AD0082F10E06F
-:103E800087D090E0982F8827802B912B880F991F3F
-:103E900090930102809300026FC0863529F484E07C
-:103EA00095D080E06DD069C0843609F03FC078D0ED
-:103EB000E0910002F091010283E087BFE895C0E045
-:103EC000D1E066D0899380910202815080930202F2
-:103ED0008823B9F775D007B600FCFDCF40910002EA
-:103EE00050910102A0E0B1E02C9130E011968C914C
-:103EF000119790E0982F8827822B932B1296FA0126
-:103F00000C01D7BEE89511244E5F5F4FF1E0A03859
-:103F1000BF0751F7E0910002F0910102F7BEE8956A
-:103F200007B600FCFDCFE7BEE89527C08437B9F49B
-:103F300037D046D0E0910002F09101023196F09323
-:103F40000102E09300023197E4918E2F19D0809105
-:103F50000202815080930202882361F70EC08537E8
-:103F600039F42ED08EE10CD084E90AD086E09ACFC5
-:103F7000813511F488E019D023D080E101D06BCFD6
-:103F8000982F8091C00085FFFCCF9093C6000895C4
-:103F9000A8958091C00087FFFCCF8091C60008954E
-:103FA000F7DFF6DF80930202F3CFE0E6F0E098E17E
-:103FB00090838083089580E0F8DFEE27FF2709943F
-:103FC000E7DF803209F0F7DF84E1DACF1F93182FA3
-:0C3FD000DFDF1150E9F7F4DF1F910895C6
+:103E700085E0BBD091C0853581F499D0082F10E042
+:103E800096D090E0982F8827802B912B880F991F30
+:103E900090930102809300027EC0863529F484E06D
+:103EA000A4D080E07CD078C0843609F04EC087D0A2
+:103EB000E0910002F091010288E3E030F80718F485
+:103EC00083E087BFE895C0E0D1E071D0899380910D
+:103ED00002028150809302028823B9F7E091000228
+:103EE000F091010288E3E030F80718F083E087BF23
+:103EF000E89575D007B600FCFDCF409100025091C7
+:103F00000102A0E0B1E02C9130E011968C91119764
+:103F100090E0982F8827822B932B1296FA010C01A0
+:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780
+:103F300051F7E0910002F0910102E7BEE89507B663
+:103F400000FCFDCFF7BEE89527C08437B9F437D021
+:103F500046D0E0910002F09101023196F093010207
+:103F6000E09300023197E4918E2F19D080910202E4
+:103F7000815080930202882361F70EC0853739F49F
+:103F80002ED08EE10CD084E90AD086E08BCF81352B
+:103F900011F488E019D023D080E101D05CCF982FB4
+:103FA0008091C00085FFFCCF9093C6000895A8952E
+:103FB0008091C00087FFFCCF8091C6000895F7DF95
+:103FC000F6DF80930202F3CFE0E6F0E098E1908321
+:103FD0008083089580E0F8DFEE27FF270994E7DF6C
+:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B
+:0A3FF0001150E9F7F4DF1F91089566
 :0400000300003E00BB
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_diecimila.lst

@@ -3,25 +3,25 @@ optiboot_diecimila.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  00003e00  00003e00  00000054  2**1
+  0 .text         000001fa  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e22:	81 ff       	sbrs	r24, 1
-    3e24:	c8 d0       	rcall	.+400    	; 0x3fb6 <appStart>
+    3e24:	d7 d0       	rcall	.+430    	; 0x3fd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     3e26:	8d e0       	ldi	r24, 0x0D	; 13
-    3e28:	c0 d0       	rcall	.+384    	; 0x3faa <watchdogConfig>
+    3e28:	cf d0       	rcall	.+414    	; 0x3fc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e4e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e50:	fa 2e       	mov	r15, r26
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e52:	f1 e1       	ldi	r31, 0x11	; 17
-    3e54:	ef 2e       	mov	r14, r31
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e56:	9c d0       	rcall	.+312    	; 0x3f90 <getch>
+    3e56:	ab d0       	rcall	.+342    	; 0x3fae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     3e5c:	81 e0       	ldi	r24, 0x01	; 1
-    3e5e:	b6 d0       	rcall	.+364    	; 0x3fcc <verifySpace+0xc>
+    3e5e:	c5 d0       	rcall	.+394    	; 0x3fea <verifySpace+0xc>
       putch(0x03);
     3e60:	83 e0       	ldi	r24, 0x03	; 3
     3e62:	20 c0       	rjmp	.+64     	; 0x3ea4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e70:	85 e0       	ldi	r24, 0x05	; 5
-    3e72:	ac d0       	rcall	.+344    	; 0x3fcc <verifySpace+0xc>
-    3e74:	82 c0       	rjmp	.+260    	; 0x3f7a <main+0x17a>
+    3e72:	bb d0       	rcall	.+374    	; 0x3fea <verifySpace+0xc>
+    3e74:	91 c0       	rjmp	.+290    	; 0x3f98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e7a:	8a d0       	rcall	.+276    	; 0x3f90 <getch>
+    3e7a:	99 d0       	rcall	.+306    	; 0x3fae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e7c:	08 2f       	mov	r16, r24
     3e7e:	10 e0       	ldi	r17, 0x00	; 0
-    3e80:	87 d0       	rcall	.+270    	; 0x3f90 <getch>
+    3e80:	96 d0       	rcall	.+300    	; 0x3fae <getch>
     3e82:	90 e0       	ldi	r25, 0x00	; 0
     3e84:	98 2f       	mov	r25, r24
     3e86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     3e90:	90 93 01 02 	sts	0x0201, r25
     3e94:	80 93 00 02 	sts	0x0200, r24
-    3e98:	6f c0       	rjmp	.+222    	; 0x3f78 <main+0x178>
+    3e98:	7e c0       	rjmp	.+252    	; 0x3f96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3e9e:	84 e0       	ldi	r24, 0x04	; 4
-    3ea0:	95 d0       	rcall	.+298    	; 0x3fcc <verifySpace+0xc>
+    3ea0:	a4 d0       	rcall	.+328    	; 0x3fea <verifySpace+0xc>
       putch(0x00);
     3ea2:	80 e0       	ldi	r24, 0x00	; 0
-    3ea4:	6d d0       	rcall	.+218    	; 0x3f80 <putch>
-    3ea6:	69 c0       	rjmp	.+210    	; 0x3f7a <main+0x17a>
+    3ea4:	7c d0       	rcall	.+248    	; 0x3f9e <putch>
+    3ea6:	78 c0       	rjmp	.+240    	; 0x3f98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     3ea8:	84 36       	cpi	r24, 0x64	; 100
     3eaa:	09 f0       	breq	.+2      	; 0x3eae <main+0xae>
-    3eac:	3f c0       	rjmp	.+126    	; 0x3f2c <main+0x12c>
+    3eac:	4e c0       	rjmp	.+156    	; 0x3f4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    3eae:	78 d0       	rcall	.+240    	; 0x3fa0 <getLen>
+    3eae:	87 d0       	rcall	.+270    	; 0x3fbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3eb0:	e0 91 00 02 	lds	r30, 0x0200
     3eb4:	f0 91 01 02 	lds	r31, 0x0201
-    3eb8:	83 e0       	ldi	r24, 0x03	; 3
-    3eba:	87 bf       	out	0x37, r24	; 55
-    3ebc:	e8 95       	spm
-    3ebe:	c0 e0       	ldi	r28, 0x00	; 0
-    3ec0:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	88 e3       	ldi	r24, 0x38	; 56
+    3eba:	e0 30       	cpi	r30, 0x00	; 0
+    3ebc:	f8 07       	cpc	r31, r24
+    3ebe:	18 f4       	brcc	.+6      	; 0x3ec6 <main+0xc6>
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	87 bf       	out	0x37, r24	; 55
+    3ec4:	e8 95       	spm
+    3ec6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ec8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ec2:	66 d0       	rcall	.+204    	; 0x3f90 <getch>
-    3ec4:	89 93       	st	Y+, r24
+    3eca:	71 d0       	rcall	.+226    	; 0x3fae <getch>
+    3ecc:	89 93       	st	Y+, r24
       while (--length);
-    3ec6:	80 91 02 02 	lds	r24, 0x0202
-    3eca:	81 50       	subi	r24, 0x01	; 1
-    3ecc:	80 93 02 02 	sts	0x0202, r24
-    3ed0:	88 23       	and	r24, r24
-    3ed2:	b9 f7       	brne	.-18     	; 0x3ec2 <main+0xc2>
+    3ece:	80 91 02 02 	lds	r24, 0x0202
+    3ed2:	81 50       	subi	r24, 0x01	; 1
+    3ed4:	80 93 02 02 	sts	0x0202, r24
+    3ed8:	88 23       	and	r24, r24
+    3eda:	b9 f7       	brne	.-18     	; 0x3eca <main+0xca>
+
+      // 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);
+    3edc:	e0 91 00 02 	lds	r30, 0x0200
+    3ee0:	f0 91 01 02 	lds	r31, 0x0201
+    3ee4:	88 e3       	ldi	r24, 0x38	; 56
+    3ee6:	e0 30       	cpi	r30, 0x00	; 0
+    3ee8:	f8 07       	cpc	r31, r24
+    3eea:	18 f0       	brcs	.+6      	; 0x3ef2 <main+0xf2>
+    3eec:	83 e0       	ldi	r24, 0x03	; 3
+    3eee:	87 bf       	out	0x37, r24	; 55
+    3ef0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ed4:	75 d0       	rcall	.+234    	; 0x3fc0 <verifySpace>
+    3ef2:	75 d0       	rcall	.+234    	; 0x3fde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3ed6:	07 b6       	in	r0, 0x37	; 55
-    3ed8:	00 fc       	sbrc	r0, 0
-    3eda:	fd cf       	rjmp	.-6      	; 0x3ed6 <main+0xd6>
+    3ef4:	07 b6       	in	r0, 0x37	; 55
+    3ef6:	00 fc       	sbrc	r0, 0
+    3ef8:	fd cf       	rjmp	.-6      	; 0x3ef4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    3edc:	40 91 00 02 	lds	r20, 0x0200
-    3ee0:	50 91 01 02 	lds	r21, 0x0201
-    3ee4:	a0 e0       	ldi	r26, 0x00	; 0
-    3ee6:	b1 e0       	ldi	r27, 0x01	; 1
+    3efa:	40 91 00 02 	lds	r20, 0x0200
+    3efe:	50 91 01 02 	lds	r21, 0x0201
+    3f02:	a0 e0       	ldi	r26, 0x00	; 0
+    3f04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3ee8:	2c 91       	ld	r18, X
-    3eea:	30 e0       	ldi	r19, 0x00	; 0
+    3f06:	2c 91       	ld	r18, X
+    3f08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3eec:	11 96       	adiw	r26, 0x01	; 1
-    3eee:	8c 91       	ld	r24, X
-    3ef0:	11 97       	sbiw	r26, 0x01	; 1
-    3ef2:	90 e0       	ldi	r25, 0x00	; 0
-    3ef4:	98 2f       	mov	r25, r24
-    3ef6:	88 27       	eor	r24, r24
-    3ef8:	82 2b       	or	r24, r18
-    3efa:	93 2b       	or	r25, r19
+    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))
 #endif
 
 /* main program starts here */
 int main(void) {
-    3efc:	12 96       	adiw	r26, 0x02	; 2
+    3f1a:	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);
-    3efe:	fa 01       	movw	r30, r20
-    3f00:	0c 01       	movw	r0, r24
-    3f02:	d7 be       	out	0x37, r13	; 55
-    3f04:	e8 95       	spm
-    3f06:	11 24       	eor	r1, r1
+    3f1c:	fa 01       	movw	r30, r20
+    3f1e:	0c 01       	movw	r0, r24
+    3f20:	d7 be       	out	0x37, r13	; 55
+    3f22:	e8 95       	spm
+    3f24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f08:	4e 5f       	subi	r20, 0xFE	; 254
-    3f0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f26:	4e 5f       	subi	r20, 0xFE	; 254
+    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f0c:	f1 e0       	ldi	r31, 0x01	; 1
-    3f0e:	a0 38       	cpi	r26, 0x80	; 128
-    3f10:	bf 07       	cpc	r27, r31
-    3f12:	51 f7       	brne	.-44     	; 0x3ee8 <main+0xe8>
+    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>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f14:	e0 91 00 02 	lds	r30, 0x0200
-    3f18:	f0 91 01 02 	lds	r31, 0x0201
-    3f1c:	f7 be       	out	0x37, r15	; 55
-    3f1e:	e8 95       	spm
+    3f32:	e0 91 00 02 	lds	r30, 0x0200
+    3f36:	f0 91 01 02 	lds	r31, 0x0201
+    3f3a:	e7 be       	out	0x37, r14	; 55
+    3f3c:	e8 95       	spm
       boot_spm_busy_wait();
-    3f20:	07 b6       	in	r0, 0x37	; 55
-    3f22:	00 fc       	sbrc	r0, 0
-    3f24:	fd cf       	rjmp	.-6      	; 0x3f20 <main+0x120>
+    3f3e:	07 b6       	in	r0, 0x37	; 55
+    3f40:	00 fc       	sbrc	r0, 0
+    3f42:	fd cf       	rjmp	.-6      	; 0x3f3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f26:	e7 be       	out	0x37, r14	; 55
-    3f28:	e8 95       	spm
-    3f2a:	27 c0       	rjmp	.+78     	; 0x3f7a <main+0x17a>
+    3f44:	f7 be       	out	0x37, r15	; 55
+    3f46:	e8 95       	spm
+    3f48:	27 c0       	rjmp	.+78     	; 0x3f98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f2c:	84 37       	cpi	r24, 0x74	; 116
-    3f2e:	b9 f4       	brne	.+46     	; 0x3f5e <main+0x15e>
+    3f4a:	84 37       	cpi	r24, 0x74	; 116
+    3f4c:	b9 f4       	brne	.+46     	; 0x3f7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    3f30:	37 d0       	rcall	.+110    	; 0x3fa0 <getLen>
+    3f4e:	37 d0       	rcall	.+110    	; 0x3fbe <getLen>
       verifySpace();
-    3f32:	46 d0       	rcall	.+140    	; 0x3fc0 <verifySpace>
+    3f50:	46 d0       	rcall	.+140    	; 0x3fde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    3f34:	e0 91 00 02 	lds	r30, 0x0200
-    3f38:	f0 91 01 02 	lds	r31, 0x0201
-    3f3c:	31 96       	adiw	r30, 0x01	; 1
-    3f3e:	f0 93 01 02 	sts	0x0201, r31
-    3f42:	e0 93 00 02 	sts	0x0200, r30
-    3f46:	31 97       	sbiw	r30, 0x01	; 1
-    3f48:	e4 91       	lpm	r30, Z+
-    3f4a:	8e 2f       	mov	r24, r30
-    3f4c:	19 d0       	rcall	.+50     	; 0x3f80 <putch>
+    3f52:	e0 91 00 02 	lds	r30, 0x0200
+    3f56:	f0 91 01 02 	lds	r31, 0x0201
+    3f5a:	31 96       	adiw	r30, 0x01	; 1
+    3f5c:	f0 93 01 02 	sts	0x0201, r31
+    3f60:	e0 93 00 02 	sts	0x0200, r30
+    3f64:	31 97       	sbiw	r30, 0x01	; 1
+    3f66:	e4 91       	lpm	r30, Z+
+    3f68:	8e 2f       	mov	r24, r30
+    3f6a:	19 d0       	rcall	.+50     	; 0x3f9e <putch>
       while (--length);
-    3f4e:	80 91 02 02 	lds	r24, 0x0202
-    3f52:	81 50       	subi	r24, 0x01	; 1
-    3f54:	80 93 02 02 	sts	0x0202, r24
-    3f58:	88 23       	and	r24, r24
-    3f5a:	61 f7       	brne	.-40     	; 0x3f34 <main+0x134>
-    3f5c:	0e c0       	rjmp	.+28     	; 0x3f7a <main+0x17a>
+    3f6c:	80 91 02 02 	lds	r24, 0x0202
+    3f70:	81 50       	subi	r24, 0x01	; 1
+    3f72:	80 93 02 02 	sts	0x0202, r24
+    3f76:	88 23       	and	r24, r24
+    3f78:	61 f7       	brne	.-40     	; 0x3f52 <main+0x152>
+    3f7a:	0e c0       	rjmp	.+28     	; 0x3f98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f5e:	85 37       	cpi	r24, 0x75	; 117
-    3f60:	39 f4       	brne	.+14     	; 0x3f70 <main+0x170>
+    3f7c:	85 37       	cpi	r24, 0x75	; 117
+    3f7e:	39 f4       	brne	.+14     	; 0x3f8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f62:	2e d0       	rcall	.+92     	; 0x3fc0 <verifySpace>
+    3f80:	2e d0       	rcall	.+92     	; 0x3fde <verifySpace>
       putch(SIGNATURE_0);
-    3f64:	8e e1       	ldi	r24, 0x1E	; 30
-    3f66:	0c d0       	rcall	.+24     	; 0x3f80 <putch>
+    3f82:	8e e1       	ldi	r24, 0x1E	; 30
+    3f84:	0c d0       	rcall	.+24     	; 0x3f9e <putch>
       putch(SIGNATURE_1);
-    3f68:	84 e9       	ldi	r24, 0x94	; 148
-    3f6a:	0a d0       	rcall	.+20     	; 0x3f80 <putch>
+    3f86:	84 e9       	ldi	r24, 0x94	; 148
+    3f88:	0a d0       	rcall	.+20     	; 0x3f9e <putch>
       putch(SIGNATURE_2);
-    3f6c:	86 e0       	ldi	r24, 0x06	; 6
-    3f6e:	9a cf       	rjmp	.-204    	; 0x3ea4 <main+0xa4>
+    3f8a:	86 e0       	ldi	r24, 0x06	; 6
+    3f8c:	8b cf       	rjmp	.-234    	; 0x3ea4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    3f70:	81 35       	cpi	r24, 0x51	; 81
-    3f72:	11 f4       	brne	.+4      	; 0x3f78 <main+0x178>
+    3f8e:	81 35       	cpi	r24, 0x51	; 81
+    3f90:	11 f4       	brne	.+4      	; 0x3f96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f74:	88 e0       	ldi	r24, 0x08	; 8
-    3f76:	19 d0       	rcall	.+50     	; 0x3faa <watchdogConfig>
+    3f92:	88 e0       	ldi	r24, 0x08	; 8
+    3f94:	19 d0       	rcall	.+50     	; 0x3fc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f78:	23 d0       	rcall	.+70     	; 0x3fc0 <verifySpace>
+    3f96:	23 d0       	rcall	.+70     	; 0x3fde <verifySpace>
     }
     putch(STK_OK);
-    3f7a:	80 e1       	ldi	r24, 0x10	; 16
-    3f7c:	01 d0       	rcall	.+2      	; 0x3f80 <putch>
-    3f7e:	6b cf       	rjmp	.-298    	; 0x3e56 <main+0x56>
+    3f98:	80 e1       	ldi	r24, 0x10	; 16
+    3f9a:	01 d0       	rcall	.+2      	; 0x3f9e <putch>
+    3f9c:	5c cf       	rjmp	.-328    	; 0x3e56 <main+0x56>
 
-00003f80 <putch>:
+00003f9e <putch>:
   }
 }
 
 void putch(char ch) {
-    3f80:	98 2f       	mov	r25, r24
+    3f9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    3f82:	80 91 c0 00 	lds	r24, 0x00C0
-    3f86:	85 ff       	sbrs	r24, 5
-    3f88:	fc cf       	rjmp	.-8      	; 0x3f82 <putch+0x2>
+    3fa0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa4:	85 ff       	sbrs	r24, 5
+    3fa6:	fc cf       	rjmp	.-8      	; 0x3fa0 <putch+0x2>
   UDR0 = ch;
-    3f8a:	90 93 c6 00 	sts	0x00C6, r25
+    3fa8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3f8e:	08 95       	ret
+    3fac:	08 95       	ret
 
-00003f90 <getch>:
+00003fae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3f90:	a8 95       	wdr
+    3fae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    3f92:	80 91 c0 00 	lds	r24, 0x00C0
-    3f96:	87 ff       	sbrs	r24, 7
-    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <getch+0x2>
+    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fb4:	87 ff       	sbrs	r24, 7
+    3fb6:	fc cf       	rjmp	.-8      	; 0x3fb0 <getch+0x2>
   ch = UDR0;
-    3f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    3f9e:	08 95       	ret
+    3fbc:	08 95       	ret
 
-00003fa0 <getLen>:
+00003fbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    3fa0:	f7 df       	rcall	.-18     	; 0x3f90 <getch>
+    3fbe:	f7 df       	rcall	.-18     	; 0x3fae <getch>
   length = getch();
-    3fa2:	f6 df       	rcall	.-20     	; 0x3f90 <getch>
-    3fa4:	80 93 02 02 	sts	0x0202, r24
+    3fc0:	f6 df       	rcall	.-20     	; 0x3fae <getch>
+    3fc2:	80 93 02 02 	sts	0x0202, r24
   return getch();
 }
-    3fa8:	f3 cf       	rjmp	.-26     	; 0x3f90 <getch>
+    3fc6:	f3 cf       	rjmp	.-26     	; 0x3fae <getch>
 
-00003faa <watchdogConfig>:
+00003fc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3faa:	e0 e6       	ldi	r30, 0x60	; 96
-    3fac:	f0 e0       	ldi	r31, 0x00	; 0
-    3fae:	98 e1       	ldi	r25, 0x18	; 24
-    3fb0:	90 83       	st	Z, r25
+    3fc8:	e0 e6       	ldi	r30, 0x60	; 96
+    3fca:	f0 e0       	ldi	r31, 0x00	; 0
+    3fcc:	98 e1       	ldi	r25, 0x18	; 24
+    3fce:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fb2:	80 83       	st	Z, r24
+    3fd0:	80 83       	st	Z, r24
 }
-    3fb4:	08 95       	ret
+    3fd2:	08 95       	ret
 
-00003fb6 <appStart>:
+00003fd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fb6:	80 e0       	ldi	r24, 0x00	; 0
-    3fb8:	f8 df       	rcall	.-16     	; 0x3faa <watchdogConfig>
+    3fd4:	80 e0       	ldi	r24, 0x00	; 0
+    3fd6:	f8 df       	rcall	.-16     	; 0x3fc8 <watchdogConfig>
   __asm__ __volatile__ (
-    3fba:	ee 27       	eor	r30, r30
-    3fbc:	ff 27       	eor	r31, r31
-    3fbe:	09 94       	ijmp
+    3fd8:	ee 27       	eor	r30, r30
+    3fda:	ff 27       	eor	r31, r31
+    3fdc:	09 94       	ijmp
 
-00003fc0 <verifySpace>:
+00003fde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    3fc0:	e7 df       	rcall	.-50     	; 0x3f90 <getch>
-    3fc2:	80 32       	cpi	r24, 0x20	; 32
-    3fc4:	09 f0       	breq	.+2      	; 0x3fc8 <verifySpace+0x8>
-    3fc6:	f7 df       	rcall	.-18     	; 0x3fb6 <appStart>
+    3fde:	e7 df       	rcall	.-50     	; 0x3fae <getch>
+    3fe0:	80 32       	cpi	r24, 0x20	; 32
+    3fe2:	09 f0       	breq	.+2      	; 0x3fe6 <verifySpace+0x8>
+    3fe4:	f7 df       	rcall	.-18     	; 0x3fd4 <appStart>
   putch(STK_INSYNC);
-    3fc8:	84 e1       	ldi	r24, 0x14	; 20
+    3fe6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fca:	da cf       	rjmp	.-76     	; 0x3f80 <putch>
+    3fe8:	da cf       	rjmp	.-76     	; 0x3f9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fcc:	1f 93       	push	r17
-    3fce:	18 2f       	mov	r17, r24
+    3fea:	1f 93       	push	r17
+    3fec:	18 2f       	mov	r17, r24
 
-00003fd0 <getNch>:
+00003fee <getNch>:
   do getch(); while (--count);
-    3fd0:	df df       	rcall	.-66     	; 0x3f90 <getch>
-    3fd2:	11 50       	subi	r17, 0x01	; 1
-    3fd4:	e9 f7       	brne	.-6      	; 0x3fd0 <getNch>
+    3fee:	df df       	rcall	.-66     	; 0x3fae <getch>
+    3ff0:	11 50       	subi	r17, 0x01	; 1
+    3ff2:	e9 f7       	brne	.-6      	; 0x3fee <getNch>
   verifySpace();
-    3fd6:	f4 df       	rcall	.-24     	; 0x3fc0 <verifySpace>
+    3ff4:	f4 df       	rcall	.-24     	; 0x3fde <verifySpace>
 }
-    3fd8:	1f 91       	pop	r17
-    3fda:	08 95       	ret
+    3ff6:	1f 91       	pop	r17
+    3ff8:	08 95       	ret

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_lilypad.hex

@@ -1,32 +1,34 @@
 :103E000085E08093810082E08093C00088E1809308
 :103E1000C10086E08093C20088E08093C40084B72C
-:103E200014BE81FFC8D08DE0C0D0259A86E028E17D
+:103E200014BE81FFD7D08DE0CFD0259A86E028E15F
 :103E30003EEF91E0309385002093840096BBB09BC9
 :103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000FA2EF1E1EF2E9CD0813421F481E0B6D02E
+:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010
 :103E600083E020C0823411F484E103C0853419F466
-:103E700085E0ACD082C0853581F48AD0082F10E06F
-:103E800087D090E0982F8827802B912B880F991F3F
-:103E900090930102809300026FC0863529F484E07C
-:103EA00095D080E06DD069C0843609F03FC078D0ED
-:103EB000E0910002F091010283E087BFE895C0E045
-:103EC000D1E066D0899380910202815080930202F2
-:103ED0008823B9F775D007B600FCFDCF40910002EA
-:103EE00050910102A0E0B1E02C9130E011968C914C
-:103EF000119790E0982F8827822B932B1296FA0126
-:103F00000C01D7BEE89511244E5F5F4FF1E0A03859
-:103F1000BF0751F7E0910002F0910102F7BEE8956A
-:103F200007B600FCFDCFE7BEE89527C08437B9F49B
-:103F300037D046D0E0910002F09101023196F09323
-:103F40000102E09300023197E4918E2F19D0809105
-:103F50000202815080930202882361F70EC08537E8
-:103F600039F42ED08EE10CD084E90AD086E09ACFC5
-:103F7000813511F488E019D023D080E101D06BCFD6
-:103F8000982F8091C00085FFFCCF9093C6000895C4
-:103F9000A8958091C00087FFFCCF8091C60008954E
-:103FA000F7DFF6DF80930202F3CFE0E6F0E098E17E
-:103FB00090838083089580E0F8DFEE27FF2709943F
-:103FC000E7DF803209F0F7DF84E1DACF1F93182FA3
-:0C3FD000DFDF1150E9F7F4DF1F910895C6
+:103E700085E0BBD091C0853581F499D0082F10E042
+:103E800096D090E0982F8827802B912B880F991F30
+:103E900090930102809300027EC0863529F484E06D
+:103EA000A4D080E07CD078C0843609F04EC087D0A2
+:103EB000E0910002F091010288E3E030F80718F485
+:103EC00083E087BFE895C0E0D1E071D0899380910D
+:103ED00002028150809302028823B9F7E091000228
+:103EE000F091010288E3E030F80718F083E087BF23
+:103EF000E89575D007B600FCFDCF409100025091C7
+:103F00000102A0E0B1E02C9130E011968C91119764
+:103F100090E0982F8827822B932B1296FA010C01A0
+:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780
+:103F300051F7E0910002F0910102E7BEE89507B663
+:103F400000FCFDCFF7BEE89527C08437B9F437D021
+:103F500046D0E0910002F09101023196F093010207
+:103F6000E09300023197E4918E2F19D080910202E4
+:103F7000815080930202882361F70EC0853739F49F
+:103F80002ED08EE10CD084E90AD086E08BCF81352B
+:103F900011F488E019D023D080E101D05CCF982FB4
+:103FA0008091C00085FFFCCF9093C6000895A8952E
+:103FB0008091C00087FFFCCF8091C6000895F7DF95
+:103FC000F6DF80930202F3CFE0E6F0E098E1908321
+:103FD0008083089580E0F8DFEE27FF270994E7DF6C
+:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B
+:0A3FF0001150E9F7F4DF1F91089566
 :0400000300003E00BB
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_lilypad.lst

@@ -3,25 +3,25 @@ optiboot_lilypad.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  00003e00  00003e00  00000054  2**1
+  0 .text         000001fa  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e22:	81 ff       	sbrs	r24, 1
-    3e24:	c8 d0       	rcall	.+400    	; 0x3fb6 <appStart>
+    3e24:	d7 d0       	rcall	.+430    	; 0x3fd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     3e26:	8d e0       	ldi	r24, 0x0D	; 13
-    3e28:	c0 d0       	rcall	.+384    	; 0x3faa <watchdogConfig>
+    3e28:	cf d0       	rcall	.+414    	; 0x3fc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e4e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e50:	fa 2e       	mov	r15, r26
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e52:	f1 e1       	ldi	r31, 0x11	; 17
-    3e54:	ef 2e       	mov	r14, r31
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e56:	9c d0       	rcall	.+312    	; 0x3f90 <getch>
+    3e56:	ab d0       	rcall	.+342    	; 0x3fae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     3e5c:	81 e0       	ldi	r24, 0x01	; 1
-    3e5e:	b6 d0       	rcall	.+364    	; 0x3fcc <verifySpace+0xc>
+    3e5e:	c5 d0       	rcall	.+394    	; 0x3fea <verifySpace+0xc>
       putch(0x03);
     3e60:	83 e0       	ldi	r24, 0x03	; 3
     3e62:	20 c0       	rjmp	.+64     	; 0x3ea4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e70:	85 e0       	ldi	r24, 0x05	; 5
-    3e72:	ac d0       	rcall	.+344    	; 0x3fcc <verifySpace+0xc>
-    3e74:	82 c0       	rjmp	.+260    	; 0x3f7a <main+0x17a>
+    3e72:	bb d0       	rcall	.+374    	; 0x3fea <verifySpace+0xc>
+    3e74:	91 c0       	rjmp	.+290    	; 0x3f98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e7a:	8a d0       	rcall	.+276    	; 0x3f90 <getch>
+    3e7a:	99 d0       	rcall	.+306    	; 0x3fae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e7c:	08 2f       	mov	r16, r24
     3e7e:	10 e0       	ldi	r17, 0x00	; 0
-    3e80:	87 d0       	rcall	.+270    	; 0x3f90 <getch>
+    3e80:	96 d0       	rcall	.+300    	; 0x3fae <getch>
     3e82:	90 e0       	ldi	r25, 0x00	; 0
     3e84:	98 2f       	mov	r25, r24
     3e86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     3e90:	90 93 01 02 	sts	0x0201, r25
     3e94:	80 93 00 02 	sts	0x0200, r24
-    3e98:	6f c0       	rjmp	.+222    	; 0x3f78 <main+0x178>
+    3e98:	7e c0       	rjmp	.+252    	; 0x3f96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3e9e:	84 e0       	ldi	r24, 0x04	; 4
-    3ea0:	95 d0       	rcall	.+298    	; 0x3fcc <verifySpace+0xc>
+    3ea0:	a4 d0       	rcall	.+328    	; 0x3fea <verifySpace+0xc>
       putch(0x00);
     3ea2:	80 e0       	ldi	r24, 0x00	; 0
-    3ea4:	6d d0       	rcall	.+218    	; 0x3f80 <putch>
-    3ea6:	69 c0       	rjmp	.+210    	; 0x3f7a <main+0x17a>
+    3ea4:	7c d0       	rcall	.+248    	; 0x3f9e <putch>
+    3ea6:	78 c0       	rjmp	.+240    	; 0x3f98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     3ea8:	84 36       	cpi	r24, 0x64	; 100
     3eaa:	09 f0       	breq	.+2      	; 0x3eae <main+0xae>
-    3eac:	3f c0       	rjmp	.+126    	; 0x3f2c <main+0x12c>
+    3eac:	4e c0       	rjmp	.+156    	; 0x3f4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    3eae:	78 d0       	rcall	.+240    	; 0x3fa0 <getLen>
+    3eae:	87 d0       	rcall	.+270    	; 0x3fbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3eb0:	e0 91 00 02 	lds	r30, 0x0200
     3eb4:	f0 91 01 02 	lds	r31, 0x0201
-    3eb8:	83 e0       	ldi	r24, 0x03	; 3
-    3eba:	87 bf       	out	0x37, r24	; 55
-    3ebc:	e8 95       	spm
-    3ebe:	c0 e0       	ldi	r28, 0x00	; 0
-    3ec0:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	88 e3       	ldi	r24, 0x38	; 56
+    3eba:	e0 30       	cpi	r30, 0x00	; 0
+    3ebc:	f8 07       	cpc	r31, r24
+    3ebe:	18 f4       	brcc	.+6      	; 0x3ec6 <main+0xc6>
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	87 bf       	out	0x37, r24	; 55
+    3ec4:	e8 95       	spm
+    3ec6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ec8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ec2:	66 d0       	rcall	.+204    	; 0x3f90 <getch>
-    3ec4:	89 93       	st	Y+, r24
+    3eca:	71 d0       	rcall	.+226    	; 0x3fae <getch>
+    3ecc:	89 93       	st	Y+, r24
       while (--length);
-    3ec6:	80 91 02 02 	lds	r24, 0x0202
-    3eca:	81 50       	subi	r24, 0x01	; 1
-    3ecc:	80 93 02 02 	sts	0x0202, r24
-    3ed0:	88 23       	and	r24, r24
-    3ed2:	b9 f7       	brne	.-18     	; 0x3ec2 <main+0xc2>
+    3ece:	80 91 02 02 	lds	r24, 0x0202
+    3ed2:	81 50       	subi	r24, 0x01	; 1
+    3ed4:	80 93 02 02 	sts	0x0202, r24
+    3ed8:	88 23       	and	r24, r24
+    3eda:	b9 f7       	brne	.-18     	; 0x3eca <main+0xca>
+
+      // 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);
+    3edc:	e0 91 00 02 	lds	r30, 0x0200
+    3ee0:	f0 91 01 02 	lds	r31, 0x0201
+    3ee4:	88 e3       	ldi	r24, 0x38	; 56
+    3ee6:	e0 30       	cpi	r30, 0x00	; 0
+    3ee8:	f8 07       	cpc	r31, r24
+    3eea:	18 f0       	brcs	.+6      	; 0x3ef2 <main+0xf2>
+    3eec:	83 e0       	ldi	r24, 0x03	; 3
+    3eee:	87 bf       	out	0x37, r24	; 55
+    3ef0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ed4:	75 d0       	rcall	.+234    	; 0x3fc0 <verifySpace>
+    3ef2:	75 d0       	rcall	.+234    	; 0x3fde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3ed6:	07 b6       	in	r0, 0x37	; 55
-    3ed8:	00 fc       	sbrc	r0, 0
-    3eda:	fd cf       	rjmp	.-6      	; 0x3ed6 <main+0xd6>
+    3ef4:	07 b6       	in	r0, 0x37	; 55
+    3ef6:	00 fc       	sbrc	r0, 0
+    3ef8:	fd cf       	rjmp	.-6      	; 0x3ef4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    3edc:	40 91 00 02 	lds	r20, 0x0200
-    3ee0:	50 91 01 02 	lds	r21, 0x0201
-    3ee4:	a0 e0       	ldi	r26, 0x00	; 0
-    3ee6:	b1 e0       	ldi	r27, 0x01	; 1
+    3efa:	40 91 00 02 	lds	r20, 0x0200
+    3efe:	50 91 01 02 	lds	r21, 0x0201
+    3f02:	a0 e0       	ldi	r26, 0x00	; 0
+    3f04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3ee8:	2c 91       	ld	r18, X
-    3eea:	30 e0       	ldi	r19, 0x00	; 0
+    3f06:	2c 91       	ld	r18, X
+    3f08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3eec:	11 96       	adiw	r26, 0x01	; 1
-    3eee:	8c 91       	ld	r24, X
-    3ef0:	11 97       	sbiw	r26, 0x01	; 1
-    3ef2:	90 e0       	ldi	r25, 0x00	; 0
-    3ef4:	98 2f       	mov	r25, r24
-    3ef6:	88 27       	eor	r24, r24
-    3ef8:	82 2b       	or	r24, r18
-    3efa:	93 2b       	or	r25, r19
+    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))
 #endif
 
 /* main program starts here */
 int main(void) {
-    3efc:	12 96       	adiw	r26, 0x02	; 2
+    3f1a:	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);
-    3efe:	fa 01       	movw	r30, r20
-    3f00:	0c 01       	movw	r0, r24
-    3f02:	d7 be       	out	0x37, r13	; 55
-    3f04:	e8 95       	spm
-    3f06:	11 24       	eor	r1, r1
+    3f1c:	fa 01       	movw	r30, r20
+    3f1e:	0c 01       	movw	r0, r24
+    3f20:	d7 be       	out	0x37, r13	; 55
+    3f22:	e8 95       	spm
+    3f24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f08:	4e 5f       	subi	r20, 0xFE	; 254
-    3f0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f26:	4e 5f       	subi	r20, 0xFE	; 254
+    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f0c:	f1 e0       	ldi	r31, 0x01	; 1
-    3f0e:	a0 38       	cpi	r26, 0x80	; 128
-    3f10:	bf 07       	cpc	r27, r31
-    3f12:	51 f7       	brne	.-44     	; 0x3ee8 <main+0xe8>
+    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>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f14:	e0 91 00 02 	lds	r30, 0x0200
-    3f18:	f0 91 01 02 	lds	r31, 0x0201
-    3f1c:	f7 be       	out	0x37, r15	; 55
-    3f1e:	e8 95       	spm
+    3f32:	e0 91 00 02 	lds	r30, 0x0200
+    3f36:	f0 91 01 02 	lds	r31, 0x0201
+    3f3a:	e7 be       	out	0x37, r14	; 55
+    3f3c:	e8 95       	spm
       boot_spm_busy_wait();
-    3f20:	07 b6       	in	r0, 0x37	; 55
-    3f22:	00 fc       	sbrc	r0, 0
-    3f24:	fd cf       	rjmp	.-6      	; 0x3f20 <main+0x120>
+    3f3e:	07 b6       	in	r0, 0x37	; 55
+    3f40:	00 fc       	sbrc	r0, 0
+    3f42:	fd cf       	rjmp	.-6      	; 0x3f3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f26:	e7 be       	out	0x37, r14	; 55
-    3f28:	e8 95       	spm
-    3f2a:	27 c0       	rjmp	.+78     	; 0x3f7a <main+0x17a>
+    3f44:	f7 be       	out	0x37, r15	; 55
+    3f46:	e8 95       	spm
+    3f48:	27 c0       	rjmp	.+78     	; 0x3f98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f2c:	84 37       	cpi	r24, 0x74	; 116
-    3f2e:	b9 f4       	brne	.+46     	; 0x3f5e <main+0x15e>
+    3f4a:	84 37       	cpi	r24, 0x74	; 116
+    3f4c:	b9 f4       	brne	.+46     	; 0x3f7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    3f30:	37 d0       	rcall	.+110    	; 0x3fa0 <getLen>
+    3f4e:	37 d0       	rcall	.+110    	; 0x3fbe <getLen>
       verifySpace();
-    3f32:	46 d0       	rcall	.+140    	; 0x3fc0 <verifySpace>
+    3f50:	46 d0       	rcall	.+140    	; 0x3fde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    3f34:	e0 91 00 02 	lds	r30, 0x0200
-    3f38:	f0 91 01 02 	lds	r31, 0x0201
-    3f3c:	31 96       	adiw	r30, 0x01	; 1
-    3f3e:	f0 93 01 02 	sts	0x0201, r31
-    3f42:	e0 93 00 02 	sts	0x0200, r30
-    3f46:	31 97       	sbiw	r30, 0x01	; 1
-    3f48:	e4 91       	lpm	r30, Z+
-    3f4a:	8e 2f       	mov	r24, r30
-    3f4c:	19 d0       	rcall	.+50     	; 0x3f80 <putch>
+    3f52:	e0 91 00 02 	lds	r30, 0x0200
+    3f56:	f0 91 01 02 	lds	r31, 0x0201
+    3f5a:	31 96       	adiw	r30, 0x01	; 1
+    3f5c:	f0 93 01 02 	sts	0x0201, r31
+    3f60:	e0 93 00 02 	sts	0x0200, r30
+    3f64:	31 97       	sbiw	r30, 0x01	; 1
+    3f66:	e4 91       	lpm	r30, Z+
+    3f68:	8e 2f       	mov	r24, r30
+    3f6a:	19 d0       	rcall	.+50     	; 0x3f9e <putch>
       while (--length);
-    3f4e:	80 91 02 02 	lds	r24, 0x0202
-    3f52:	81 50       	subi	r24, 0x01	; 1
-    3f54:	80 93 02 02 	sts	0x0202, r24
-    3f58:	88 23       	and	r24, r24
-    3f5a:	61 f7       	brne	.-40     	; 0x3f34 <main+0x134>
-    3f5c:	0e c0       	rjmp	.+28     	; 0x3f7a <main+0x17a>
+    3f6c:	80 91 02 02 	lds	r24, 0x0202
+    3f70:	81 50       	subi	r24, 0x01	; 1
+    3f72:	80 93 02 02 	sts	0x0202, r24
+    3f76:	88 23       	and	r24, r24
+    3f78:	61 f7       	brne	.-40     	; 0x3f52 <main+0x152>
+    3f7a:	0e c0       	rjmp	.+28     	; 0x3f98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f5e:	85 37       	cpi	r24, 0x75	; 117
-    3f60:	39 f4       	brne	.+14     	; 0x3f70 <main+0x170>
+    3f7c:	85 37       	cpi	r24, 0x75	; 117
+    3f7e:	39 f4       	brne	.+14     	; 0x3f8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f62:	2e d0       	rcall	.+92     	; 0x3fc0 <verifySpace>
+    3f80:	2e d0       	rcall	.+92     	; 0x3fde <verifySpace>
       putch(SIGNATURE_0);
-    3f64:	8e e1       	ldi	r24, 0x1E	; 30
-    3f66:	0c d0       	rcall	.+24     	; 0x3f80 <putch>
+    3f82:	8e e1       	ldi	r24, 0x1E	; 30
+    3f84:	0c d0       	rcall	.+24     	; 0x3f9e <putch>
       putch(SIGNATURE_1);
-    3f68:	84 e9       	ldi	r24, 0x94	; 148
-    3f6a:	0a d0       	rcall	.+20     	; 0x3f80 <putch>
+    3f86:	84 e9       	ldi	r24, 0x94	; 148
+    3f88:	0a d0       	rcall	.+20     	; 0x3f9e <putch>
       putch(SIGNATURE_2);
-    3f6c:	86 e0       	ldi	r24, 0x06	; 6
-    3f6e:	9a cf       	rjmp	.-204    	; 0x3ea4 <main+0xa4>
+    3f8a:	86 e0       	ldi	r24, 0x06	; 6
+    3f8c:	8b cf       	rjmp	.-234    	; 0x3ea4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    3f70:	81 35       	cpi	r24, 0x51	; 81
-    3f72:	11 f4       	brne	.+4      	; 0x3f78 <main+0x178>
+    3f8e:	81 35       	cpi	r24, 0x51	; 81
+    3f90:	11 f4       	brne	.+4      	; 0x3f96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f74:	88 e0       	ldi	r24, 0x08	; 8
-    3f76:	19 d0       	rcall	.+50     	; 0x3faa <watchdogConfig>
+    3f92:	88 e0       	ldi	r24, 0x08	; 8
+    3f94:	19 d0       	rcall	.+50     	; 0x3fc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f78:	23 d0       	rcall	.+70     	; 0x3fc0 <verifySpace>
+    3f96:	23 d0       	rcall	.+70     	; 0x3fde <verifySpace>
     }
     putch(STK_OK);
-    3f7a:	80 e1       	ldi	r24, 0x10	; 16
-    3f7c:	01 d0       	rcall	.+2      	; 0x3f80 <putch>
-    3f7e:	6b cf       	rjmp	.-298    	; 0x3e56 <main+0x56>
+    3f98:	80 e1       	ldi	r24, 0x10	; 16
+    3f9a:	01 d0       	rcall	.+2      	; 0x3f9e <putch>
+    3f9c:	5c cf       	rjmp	.-328    	; 0x3e56 <main+0x56>
 
-00003f80 <putch>:
+00003f9e <putch>:
   }
 }
 
 void putch(char ch) {
-    3f80:	98 2f       	mov	r25, r24
+    3f9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    3f82:	80 91 c0 00 	lds	r24, 0x00C0
-    3f86:	85 ff       	sbrs	r24, 5
-    3f88:	fc cf       	rjmp	.-8      	; 0x3f82 <putch+0x2>
+    3fa0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa4:	85 ff       	sbrs	r24, 5
+    3fa6:	fc cf       	rjmp	.-8      	; 0x3fa0 <putch+0x2>
   UDR0 = ch;
-    3f8a:	90 93 c6 00 	sts	0x00C6, r25
+    3fa8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3f8e:	08 95       	ret
+    3fac:	08 95       	ret
 
-00003f90 <getch>:
+00003fae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3f90:	a8 95       	wdr
+    3fae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    3f92:	80 91 c0 00 	lds	r24, 0x00C0
-    3f96:	87 ff       	sbrs	r24, 7
-    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <getch+0x2>
+    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fb4:	87 ff       	sbrs	r24, 7
+    3fb6:	fc cf       	rjmp	.-8      	; 0x3fb0 <getch+0x2>
   ch = UDR0;
-    3f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    3f9e:	08 95       	ret
+    3fbc:	08 95       	ret
 
-00003fa0 <getLen>:
+00003fbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    3fa0:	f7 df       	rcall	.-18     	; 0x3f90 <getch>
+    3fbe:	f7 df       	rcall	.-18     	; 0x3fae <getch>
   length = getch();
-    3fa2:	f6 df       	rcall	.-20     	; 0x3f90 <getch>
-    3fa4:	80 93 02 02 	sts	0x0202, r24
+    3fc0:	f6 df       	rcall	.-20     	; 0x3fae <getch>
+    3fc2:	80 93 02 02 	sts	0x0202, r24
   return getch();
 }
-    3fa8:	f3 cf       	rjmp	.-26     	; 0x3f90 <getch>
+    3fc6:	f3 cf       	rjmp	.-26     	; 0x3fae <getch>
 
-00003faa <watchdogConfig>:
+00003fc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3faa:	e0 e6       	ldi	r30, 0x60	; 96
-    3fac:	f0 e0       	ldi	r31, 0x00	; 0
-    3fae:	98 e1       	ldi	r25, 0x18	; 24
-    3fb0:	90 83       	st	Z, r25
+    3fc8:	e0 e6       	ldi	r30, 0x60	; 96
+    3fca:	f0 e0       	ldi	r31, 0x00	; 0
+    3fcc:	98 e1       	ldi	r25, 0x18	; 24
+    3fce:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fb2:	80 83       	st	Z, r24
+    3fd0:	80 83       	st	Z, r24
 }
-    3fb4:	08 95       	ret
+    3fd2:	08 95       	ret
 
-00003fb6 <appStart>:
+00003fd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fb6:	80 e0       	ldi	r24, 0x00	; 0
-    3fb8:	f8 df       	rcall	.-16     	; 0x3faa <watchdogConfig>
+    3fd4:	80 e0       	ldi	r24, 0x00	; 0
+    3fd6:	f8 df       	rcall	.-16     	; 0x3fc8 <watchdogConfig>
   __asm__ __volatile__ (
-    3fba:	ee 27       	eor	r30, r30
-    3fbc:	ff 27       	eor	r31, r31
-    3fbe:	09 94       	ijmp
+    3fd8:	ee 27       	eor	r30, r30
+    3fda:	ff 27       	eor	r31, r31
+    3fdc:	09 94       	ijmp
 
-00003fc0 <verifySpace>:
+00003fde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    3fc0:	e7 df       	rcall	.-50     	; 0x3f90 <getch>
-    3fc2:	80 32       	cpi	r24, 0x20	; 32
-    3fc4:	09 f0       	breq	.+2      	; 0x3fc8 <verifySpace+0x8>
-    3fc6:	f7 df       	rcall	.-18     	; 0x3fb6 <appStart>
+    3fde:	e7 df       	rcall	.-50     	; 0x3fae <getch>
+    3fe0:	80 32       	cpi	r24, 0x20	; 32
+    3fe2:	09 f0       	breq	.+2      	; 0x3fe6 <verifySpace+0x8>
+    3fe4:	f7 df       	rcall	.-18     	; 0x3fd4 <appStart>
   putch(STK_INSYNC);
-    3fc8:	84 e1       	ldi	r24, 0x14	; 20
+    3fe6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fca:	da cf       	rjmp	.-76     	; 0x3f80 <putch>
+    3fe8:	da cf       	rjmp	.-76     	; 0x3f9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fcc:	1f 93       	push	r17
-    3fce:	18 2f       	mov	r17, r24
+    3fea:	1f 93       	push	r17
+    3fec:	18 2f       	mov	r17, r24
 
-00003fd0 <getNch>:
+00003fee <getNch>:
   do getch(); while (--count);
-    3fd0:	df df       	rcall	.-66     	; 0x3f90 <getch>
-    3fd2:	11 50       	subi	r17, 0x01	; 1
-    3fd4:	e9 f7       	brne	.-6      	; 0x3fd0 <getNch>
+    3fee:	df df       	rcall	.-66     	; 0x3fae <getch>
+    3ff0:	11 50       	subi	r17, 0x01	; 1
+    3ff2:	e9 f7       	brne	.-6      	; 0x3fee <getNch>
   verifySpace();
-    3fd6:	f4 df       	rcall	.-24     	; 0x3fc0 <verifySpace>
+    3ff4:	f4 df       	rcall	.-24     	; 0x3fde <verifySpace>
 }
-    3fd8:	1f 91       	pop	r17
-    3fda:	08 95       	ret
+    3ff6:	1f 91       	pop	r17
+    3ff8:	08 95       	ret

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.hex

@@ -1,32 +1,34 @@
 :103E000085E08093810082E08093C00088E1809308
 :103E1000C10086E08093C20088E08093C40084B72C
-:103E200014BE81FFC8D08DE0C0D0259A86E028E17D
+:103E200014BE81FFD7D08DE0CFD0259A86E028E15F
 :103E30003EEF91E0309385002093840096BBB09BC9
 :103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000FA2EF1E1EF2E9CD0813421F481E0B6D02E
+:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010
 :103E600083E020C0823411F484E103C0853419F466
-:103E700085E0ACD082C0853581F48AD0082F10E06F
-:103E800087D090E0982F8827802B912B880F991F3F
-:103E900090930102809300026FC0863529F484E07C
-:103EA00095D080E06DD069C0843609F03FC078D0ED
-:103EB000E0910002F091010283E087BFE895C0E045
-:103EC000D1E066D0899380910202815080930202F2
-:103ED0008823B9F775D007B600FCFDCF40910002EA
-:103EE00050910102A0E0B1E02C9130E011968C914C
-:103EF000119790E0982F8827822B932B1296FA0126
-:103F00000C01D7BEE89511244E5F5F4FF1E0A03859
-:103F1000BF0751F7E0910002F0910102F7BEE8956A
-:103F200007B600FCFDCFE7BEE89527C08437B9F49B
-:103F300037D046D0E0910002F09101023196F09323
-:103F40000102E09300023197E4918E2F19D0809105
-:103F50000202815080930202882361F70EC08537E8
-:103F600039F42ED08EE10CD084E90AD086E09ACFC5
-:103F7000813511F488E019D023D080E101D06BCFD6
-:103F8000982F8091C00085FFFCCF9093C6000895C4
-:103F9000A8958091C00087FFFCCF8091C60008954E
-:103FA000F7DFF6DF80930202F3CFE0E6F0E098E17E
-:103FB00090838083089580E0F8DFEE27FF2709943F
-:103FC000E7DF803209F0F7DF84E1DACF1F93182FA3
-:0C3FD000DFDF1150E9F7F4DF1F910895C6
+:103E700085E0BBD091C0853581F499D0082F10E042
+:103E800096D090E0982F8827802B912B880F991F30
+:103E900090930102809300027EC0863529F484E06D
+:103EA000A4D080E07CD078C0843609F04EC087D0A2
+:103EB000E0910002F091010288E3E030F80718F485
+:103EC00083E087BFE895C0E0D1E071D0899380910D
+:103ED00002028150809302028823B9F7E091000228
+:103EE000F091010288E3E030F80718F083E087BF23
+:103EF000E89575D007B600FCFDCF409100025091C7
+:103F00000102A0E0B1E02C9130E011968C91119764
+:103F100090E0982F8827822B932B1296FA010C01A0
+:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780
+:103F300051F7E0910002F0910102E7BEE89507B663
+:103F400000FCFDCFF7BEE89527C08437B9F437D021
+:103F500046D0E0910002F09101023196F093010207
+:103F6000E09300023197E4918E2F19D080910202E4
+:103F7000815080930202882361F70EC0853739F49F
+:103F80002ED08EE10CD084E90AD086E08BCF81352B
+:103F900011F488E019D023D080E101D05CCF982FB4
+:103FA0008091C00085FFFCCF9093C6000895A8952E
+:103FB0008091C00087FFFCCF8091C6000895F7DF95
+:103FC000F6DF80930202F3CFE0E6F0E098E1908321
+:103FD0008083089580E0F8DFEE27FF270994E7DF6C
+:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B
+:0A3FF0001150E9F7F4DF1F91089566
 :0400000300003E00BB
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.lst

@@ -3,25 +3,25 @@ optiboot_lilypad_resonator.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  00003e00  00003e00  00000054  2**1
+  0 .text         000001fa  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e22:	81 ff       	sbrs	r24, 1
-    3e24:	c8 d0       	rcall	.+400    	; 0x3fb6 <appStart>
+    3e24:	d7 d0       	rcall	.+430    	; 0x3fd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     3e26:	8d e0       	ldi	r24, 0x0D	; 13
-    3e28:	c0 d0       	rcall	.+384    	; 0x3faa <watchdogConfig>
+    3e28:	cf d0       	rcall	.+414    	; 0x3fc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e4e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e50:	fa 2e       	mov	r15, r26
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e52:	f1 e1       	ldi	r31, 0x11	; 17
-    3e54:	ef 2e       	mov	r14, r31
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e56:	9c d0       	rcall	.+312    	; 0x3f90 <getch>
+    3e56:	ab d0       	rcall	.+342    	; 0x3fae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     3e5c:	81 e0       	ldi	r24, 0x01	; 1
-    3e5e:	b6 d0       	rcall	.+364    	; 0x3fcc <verifySpace+0xc>
+    3e5e:	c5 d0       	rcall	.+394    	; 0x3fea <verifySpace+0xc>
       putch(0x03);
     3e60:	83 e0       	ldi	r24, 0x03	; 3
     3e62:	20 c0       	rjmp	.+64     	; 0x3ea4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e70:	85 e0       	ldi	r24, 0x05	; 5
-    3e72:	ac d0       	rcall	.+344    	; 0x3fcc <verifySpace+0xc>
-    3e74:	82 c0       	rjmp	.+260    	; 0x3f7a <main+0x17a>
+    3e72:	bb d0       	rcall	.+374    	; 0x3fea <verifySpace+0xc>
+    3e74:	91 c0       	rjmp	.+290    	; 0x3f98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e7a:	8a d0       	rcall	.+276    	; 0x3f90 <getch>
+    3e7a:	99 d0       	rcall	.+306    	; 0x3fae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e7c:	08 2f       	mov	r16, r24
     3e7e:	10 e0       	ldi	r17, 0x00	; 0
-    3e80:	87 d0       	rcall	.+270    	; 0x3f90 <getch>
+    3e80:	96 d0       	rcall	.+300    	; 0x3fae <getch>
     3e82:	90 e0       	ldi	r25, 0x00	; 0
     3e84:	98 2f       	mov	r25, r24
     3e86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     3e90:	90 93 01 02 	sts	0x0201, r25
     3e94:	80 93 00 02 	sts	0x0200, r24
-    3e98:	6f c0       	rjmp	.+222    	; 0x3f78 <main+0x178>
+    3e98:	7e c0       	rjmp	.+252    	; 0x3f96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3e9e:	84 e0       	ldi	r24, 0x04	; 4
-    3ea0:	95 d0       	rcall	.+298    	; 0x3fcc <verifySpace+0xc>
+    3ea0:	a4 d0       	rcall	.+328    	; 0x3fea <verifySpace+0xc>
       putch(0x00);
     3ea2:	80 e0       	ldi	r24, 0x00	; 0
-    3ea4:	6d d0       	rcall	.+218    	; 0x3f80 <putch>
-    3ea6:	69 c0       	rjmp	.+210    	; 0x3f7a <main+0x17a>
+    3ea4:	7c d0       	rcall	.+248    	; 0x3f9e <putch>
+    3ea6:	78 c0       	rjmp	.+240    	; 0x3f98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     3ea8:	84 36       	cpi	r24, 0x64	; 100
     3eaa:	09 f0       	breq	.+2      	; 0x3eae <main+0xae>
-    3eac:	3f c0       	rjmp	.+126    	; 0x3f2c <main+0x12c>
+    3eac:	4e c0       	rjmp	.+156    	; 0x3f4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    3eae:	78 d0       	rcall	.+240    	; 0x3fa0 <getLen>
+    3eae:	87 d0       	rcall	.+270    	; 0x3fbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3eb0:	e0 91 00 02 	lds	r30, 0x0200
     3eb4:	f0 91 01 02 	lds	r31, 0x0201
-    3eb8:	83 e0       	ldi	r24, 0x03	; 3
-    3eba:	87 bf       	out	0x37, r24	; 55
-    3ebc:	e8 95       	spm
-    3ebe:	c0 e0       	ldi	r28, 0x00	; 0
-    3ec0:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	88 e3       	ldi	r24, 0x38	; 56
+    3eba:	e0 30       	cpi	r30, 0x00	; 0
+    3ebc:	f8 07       	cpc	r31, r24
+    3ebe:	18 f4       	brcc	.+6      	; 0x3ec6 <main+0xc6>
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	87 bf       	out	0x37, r24	; 55
+    3ec4:	e8 95       	spm
+    3ec6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ec8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ec2:	66 d0       	rcall	.+204    	; 0x3f90 <getch>
-    3ec4:	89 93       	st	Y+, r24
+    3eca:	71 d0       	rcall	.+226    	; 0x3fae <getch>
+    3ecc:	89 93       	st	Y+, r24
       while (--length);
-    3ec6:	80 91 02 02 	lds	r24, 0x0202
-    3eca:	81 50       	subi	r24, 0x01	; 1
-    3ecc:	80 93 02 02 	sts	0x0202, r24
-    3ed0:	88 23       	and	r24, r24
-    3ed2:	b9 f7       	brne	.-18     	; 0x3ec2 <main+0xc2>
+    3ece:	80 91 02 02 	lds	r24, 0x0202
+    3ed2:	81 50       	subi	r24, 0x01	; 1
+    3ed4:	80 93 02 02 	sts	0x0202, r24
+    3ed8:	88 23       	and	r24, r24
+    3eda:	b9 f7       	brne	.-18     	; 0x3eca <main+0xca>
+
+      // 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);
+    3edc:	e0 91 00 02 	lds	r30, 0x0200
+    3ee0:	f0 91 01 02 	lds	r31, 0x0201
+    3ee4:	88 e3       	ldi	r24, 0x38	; 56
+    3ee6:	e0 30       	cpi	r30, 0x00	; 0
+    3ee8:	f8 07       	cpc	r31, r24
+    3eea:	18 f0       	brcs	.+6      	; 0x3ef2 <main+0xf2>
+    3eec:	83 e0       	ldi	r24, 0x03	; 3
+    3eee:	87 bf       	out	0x37, r24	; 55
+    3ef0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ed4:	75 d0       	rcall	.+234    	; 0x3fc0 <verifySpace>
+    3ef2:	75 d0       	rcall	.+234    	; 0x3fde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3ed6:	07 b6       	in	r0, 0x37	; 55
-    3ed8:	00 fc       	sbrc	r0, 0
-    3eda:	fd cf       	rjmp	.-6      	; 0x3ed6 <main+0xd6>
+    3ef4:	07 b6       	in	r0, 0x37	; 55
+    3ef6:	00 fc       	sbrc	r0, 0
+    3ef8:	fd cf       	rjmp	.-6      	; 0x3ef4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    3edc:	40 91 00 02 	lds	r20, 0x0200
-    3ee0:	50 91 01 02 	lds	r21, 0x0201
-    3ee4:	a0 e0       	ldi	r26, 0x00	; 0
-    3ee6:	b1 e0       	ldi	r27, 0x01	; 1
+    3efa:	40 91 00 02 	lds	r20, 0x0200
+    3efe:	50 91 01 02 	lds	r21, 0x0201
+    3f02:	a0 e0       	ldi	r26, 0x00	; 0
+    3f04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3ee8:	2c 91       	ld	r18, X
-    3eea:	30 e0       	ldi	r19, 0x00	; 0
+    3f06:	2c 91       	ld	r18, X
+    3f08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3eec:	11 96       	adiw	r26, 0x01	; 1
-    3eee:	8c 91       	ld	r24, X
-    3ef0:	11 97       	sbiw	r26, 0x01	; 1
-    3ef2:	90 e0       	ldi	r25, 0x00	; 0
-    3ef4:	98 2f       	mov	r25, r24
-    3ef6:	88 27       	eor	r24, r24
-    3ef8:	82 2b       	or	r24, r18
-    3efa:	93 2b       	or	r25, r19
+    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))
 #endif
 
 /* main program starts here */
 int main(void) {
-    3efc:	12 96       	adiw	r26, 0x02	; 2
+    3f1a:	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);
-    3efe:	fa 01       	movw	r30, r20
-    3f00:	0c 01       	movw	r0, r24
-    3f02:	d7 be       	out	0x37, r13	; 55
-    3f04:	e8 95       	spm
-    3f06:	11 24       	eor	r1, r1
+    3f1c:	fa 01       	movw	r30, r20
+    3f1e:	0c 01       	movw	r0, r24
+    3f20:	d7 be       	out	0x37, r13	; 55
+    3f22:	e8 95       	spm
+    3f24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f08:	4e 5f       	subi	r20, 0xFE	; 254
-    3f0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f26:	4e 5f       	subi	r20, 0xFE	; 254
+    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f0c:	f1 e0       	ldi	r31, 0x01	; 1
-    3f0e:	a0 38       	cpi	r26, 0x80	; 128
-    3f10:	bf 07       	cpc	r27, r31
-    3f12:	51 f7       	brne	.-44     	; 0x3ee8 <main+0xe8>
+    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>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f14:	e0 91 00 02 	lds	r30, 0x0200
-    3f18:	f0 91 01 02 	lds	r31, 0x0201
-    3f1c:	f7 be       	out	0x37, r15	; 55
-    3f1e:	e8 95       	spm
+    3f32:	e0 91 00 02 	lds	r30, 0x0200
+    3f36:	f0 91 01 02 	lds	r31, 0x0201
+    3f3a:	e7 be       	out	0x37, r14	; 55
+    3f3c:	e8 95       	spm
       boot_spm_busy_wait();
-    3f20:	07 b6       	in	r0, 0x37	; 55
-    3f22:	00 fc       	sbrc	r0, 0
-    3f24:	fd cf       	rjmp	.-6      	; 0x3f20 <main+0x120>
+    3f3e:	07 b6       	in	r0, 0x37	; 55
+    3f40:	00 fc       	sbrc	r0, 0
+    3f42:	fd cf       	rjmp	.-6      	; 0x3f3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f26:	e7 be       	out	0x37, r14	; 55
-    3f28:	e8 95       	spm
-    3f2a:	27 c0       	rjmp	.+78     	; 0x3f7a <main+0x17a>
+    3f44:	f7 be       	out	0x37, r15	; 55
+    3f46:	e8 95       	spm
+    3f48:	27 c0       	rjmp	.+78     	; 0x3f98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f2c:	84 37       	cpi	r24, 0x74	; 116
-    3f2e:	b9 f4       	brne	.+46     	; 0x3f5e <main+0x15e>
+    3f4a:	84 37       	cpi	r24, 0x74	; 116
+    3f4c:	b9 f4       	brne	.+46     	; 0x3f7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    3f30:	37 d0       	rcall	.+110    	; 0x3fa0 <getLen>
+    3f4e:	37 d0       	rcall	.+110    	; 0x3fbe <getLen>
       verifySpace();
-    3f32:	46 d0       	rcall	.+140    	; 0x3fc0 <verifySpace>
+    3f50:	46 d0       	rcall	.+140    	; 0x3fde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    3f34:	e0 91 00 02 	lds	r30, 0x0200
-    3f38:	f0 91 01 02 	lds	r31, 0x0201
-    3f3c:	31 96       	adiw	r30, 0x01	; 1
-    3f3e:	f0 93 01 02 	sts	0x0201, r31
-    3f42:	e0 93 00 02 	sts	0x0200, r30
-    3f46:	31 97       	sbiw	r30, 0x01	; 1
-    3f48:	e4 91       	lpm	r30, Z+
-    3f4a:	8e 2f       	mov	r24, r30
-    3f4c:	19 d0       	rcall	.+50     	; 0x3f80 <putch>
+    3f52:	e0 91 00 02 	lds	r30, 0x0200
+    3f56:	f0 91 01 02 	lds	r31, 0x0201
+    3f5a:	31 96       	adiw	r30, 0x01	; 1
+    3f5c:	f0 93 01 02 	sts	0x0201, r31
+    3f60:	e0 93 00 02 	sts	0x0200, r30
+    3f64:	31 97       	sbiw	r30, 0x01	; 1
+    3f66:	e4 91       	lpm	r30, Z+
+    3f68:	8e 2f       	mov	r24, r30
+    3f6a:	19 d0       	rcall	.+50     	; 0x3f9e <putch>
       while (--length);
-    3f4e:	80 91 02 02 	lds	r24, 0x0202
-    3f52:	81 50       	subi	r24, 0x01	; 1
-    3f54:	80 93 02 02 	sts	0x0202, r24
-    3f58:	88 23       	and	r24, r24
-    3f5a:	61 f7       	brne	.-40     	; 0x3f34 <main+0x134>
-    3f5c:	0e c0       	rjmp	.+28     	; 0x3f7a <main+0x17a>
+    3f6c:	80 91 02 02 	lds	r24, 0x0202
+    3f70:	81 50       	subi	r24, 0x01	; 1
+    3f72:	80 93 02 02 	sts	0x0202, r24
+    3f76:	88 23       	and	r24, r24
+    3f78:	61 f7       	brne	.-40     	; 0x3f52 <main+0x152>
+    3f7a:	0e c0       	rjmp	.+28     	; 0x3f98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f5e:	85 37       	cpi	r24, 0x75	; 117
-    3f60:	39 f4       	brne	.+14     	; 0x3f70 <main+0x170>
+    3f7c:	85 37       	cpi	r24, 0x75	; 117
+    3f7e:	39 f4       	brne	.+14     	; 0x3f8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f62:	2e d0       	rcall	.+92     	; 0x3fc0 <verifySpace>
+    3f80:	2e d0       	rcall	.+92     	; 0x3fde <verifySpace>
       putch(SIGNATURE_0);
-    3f64:	8e e1       	ldi	r24, 0x1E	; 30
-    3f66:	0c d0       	rcall	.+24     	; 0x3f80 <putch>
+    3f82:	8e e1       	ldi	r24, 0x1E	; 30
+    3f84:	0c d0       	rcall	.+24     	; 0x3f9e <putch>
       putch(SIGNATURE_1);
-    3f68:	84 e9       	ldi	r24, 0x94	; 148
-    3f6a:	0a d0       	rcall	.+20     	; 0x3f80 <putch>
+    3f86:	84 e9       	ldi	r24, 0x94	; 148
+    3f88:	0a d0       	rcall	.+20     	; 0x3f9e <putch>
       putch(SIGNATURE_2);
-    3f6c:	86 e0       	ldi	r24, 0x06	; 6
-    3f6e:	9a cf       	rjmp	.-204    	; 0x3ea4 <main+0xa4>
+    3f8a:	86 e0       	ldi	r24, 0x06	; 6
+    3f8c:	8b cf       	rjmp	.-234    	; 0x3ea4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    3f70:	81 35       	cpi	r24, 0x51	; 81
-    3f72:	11 f4       	brne	.+4      	; 0x3f78 <main+0x178>
+    3f8e:	81 35       	cpi	r24, 0x51	; 81
+    3f90:	11 f4       	brne	.+4      	; 0x3f96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f74:	88 e0       	ldi	r24, 0x08	; 8
-    3f76:	19 d0       	rcall	.+50     	; 0x3faa <watchdogConfig>
+    3f92:	88 e0       	ldi	r24, 0x08	; 8
+    3f94:	19 d0       	rcall	.+50     	; 0x3fc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f78:	23 d0       	rcall	.+70     	; 0x3fc0 <verifySpace>
+    3f96:	23 d0       	rcall	.+70     	; 0x3fde <verifySpace>
     }
     putch(STK_OK);
-    3f7a:	80 e1       	ldi	r24, 0x10	; 16
-    3f7c:	01 d0       	rcall	.+2      	; 0x3f80 <putch>
-    3f7e:	6b cf       	rjmp	.-298    	; 0x3e56 <main+0x56>
+    3f98:	80 e1       	ldi	r24, 0x10	; 16
+    3f9a:	01 d0       	rcall	.+2      	; 0x3f9e <putch>
+    3f9c:	5c cf       	rjmp	.-328    	; 0x3e56 <main+0x56>
 
-00003f80 <putch>:
+00003f9e <putch>:
   }
 }
 
 void putch(char ch) {
-    3f80:	98 2f       	mov	r25, r24
+    3f9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    3f82:	80 91 c0 00 	lds	r24, 0x00C0
-    3f86:	85 ff       	sbrs	r24, 5
-    3f88:	fc cf       	rjmp	.-8      	; 0x3f82 <putch+0x2>
+    3fa0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa4:	85 ff       	sbrs	r24, 5
+    3fa6:	fc cf       	rjmp	.-8      	; 0x3fa0 <putch+0x2>
   UDR0 = ch;
-    3f8a:	90 93 c6 00 	sts	0x00C6, r25
+    3fa8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3f8e:	08 95       	ret
+    3fac:	08 95       	ret
 
-00003f90 <getch>:
+00003fae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3f90:	a8 95       	wdr
+    3fae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    3f92:	80 91 c0 00 	lds	r24, 0x00C0
-    3f96:	87 ff       	sbrs	r24, 7
-    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <getch+0x2>
+    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fb4:	87 ff       	sbrs	r24, 7
+    3fb6:	fc cf       	rjmp	.-8      	; 0x3fb0 <getch+0x2>
   ch = UDR0;
-    3f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    3f9e:	08 95       	ret
+    3fbc:	08 95       	ret
 
-00003fa0 <getLen>:
+00003fbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    3fa0:	f7 df       	rcall	.-18     	; 0x3f90 <getch>
+    3fbe:	f7 df       	rcall	.-18     	; 0x3fae <getch>
   length = getch();
-    3fa2:	f6 df       	rcall	.-20     	; 0x3f90 <getch>
-    3fa4:	80 93 02 02 	sts	0x0202, r24
+    3fc0:	f6 df       	rcall	.-20     	; 0x3fae <getch>
+    3fc2:	80 93 02 02 	sts	0x0202, r24
   return getch();
 }
-    3fa8:	f3 cf       	rjmp	.-26     	; 0x3f90 <getch>
+    3fc6:	f3 cf       	rjmp	.-26     	; 0x3fae <getch>
 
-00003faa <watchdogConfig>:
+00003fc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3faa:	e0 e6       	ldi	r30, 0x60	; 96
-    3fac:	f0 e0       	ldi	r31, 0x00	; 0
-    3fae:	98 e1       	ldi	r25, 0x18	; 24
-    3fb0:	90 83       	st	Z, r25
+    3fc8:	e0 e6       	ldi	r30, 0x60	; 96
+    3fca:	f0 e0       	ldi	r31, 0x00	; 0
+    3fcc:	98 e1       	ldi	r25, 0x18	; 24
+    3fce:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fb2:	80 83       	st	Z, r24
+    3fd0:	80 83       	st	Z, r24
 }
-    3fb4:	08 95       	ret
+    3fd2:	08 95       	ret
 
-00003fb6 <appStart>:
+00003fd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fb6:	80 e0       	ldi	r24, 0x00	; 0
-    3fb8:	f8 df       	rcall	.-16     	; 0x3faa <watchdogConfig>
+    3fd4:	80 e0       	ldi	r24, 0x00	; 0
+    3fd6:	f8 df       	rcall	.-16     	; 0x3fc8 <watchdogConfig>
   __asm__ __volatile__ (
-    3fba:	ee 27       	eor	r30, r30
-    3fbc:	ff 27       	eor	r31, r31
-    3fbe:	09 94       	ijmp
+    3fd8:	ee 27       	eor	r30, r30
+    3fda:	ff 27       	eor	r31, r31
+    3fdc:	09 94       	ijmp
 
-00003fc0 <verifySpace>:
+00003fde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    3fc0:	e7 df       	rcall	.-50     	; 0x3f90 <getch>
-    3fc2:	80 32       	cpi	r24, 0x20	; 32
-    3fc4:	09 f0       	breq	.+2      	; 0x3fc8 <verifySpace+0x8>
-    3fc6:	f7 df       	rcall	.-18     	; 0x3fb6 <appStart>
+    3fde:	e7 df       	rcall	.-50     	; 0x3fae <getch>
+    3fe0:	80 32       	cpi	r24, 0x20	; 32
+    3fe2:	09 f0       	breq	.+2      	; 0x3fe6 <verifySpace+0x8>
+    3fe4:	f7 df       	rcall	.-18     	; 0x3fd4 <appStart>
   putch(STK_INSYNC);
-    3fc8:	84 e1       	ldi	r24, 0x14	; 20
+    3fe6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fca:	da cf       	rjmp	.-76     	; 0x3f80 <putch>
+    3fe8:	da cf       	rjmp	.-76     	; 0x3f9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fcc:	1f 93       	push	r17
-    3fce:	18 2f       	mov	r17, r24
+    3fea:	1f 93       	push	r17
+    3fec:	18 2f       	mov	r17, r24
 
-00003fd0 <getNch>:
+00003fee <getNch>:
   do getch(); while (--count);
-    3fd0:	df df       	rcall	.-66     	; 0x3f90 <getch>
-    3fd2:	11 50       	subi	r17, 0x01	; 1
-    3fd4:	e9 f7       	brne	.-6      	; 0x3fd0 <getNch>
+    3fee:	df df       	rcall	.-66     	; 0x3fae <getch>
+    3ff0:	11 50       	subi	r17, 0x01	; 1
+    3ff2:	e9 f7       	brne	.-6      	; 0x3fee <getNch>
   verifySpace();
-    3fd6:	f4 df       	rcall	.-24     	; 0x3fc0 <verifySpace>
+    3ff4:	f4 df       	rcall	.-24     	; 0x3fde <verifySpace>
 }
-    3fd8:	1f 91       	pop	r17
-    3fda:	08 95       	ret
+    3ff6:	1f 91       	pop	r17
+    3ff8:	08 95       	ret

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

@@ -7,9 +7,9 @@
 :101D600081F4D7D0082F10E0D4D090E0982F8827A6
 :101D7000802B912B880F991F909381018093800174
 :101D8000B5C0863529F484E0ECD080E0B3D0AFC094
-:101D9000843609F06BC0D1D0E0918001F0918101CF
-:101DA00083E087BFE895C0E0D1E0B3D0899380910C
-:101DB00082018150809382018823B9F7CCD007B685
+:101D9000843609F06BC0D1D0C0E0D1E0BAD08993CD
+:101DA000809182018150809382018823B9F7E0916C
+:101DB0008001F091810183E087BFE895CCD007B620
 :101DC00000FCFDCF8091800190918101892B41F52C
 :101DD000809100012091010130E0322F222790E014
 :101DE000282B392B309385012093840140910801E1

+ 23 - 20
optiboot/bootloaders/optiboot/optiboot_luminet.lst

@@ -9,11 +9,11 @@ Idx Name          Size      VMA       LMA       File off  Algn
                   CONTENTS, READONLY, DEBUGGING
   2 .debug_pubnames 00000078  00000000  00000000  000002ee  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   000002a3  00000000  00000000  00000366  2**0
+  3 .debug_info   000002a4  00000000  00000000  00000366  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ac  00000000  00000000  00000609  2**0
+  4 .debug_abbrev 000001ac  00000000  00000000  0000060a  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   0000043d  00000000  00000000  000007b5  2**0
+  5 .debug_line   0000043d  00000000  00000000  000007b6  2**0
                   CONTENTS, READONLY, DEBUGGING
   6 .debug_frame  000000a0  00000000  00000000  00000bf4  2**2
                   CONTENTS, READONLY, DEBUGGING
@@ -217,28 +217,31 @@ void watchdogReset() {
 
       getLen();
     1d96:	d1 d0       	rcall	.+418    	; 0x1f3a <getLen>
-
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
-    1d98:	e0 91 80 01 	lds	r30, 0x0180
-    1d9c:	f0 91 81 01 	lds	r31, 0x0181
-    1da0:	83 e0       	ldi	r24, 0x03	; 3
-    1da2:	87 bf       	out	0x37, r24	; 55
-    1da4:	e8 95       	spm
-    1da6:	c0 e0       	ldi	r28, 0x00	; 0
-    1da8:	d1 e0       	ldi	r29, 0x01	; 1
+    1d98:	c0 e0       	ldi	r28, 0x00	; 0
+    1d9a:	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();
-    1daa:	b3 d0       	rcall	.+358    	; 0x1f12 <getch>
-    1dac:	89 93       	st	Y+, r24
+    1d9c:	ba d0       	rcall	.+372    	; 0x1f12 <getch>
+    1d9e:	89 93       	st	Y+, r24
       while (--length);
-    1dae:	80 91 82 01 	lds	r24, 0x0182
-    1db2:	81 50       	subi	r24, 0x01	; 1
-    1db4:	80 93 82 01 	sts	0x0182, r24
-    1db8:	88 23       	and	r24, r24
-    1dba:	b9 f7       	brne	.-18     	; 0x1daa <main+0xaa>
+    1da0:	80 91 82 01 	lds	r24, 0x0182
+    1da4:	81 50       	subi	r24, 0x01	; 1
+    1da6:	80 93 82 01 	sts	0x0182, r24
+    1daa:	88 23       	and	r24, r24
+    1dac:	b9 f7       	brne	.-18     	; 0x1d9c <main+0x9c>
+
+      // 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);
+    1dae:	e0 91 80 01 	lds	r30, 0x0180
+    1db2:	f0 91 81 01 	lds	r31, 0x0181
+    1db6:	83 e0       	ldi	r24, 0x03	; 3
+    1db8:	87 bf       	out	0x37, r24	; 55
+    1dba:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_pro_16MHz.hex

@@ -1,32 +1,34 @@
 :103E000085E08093810082E08093C00088E1809308
 :103E1000C10086E08093C20080E18093C40084B733
-:103E200014BE81FFC8D08DE0C0D0259A86E020E383
+:103E200014BE81FFD7D08DE0CFD0259A86E020E365
 :103E30003CEF91E0309385002093840096BBB09BCB
 :103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000FA2EF1E1EF2E9CD0813421F481E0B6D02E
+:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010
 :103E600083E020C0823411F484E103C0853419F466
-:103E700085E0ACD082C0853581F48AD0082F10E06F
-:103E800087D090E0982F8827802B912B880F991F3F
-:103E900090930102809300026FC0863529F484E07C
-:103EA00095D080E06DD069C0843609F03FC078D0ED
-:103EB000E0910002F091010283E087BFE895C0E045
-:103EC000D1E066D0899380910202815080930202F2
-:103ED0008823B9F775D007B600FCFDCF40910002EA
-:103EE00050910102A0E0B1E02C9130E011968C914C
-:103EF000119790E0982F8827822B932B1296FA0126
-:103F00000C01D7BEE89511244E5F5F4FF1E0A03859
-:103F1000BF0751F7E0910002F0910102F7BEE8956A
-:103F200007B600FCFDCFE7BEE89527C08437B9F49B
-:103F300037D046D0E0910002F09101023196F09323
-:103F40000102E09300023197E4918E2F19D0809105
-:103F50000202815080930202882361F70EC08537E8
-:103F600039F42ED08EE10CD084E90AD086E09ACFC5
-:103F7000813511F488E019D023D080E101D06BCFD6
-:103F8000982F8091C00085FFFCCF9093C6000895C4
-:103F9000A8958091C00087FFFCCF8091C60008954E
-:103FA000F7DFF6DF80930202F3CFE0E6F0E098E17E
-:103FB00090838083089580E0F8DFEE27FF2709943F
-:103FC000E7DF803209F0F7DF84E1DACF1F93182FA3
-:0C3FD000DFDF1150E9F7F4DF1F910895C6
+:103E700085E0BBD091C0853581F499D0082F10E042
+:103E800096D090E0982F8827802B912B880F991F30
+:103E900090930102809300027EC0863529F484E06D
+:103EA000A4D080E07CD078C0843609F04EC087D0A2
+:103EB000E0910002F091010288E3E030F80718F485
+:103EC00083E087BFE895C0E0D1E071D0899380910D
+:103ED00002028150809302028823B9F7E091000228
+:103EE000F091010288E3E030F80718F083E087BF23
+:103EF000E89575D007B600FCFDCF409100025091C7
+:103F00000102A0E0B1E02C9130E011968C91119764
+:103F100090E0982F8827822B932B1296FA010C01A0
+:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780
+:103F300051F7E0910002F0910102E7BEE89507B663
+:103F400000FCFDCFF7BEE89527C08437B9F437D021
+:103F500046D0E0910002F09101023196F093010207
+:103F6000E09300023197E4918E2F19D080910202E4
+:103F7000815080930202882361F70EC0853739F49F
+:103F80002ED08EE10CD084E90AD086E08BCF81352B
+:103F900011F488E019D023D080E101D05CCF982FB4
+:103FA0008091C00085FFFCCF9093C6000895A8952E
+:103FB0008091C00087FFFCCF8091C6000895F7DF95
+:103FC000F6DF80930202F3CFE0E6F0E098E1908321
+:103FD0008083089580E0F8DFEE27FF270994E7DF6C
+:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B
+:0A3FF0001150E9F7F4DF1F91089566
 :0400000300003E00BB
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst

@@ -3,25 +3,25 @@ optiboot_pro_16MHz.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  00003e00  00003e00  00000054  2**1
+  0 .text         000001fa  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e22:	81 ff       	sbrs	r24, 1
-    3e24:	c8 d0       	rcall	.+400    	; 0x3fb6 <appStart>
+    3e24:	d7 d0       	rcall	.+430    	; 0x3fd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     3e26:	8d e0       	ldi	r24, 0x0D	; 13
-    3e28:	c0 d0       	rcall	.+384    	; 0x3faa <watchdogConfig>
+    3e28:	cf d0       	rcall	.+414    	; 0x3fc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e4e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e50:	fa 2e       	mov	r15, r26
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e52:	f1 e1       	ldi	r31, 0x11	; 17
-    3e54:	ef 2e       	mov	r14, r31
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e56:	9c d0       	rcall	.+312    	; 0x3f90 <getch>
+    3e56:	ab d0       	rcall	.+342    	; 0x3fae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     3e5c:	81 e0       	ldi	r24, 0x01	; 1
-    3e5e:	b6 d0       	rcall	.+364    	; 0x3fcc <verifySpace+0xc>
+    3e5e:	c5 d0       	rcall	.+394    	; 0x3fea <verifySpace+0xc>
       putch(0x03);
     3e60:	83 e0       	ldi	r24, 0x03	; 3
     3e62:	20 c0       	rjmp	.+64     	; 0x3ea4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e70:	85 e0       	ldi	r24, 0x05	; 5
-    3e72:	ac d0       	rcall	.+344    	; 0x3fcc <verifySpace+0xc>
-    3e74:	82 c0       	rjmp	.+260    	; 0x3f7a <main+0x17a>
+    3e72:	bb d0       	rcall	.+374    	; 0x3fea <verifySpace+0xc>
+    3e74:	91 c0       	rjmp	.+290    	; 0x3f98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e7a:	8a d0       	rcall	.+276    	; 0x3f90 <getch>
+    3e7a:	99 d0       	rcall	.+306    	; 0x3fae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e7c:	08 2f       	mov	r16, r24
     3e7e:	10 e0       	ldi	r17, 0x00	; 0
-    3e80:	87 d0       	rcall	.+270    	; 0x3f90 <getch>
+    3e80:	96 d0       	rcall	.+300    	; 0x3fae <getch>
     3e82:	90 e0       	ldi	r25, 0x00	; 0
     3e84:	98 2f       	mov	r25, r24
     3e86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     3e90:	90 93 01 02 	sts	0x0201, r25
     3e94:	80 93 00 02 	sts	0x0200, r24
-    3e98:	6f c0       	rjmp	.+222    	; 0x3f78 <main+0x178>
+    3e98:	7e c0       	rjmp	.+252    	; 0x3f96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3e9e:	84 e0       	ldi	r24, 0x04	; 4
-    3ea0:	95 d0       	rcall	.+298    	; 0x3fcc <verifySpace+0xc>
+    3ea0:	a4 d0       	rcall	.+328    	; 0x3fea <verifySpace+0xc>
       putch(0x00);
     3ea2:	80 e0       	ldi	r24, 0x00	; 0
-    3ea4:	6d d0       	rcall	.+218    	; 0x3f80 <putch>
-    3ea6:	69 c0       	rjmp	.+210    	; 0x3f7a <main+0x17a>
+    3ea4:	7c d0       	rcall	.+248    	; 0x3f9e <putch>
+    3ea6:	78 c0       	rjmp	.+240    	; 0x3f98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     3ea8:	84 36       	cpi	r24, 0x64	; 100
     3eaa:	09 f0       	breq	.+2      	; 0x3eae <main+0xae>
-    3eac:	3f c0       	rjmp	.+126    	; 0x3f2c <main+0x12c>
+    3eac:	4e c0       	rjmp	.+156    	; 0x3f4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    3eae:	78 d0       	rcall	.+240    	; 0x3fa0 <getLen>
+    3eae:	87 d0       	rcall	.+270    	; 0x3fbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3eb0:	e0 91 00 02 	lds	r30, 0x0200
     3eb4:	f0 91 01 02 	lds	r31, 0x0201
-    3eb8:	83 e0       	ldi	r24, 0x03	; 3
-    3eba:	87 bf       	out	0x37, r24	; 55
-    3ebc:	e8 95       	spm
-    3ebe:	c0 e0       	ldi	r28, 0x00	; 0
-    3ec0:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	88 e3       	ldi	r24, 0x38	; 56
+    3eba:	e0 30       	cpi	r30, 0x00	; 0
+    3ebc:	f8 07       	cpc	r31, r24
+    3ebe:	18 f4       	brcc	.+6      	; 0x3ec6 <main+0xc6>
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	87 bf       	out	0x37, r24	; 55
+    3ec4:	e8 95       	spm
+    3ec6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ec8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ec2:	66 d0       	rcall	.+204    	; 0x3f90 <getch>
-    3ec4:	89 93       	st	Y+, r24
+    3eca:	71 d0       	rcall	.+226    	; 0x3fae <getch>
+    3ecc:	89 93       	st	Y+, r24
       while (--length);
-    3ec6:	80 91 02 02 	lds	r24, 0x0202
-    3eca:	81 50       	subi	r24, 0x01	; 1
-    3ecc:	80 93 02 02 	sts	0x0202, r24
-    3ed0:	88 23       	and	r24, r24
-    3ed2:	b9 f7       	brne	.-18     	; 0x3ec2 <main+0xc2>
+    3ece:	80 91 02 02 	lds	r24, 0x0202
+    3ed2:	81 50       	subi	r24, 0x01	; 1
+    3ed4:	80 93 02 02 	sts	0x0202, r24
+    3ed8:	88 23       	and	r24, r24
+    3eda:	b9 f7       	brne	.-18     	; 0x3eca <main+0xca>
+
+      // 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);
+    3edc:	e0 91 00 02 	lds	r30, 0x0200
+    3ee0:	f0 91 01 02 	lds	r31, 0x0201
+    3ee4:	88 e3       	ldi	r24, 0x38	; 56
+    3ee6:	e0 30       	cpi	r30, 0x00	; 0
+    3ee8:	f8 07       	cpc	r31, r24
+    3eea:	18 f0       	brcs	.+6      	; 0x3ef2 <main+0xf2>
+    3eec:	83 e0       	ldi	r24, 0x03	; 3
+    3eee:	87 bf       	out	0x37, r24	; 55
+    3ef0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ed4:	75 d0       	rcall	.+234    	; 0x3fc0 <verifySpace>
+    3ef2:	75 d0       	rcall	.+234    	; 0x3fde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3ed6:	07 b6       	in	r0, 0x37	; 55
-    3ed8:	00 fc       	sbrc	r0, 0
-    3eda:	fd cf       	rjmp	.-6      	; 0x3ed6 <main+0xd6>
+    3ef4:	07 b6       	in	r0, 0x37	; 55
+    3ef6:	00 fc       	sbrc	r0, 0
+    3ef8:	fd cf       	rjmp	.-6      	; 0x3ef4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    3edc:	40 91 00 02 	lds	r20, 0x0200
-    3ee0:	50 91 01 02 	lds	r21, 0x0201
-    3ee4:	a0 e0       	ldi	r26, 0x00	; 0
-    3ee6:	b1 e0       	ldi	r27, 0x01	; 1
+    3efa:	40 91 00 02 	lds	r20, 0x0200
+    3efe:	50 91 01 02 	lds	r21, 0x0201
+    3f02:	a0 e0       	ldi	r26, 0x00	; 0
+    3f04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3ee8:	2c 91       	ld	r18, X
-    3eea:	30 e0       	ldi	r19, 0x00	; 0
+    3f06:	2c 91       	ld	r18, X
+    3f08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3eec:	11 96       	adiw	r26, 0x01	; 1
-    3eee:	8c 91       	ld	r24, X
-    3ef0:	11 97       	sbiw	r26, 0x01	; 1
-    3ef2:	90 e0       	ldi	r25, 0x00	; 0
-    3ef4:	98 2f       	mov	r25, r24
-    3ef6:	88 27       	eor	r24, r24
-    3ef8:	82 2b       	or	r24, r18
-    3efa:	93 2b       	or	r25, r19
+    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))
 #endif
 
 /* main program starts here */
 int main(void) {
-    3efc:	12 96       	adiw	r26, 0x02	; 2
+    3f1a:	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);
-    3efe:	fa 01       	movw	r30, r20
-    3f00:	0c 01       	movw	r0, r24
-    3f02:	d7 be       	out	0x37, r13	; 55
-    3f04:	e8 95       	spm
-    3f06:	11 24       	eor	r1, r1
+    3f1c:	fa 01       	movw	r30, r20
+    3f1e:	0c 01       	movw	r0, r24
+    3f20:	d7 be       	out	0x37, r13	; 55
+    3f22:	e8 95       	spm
+    3f24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f08:	4e 5f       	subi	r20, 0xFE	; 254
-    3f0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f26:	4e 5f       	subi	r20, 0xFE	; 254
+    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f0c:	f1 e0       	ldi	r31, 0x01	; 1
-    3f0e:	a0 38       	cpi	r26, 0x80	; 128
-    3f10:	bf 07       	cpc	r27, r31
-    3f12:	51 f7       	brne	.-44     	; 0x3ee8 <main+0xe8>
+    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>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f14:	e0 91 00 02 	lds	r30, 0x0200
-    3f18:	f0 91 01 02 	lds	r31, 0x0201
-    3f1c:	f7 be       	out	0x37, r15	; 55
-    3f1e:	e8 95       	spm
+    3f32:	e0 91 00 02 	lds	r30, 0x0200
+    3f36:	f0 91 01 02 	lds	r31, 0x0201
+    3f3a:	e7 be       	out	0x37, r14	; 55
+    3f3c:	e8 95       	spm
       boot_spm_busy_wait();
-    3f20:	07 b6       	in	r0, 0x37	; 55
-    3f22:	00 fc       	sbrc	r0, 0
-    3f24:	fd cf       	rjmp	.-6      	; 0x3f20 <main+0x120>
+    3f3e:	07 b6       	in	r0, 0x37	; 55
+    3f40:	00 fc       	sbrc	r0, 0
+    3f42:	fd cf       	rjmp	.-6      	; 0x3f3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f26:	e7 be       	out	0x37, r14	; 55
-    3f28:	e8 95       	spm
-    3f2a:	27 c0       	rjmp	.+78     	; 0x3f7a <main+0x17a>
+    3f44:	f7 be       	out	0x37, r15	; 55
+    3f46:	e8 95       	spm
+    3f48:	27 c0       	rjmp	.+78     	; 0x3f98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f2c:	84 37       	cpi	r24, 0x74	; 116
-    3f2e:	b9 f4       	brne	.+46     	; 0x3f5e <main+0x15e>
+    3f4a:	84 37       	cpi	r24, 0x74	; 116
+    3f4c:	b9 f4       	brne	.+46     	; 0x3f7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    3f30:	37 d0       	rcall	.+110    	; 0x3fa0 <getLen>
+    3f4e:	37 d0       	rcall	.+110    	; 0x3fbe <getLen>
       verifySpace();
-    3f32:	46 d0       	rcall	.+140    	; 0x3fc0 <verifySpace>
+    3f50:	46 d0       	rcall	.+140    	; 0x3fde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    3f34:	e0 91 00 02 	lds	r30, 0x0200
-    3f38:	f0 91 01 02 	lds	r31, 0x0201
-    3f3c:	31 96       	adiw	r30, 0x01	; 1
-    3f3e:	f0 93 01 02 	sts	0x0201, r31
-    3f42:	e0 93 00 02 	sts	0x0200, r30
-    3f46:	31 97       	sbiw	r30, 0x01	; 1
-    3f48:	e4 91       	lpm	r30, Z+
-    3f4a:	8e 2f       	mov	r24, r30
-    3f4c:	19 d0       	rcall	.+50     	; 0x3f80 <putch>
+    3f52:	e0 91 00 02 	lds	r30, 0x0200
+    3f56:	f0 91 01 02 	lds	r31, 0x0201
+    3f5a:	31 96       	adiw	r30, 0x01	; 1
+    3f5c:	f0 93 01 02 	sts	0x0201, r31
+    3f60:	e0 93 00 02 	sts	0x0200, r30
+    3f64:	31 97       	sbiw	r30, 0x01	; 1
+    3f66:	e4 91       	lpm	r30, Z+
+    3f68:	8e 2f       	mov	r24, r30
+    3f6a:	19 d0       	rcall	.+50     	; 0x3f9e <putch>
       while (--length);
-    3f4e:	80 91 02 02 	lds	r24, 0x0202
-    3f52:	81 50       	subi	r24, 0x01	; 1
-    3f54:	80 93 02 02 	sts	0x0202, r24
-    3f58:	88 23       	and	r24, r24
-    3f5a:	61 f7       	brne	.-40     	; 0x3f34 <main+0x134>
-    3f5c:	0e c0       	rjmp	.+28     	; 0x3f7a <main+0x17a>
+    3f6c:	80 91 02 02 	lds	r24, 0x0202
+    3f70:	81 50       	subi	r24, 0x01	; 1
+    3f72:	80 93 02 02 	sts	0x0202, r24
+    3f76:	88 23       	and	r24, r24
+    3f78:	61 f7       	brne	.-40     	; 0x3f52 <main+0x152>
+    3f7a:	0e c0       	rjmp	.+28     	; 0x3f98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f5e:	85 37       	cpi	r24, 0x75	; 117
-    3f60:	39 f4       	brne	.+14     	; 0x3f70 <main+0x170>
+    3f7c:	85 37       	cpi	r24, 0x75	; 117
+    3f7e:	39 f4       	brne	.+14     	; 0x3f8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f62:	2e d0       	rcall	.+92     	; 0x3fc0 <verifySpace>
+    3f80:	2e d0       	rcall	.+92     	; 0x3fde <verifySpace>
       putch(SIGNATURE_0);
-    3f64:	8e e1       	ldi	r24, 0x1E	; 30
-    3f66:	0c d0       	rcall	.+24     	; 0x3f80 <putch>
+    3f82:	8e e1       	ldi	r24, 0x1E	; 30
+    3f84:	0c d0       	rcall	.+24     	; 0x3f9e <putch>
       putch(SIGNATURE_1);
-    3f68:	84 e9       	ldi	r24, 0x94	; 148
-    3f6a:	0a d0       	rcall	.+20     	; 0x3f80 <putch>
+    3f86:	84 e9       	ldi	r24, 0x94	; 148
+    3f88:	0a d0       	rcall	.+20     	; 0x3f9e <putch>
       putch(SIGNATURE_2);
-    3f6c:	86 e0       	ldi	r24, 0x06	; 6
-    3f6e:	9a cf       	rjmp	.-204    	; 0x3ea4 <main+0xa4>
+    3f8a:	86 e0       	ldi	r24, 0x06	; 6
+    3f8c:	8b cf       	rjmp	.-234    	; 0x3ea4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    3f70:	81 35       	cpi	r24, 0x51	; 81
-    3f72:	11 f4       	brne	.+4      	; 0x3f78 <main+0x178>
+    3f8e:	81 35       	cpi	r24, 0x51	; 81
+    3f90:	11 f4       	brne	.+4      	; 0x3f96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f74:	88 e0       	ldi	r24, 0x08	; 8
-    3f76:	19 d0       	rcall	.+50     	; 0x3faa <watchdogConfig>
+    3f92:	88 e0       	ldi	r24, 0x08	; 8
+    3f94:	19 d0       	rcall	.+50     	; 0x3fc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f78:	23 d0       	rcall	.+70     	; 0x3fc0 <verifySpace>
+    3f96:	23 d0       	rcall	.+70     	; 0x3fde <verifySpace>
     }
     putch(STK_OK);
-    3f7a:	80 e1       	ldi	r24, 0x10	; 16
-    3f7c:	01 d0       	rcall	.+2      	; 0x3f80 <putch>
-    3f7e:	6b cf       	rjmp	.-298    	; 0x3e56 <main+0x56>
+    3f98:	80 e1       	ldi	r24, 0x10	; 16
+    3f9a:	01 d0       	rcall	.+2      	; 0x3f9e <putch>
+    3f9c:	5c cf       	rjmp	.-328    	; 0x3e56 <main+0x56>
 
-00003f80 <putch>:
+00003f9e <putch>:
   }
 }
 
 void putch(char ch) {
-    3f80:	98 2f       	mov	r25, r24
+    3f9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    3f82:	80 91 c0 00 	lds	r24, 0x00C0
-    3f86:	85 ff       	sbrs	r24, 5
-    3f88:	fc cf       	rjmp	.-8      	; 0x3f82 <putch+0x2>
+    3fa0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa4:	85 ff       	sbrs	r24, 5
+    3fa6:	fc cf       	rjmp	.-8      	; 0x3fa0 <putch+0x2>
   UDR0 = ch;
-    3f8a:	90 93 c6 00 	sts	0x00C6, r25
+    3fa8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3f8e:	08 95       	ret
+    3fac:	08 95       	ret
 
-00003f90 <getch>:
+00003fae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3f90:	a8 95       	wdr
+    3fae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    3f92:	80 91 c0 00 	lds	r24, 0x00C0
-    3f96:	87 ff       	sbrs	r24, 7
-    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <getch+0x2>
+    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fb4:	87 ff       	sbrs	r24, 7
+    3fb6:	fc cf       	rjmp	.-8      	; 0x3fb0 <getch+0x2>
   ch = UDR0;
-    3f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    3f9e:	08 95       	ret
+    3fbc:	08 95       	ret
 
-00003fa0 <getLen>:
+00003fbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    3fa0:	f7 df       	rcall	.-18     	; 0x3f90 <getch>
+    3fbe:	f7 df       	rcall	.-18     	; 0x3fae <getch>
   length = getch();
-    3fa2:	f6 df       	rcall	.-20     	; 0x3f90 <getch>
-    3fa4:	80 93 02 02 	sts	0x0202, r24
+    3fc0:	f6 df       	rcall	.-20     	; 0x3fae <getch>
+    3fc2:	80 93 02 02 	sts	0x0202, r24
   return getch();
 }
-    3fa8:	f3 cf       	rjmp	.-26     	; 0x3f90 <getch>
+    3fc6:	f3 cf       	rjmp	.-26     	; 0x3fae <getch>
 
-00003faa <watchdogConfig>:
+00003fc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3faa:	e0 e6       	ldi	r30, 0x60	; 96
-    3fac:	f0 e0       	ldi	r31, 0x00	; 0
-    3fae:	98 e1       	ldi	r25, 0x18	; 24
-    3fb0:	90 83       	st	Z, r25
+    3fc8:	e0 e6       	ldi	r30, 0x60	; 96
+    3fca:	f0 e0       	ldi	r31, 0x00	; 0
+    3fcc:	98 e1       	ldi	r25, 0x18	; 24
+    3fce:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fb2:	80 83       	st	Z, r24
+    3fd0:	80 83       	st	Z, r24
 }
-    3fb4:	08 95       	ret
+    3fd2:	08 95       	ret
 
-00003fb6 <appStart>:
+00003fd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fb6:	80 e0       	ldi	r24, 0x00	; 0
-    3fb8:	f8 df       	rcall	.-16     	; 0x3faa <watchdogConfig>
+    3fd4:	80 e0       	ldi	r24, 0x00	; 0
+    3fd6:	f8 df       	rcall	.-16     	; 0x3fc8 <watchdogConfig>
   __asm__ __volatile__ (
-    3fba:	ee 27       	eor	r30, r30
-    3fbc:	ff 27       	eor	r31, r31
-    3fbe:	09 94       	ijmp
+    3fd8:	ee 27       	eor	r30, r30
+    3fda:	ff 27       	eor	r31, r31
+    3fdc:	09 94       	ijmp
 
-00003fc0 <verifySpace>:
+00003fde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    3fc0:	e7 df       	rcall	.-50     	; 0x3f90 <getch>
-    3fc2:	80 32       	cpi	r24, 0x20	; 32
-    3fc4:	09 f0       	breq	.+2      	; 0x3fc8 <verifySpace+0x8>
-    3fc6:	f7 df       	rcall	.-18     	; 0x3fb6 <appStart>
+    3fde:	e7 df       	rcall	.-50     	; 0x3fae <getch>
+    3fe0:	80 32       	cpi	r24, 0x20	; 32
+    3fe2:	09 f0       	breq	.+2      	; 0x3fe6 <verifySpace+0x8>
+    3fe4:	f7 df       	rcall	.-18     	; 0x3fd4 <appStart>
   putch(STK_INSYNC);
-    3fc8:	84 e1       	ldi	r24, 0x14	; 20
+    3fe6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fca:	da cf       	rjmp	.-76     	; 0x3f80 <putch>
+    3fe8:	da cf       	rjmp	.-76     	; 0x3f9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fcc:	1f 93       	push	r17
-    3fce:	18 2f       	mov	r17, r24
+    3fea:	1f 93       	push	r17
+    3fec:	18 2f       	mov	r17, r24
 
-00003fd0 <getNch>:
+00003fee <getNch>:
   do getch(); while (--count);
-    3fd0:	df df       	rcall	.-66     	; 0x3f90 <getch>
-    3fd2:	11 50       	subi	r17, 0x01	; 1
-    3fd4:	e9 f7       	brne	.-6      	; 0x3fd0 <getNch>
+    3fee:	df df       	rcall	.-66     	; 0x3fae <getch>
+    3ff0:	11 50       	subi	r17, 0x01	; 1
+    3ff2:	e9 f7       	brne	.-6      	; 0x3fee <getNch>
   verifySpace();
-    3fd6:	f4 df       	rcall	.-24     	; 0x3fc0 <verifySpace>
+    3ff4:	f4 df       	rcall	.-24     	; 0x3fde <verifySpace>
 }
-    3fd8:	1f 91       	pop	r17
-    3fda:	08 95       	ret
+    3ff6:	1f 91       	pop	r17
+    3ff8:	08 95       	ret

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_pro_20mhz.hex

@@ -1,32 +1,34 @@
 :103E000085E08093810082E08093C00088E1809308
 :103E1000C10086E08093C20085E18093C40084B72E
-:103E200014BE81FFC8D08DE0C0D0259A86E02CE377
+:103E200014BE81FFD7D08DE0CFD0259A86E02CE359
 :103E30003BEF91E0309385002093840096BBB09BCC
 :103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000FA2EF1E1EF2E9CD0813421F481E0B6D02E
+:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010
 :103E600083E020C0823411F484E103C0853419F466
-:103E700085E0ACD082C0853581F48AD0082F10E06F
-:103E800087D090E0982F8827802B912B880F991F3F
-:103E900090930102809300026FC0863529F484E07C
-:103EA00095D080E06DD069C0843609F03FC078D0ED
-:103EB000E0910002F091010283E087BFE895C0E045
-:103EC000D1E066D0899380910202815080930202F2
-:103ED0008823B9F775D007B600FCFDCF40910002EA
-:103EE00050910102A0E0B1E02C9130E011968C914C
-:103EF000119790E0982F8827822B932B1296FA0126
-:103F00000C01D7BEE89511244E5F5F4FF1E0A03859
-:103F1000BF0751F7E0910002F0910102F7BEE8956A
-:103F200007B600FCFDCFE7BEE89527C08437B9F49B
-:103F300037D046D0E0910002F09101023196F09323
-:103F40000102E09300023197E4918E2F19D0809105
-:103F50000202815080930202882361F70EC08537E8
-:103F600039F42ED08EE10CD084E90AD086E09ACFC5
-:103F7000813511F488E019D023D080E101D06BCFD6
-:103F8000982F8091C00085FFFCCF9093C6000895C4
-:103F9000A8958091C00087FFFCCF8091C60008954E
-:103FA000F7DFF6DF80930202F3CFE0E6F0E098E17E
-:103FB00090838083089580E0F8DFEE27FF2709943F
-:103FC000E7DF803209F0F7DF84E1DACF1F93182FA3
-:0C3FD000DFDF1150E9F7F4DF1F910895C6
+:103E700085E0BBD091C0853581F499D0082F10E042
+:103E800096D090E0982F8827802B912B880F991F30
+:103E900090930102809300027EC0863529F484E06D
+:103EA000A4D080E07CD078C0843609F04EC087D0A2
+:103EB000E0910002F091010288E3E030F80718F485
+:103EC00083E087BFE895C0E0D1E071D0899380910D
+:103ED00002028150809302028823B9F7E091000228
+:103EE000F091010288E3E030F80718F083E087BF23
+:103EF000E89575D007B600FCFDCF409100025091C7
+:103F00000102A0E0B1E02C9130E011968C91119764
+:103F100090E0982F8827822B932B1296FA010C01A0
+:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780
+:103F300051F7E0910002F0910102E7BEE89507B663
+:103F400000FCFDCFF7BEE89527C08437B9F437D021
+:103F500046D0E0910002F09101023196F093010207
+:103F6000E09300023197E4918E2F19D080910202E4
+:103F7000815080930202882361F70EC0853739F49F
+:103F80002ED08EE10CD084E90AD086E08BCF81352B
+:103F900011F488E019D023D080E101D05CCF982FB4
+:103FA0008091C00085FFFCCF9093C6000895A8952E
+:103FB0008091C00087FFFCCF8091C6000895F7DF95
+:103FC000F6DF80930202F3CFE0E6F0E098E1908321
+:103FD0008083089580E0F8DFEE27FF270994E7DF6C
+:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B
+:0A3FF0001150E9F7F4DF1F91089566
 :0400000300003E00BB
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst

@@ -3,25 +3,25 @@ optiboot_pro_20mhz.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  00003e00  00003e00  00000054  2**1
+  0 .text         000001fa  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e22:	81 ff       	sbrs	r24, 1
-    3e24:	c8 d0       	rcall	.+400    	; 0x3fb6 <appStart>
+    3e24:	d7 d0       	rcall	.+430    	; 0x3fd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     3e26:	8d e0       	ldi	r24, 0x0D	; 13
-    3e28:	c0 d0       	rcall	.+384    	; 0x3faa <watchdogConfig>
+    3e28:	cf d0       	rcall	.+414    	; 0x3fc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e4e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e50:	fa 2e       	mov	r15, r26
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e52:	f1 e1       	ldi	r31, 0x11	; 17
-    3e54:	ef 2e       	mov	r14, r31
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e56:	9c d0       	rcall	.+312    	; 0x3f90 <getch>
+    3e56:	ab d0       	rcall	.+342    	; 0x3fae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     3e5c:	81 e0       	ldi	r24, 0x01	; 1
-    3e5e:	b6 d0       	rcall	.+364    	; 0x3fcc <verifySpace+0xc>
+    3e5e:	c5 d0       	rcall	.+394    	; 0x3fea <verifySpace+0xc>
       putch(0x03);
     3e60:	83 e0       	ldi	r24, 0x03	; 3
     3e62:	20 c0       	rjmp	.+64     	; 0x3ea4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e70:	85 e0       	ldi	r24, 0x05	; 5
-    3e72:	ac d0       	rcall	.+344    	; 0x3fcc <verifySpace+0xc>
-    3e74:	82 c0       	rjmp	.+260    	; 0x3f7a <main+0x17a>
+    3e72:	bb d0       	rcall	.+374    	; 0x3fea <verifySpace+0xc>
+    3e74:	91 c0       	rjmp	.+290    	; 0x3f98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e7a:	8a d0       	rcall	.+276    	; 0x3f90 <getch>
+    3e7a:	99 d0       	rcall	.+306    	; 0x3fae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e7c:	08 2f       	mov	r16, r24
     3e7e:	10 e0       	ldi	r17, 0x00	; 0
-    3e80:	87 d0       	rcall	.+270    	; 0x3f90 <getch>
+    3e80:	96 d0       	rcall	.+300    	; 0x3fae <getch>
     3e82:	90 e0       	ldi	r25, 0x00	; 0
     3e84:	98 2f       	mov	r25, r24
     3e86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     3e90:	90 93 01 02 	sts	0x0201, r25
     3e94:	80 93 00 02 	sts	0x0200, r24
-    3e98:	6f c0       	rjmp	.+222    	; 0x3f78 <main+0x178>
+    3e98:	7e c0       	rjmp	.+252    	; 0x3f96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3e9e:	84 e0       	ldi	r24, 0x04	; 4
-    3ea0:	95 d0       	rcall	.+298    	; 0x3fcc <verifySpace+0xc>
+    3ea0:	a4 d0       	rcall	.+328    	; 0x3fea <verifySpace+0xc>
       putch(0x00);
     3ea2:	80 e0       	ldi	r24, 0x00	; 0
-    3ea4:	6d d0       	rcall	.+218    	; 0x3f80 <putch>
-    3ea6:	69 c0       	rjmp	.+210    	; 0x3f7a <main+0x17a>
+    3ea4:	7c d0       	rcall	.+248    	; 0x3f9e <putch>
+    3ea6:	78 c0       	rjmp	.+240    	; 0x3f98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     3ea8:	84 36       	cpi	r24, 0x64	; 100
     3eaa:	09 f0       	breq	.+2      	; 0x3eae <main+0xae>
-    3eac:	3f c0       	rjmp	.+126    	; 0x3f2c <main+0x12c>
+    3eac:	4e c0       	rjmp	.+156    	; 0x3f4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    3eae:	78 d0       	rcall	.+240    	; 0x3fa0 <getLen>
+    3eae:	87 d0       	rcall	.+270    	; 0x3fbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3eb0:	e0 91 00 02 	lds	r30, 0x0200
     3eb4:	f0 91 01 02 	lds	r31, 0x0201
-    3eb8:	83 e0       	ldi	r24, 0x03	; 3
-    3eba:	87 bf       	out	0x37, r24	; 55
-    3ebc:	e8 95       	spm
-    3ebe:	c0 e0       	ldi	r28, 0x00	; 0
-    3ec0:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	88 e3       	ldi	r24, 0x38	; 56
+    3eba:	e0 30       	cpi	r30, 0x00	; 0
+    3ebc:	f8 07       	cpc	r31, r24
+    3ebe:	18 f4       	brcc	.+6      	; 0x3ec6 <main+0xc6>
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	87 bf       	out	0x37, r24	; 55
+    3ec4:	e8 95       	spm
+    3ec6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ec8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ec2:	66 d0       	rcall	.+204    	; 0x3f90 <getch>
-    3ec4:	89 93       	st	Y+, r24
+    3eca:	71 d0       	rcall	.+226    	; 0x3fae <getch>
+    3ecc:	89 93       	st	Y+, r24
       while (--length);
-    3ec6:	80 91 02 02 	lds	r24, 0x0202
-    3eca:	81 50       	subi	r24, 0x01	; 1
-    3ecc:	80 93 02 02 	sts	0x0202, r24
-    3ed0:	88 23       	and	r24, r24
-    3ed2:	b9 f7       	brne	.-18     	; 0x3ec2 <main+0xc2>
+    3ece:	80 91 02 02 	lds	r24, 0x0202
+    3ed2:	81 50       	subi	r24, 0x01	; 1
+    3ed4:	80 93 02 02 	sts	0x0202, r24
+    3ed8:	88 23       	and	r24, r24
+    3eda:	b9 f7       	brne	.-18     	; 0x3eca <main+0xca>
+
+      // 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);
+    3edc:	e0 91 00 02 	lds	r30, 0x0200
+    3ee0:	f0 91 01 02 	lds	r31, 0x0201
+    3ee4:	88 e3       	ldi	r24, 0x38	; 56
+    3ee6:	e0 30       	cpi	r30, 0x00	; 0
+    3ee8:	f8 07       	cpc	r31, r24
+    3eea:	18 f0       	brcs	.+6      	; 0x3ef2 <main+0xf2>
+    3eec:	83 e0       	ldi	r24, 0x03	; 3
+    3eee:	87 bf       	out	0x37, r24	; 55
+    3ef0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ed4:	75 d0       	rcall	.+234    	; 0x3fc0 <verifySpace>
+    3ef2:	75 d0       	rcall	.+234    	; 0x3fde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3ed6:	07 b6       	in	r0, 0x37	; 55
-    3ed8:	00 fc       	sbrc	r0, 0
-    3eda:	fd cf       	rjmp	.-6      	; 0x3ed6 <main+0xd6>
+    3ef4:	07 b6       	in	r0, 0x37	; 55
+    3ef6:	00 fc       	sbrc	r0, 0
+    3ef8:	fd cf       	rjmp	.-6      	; 0x3ef4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    3edc:	40 91 00 02 	lds	r20, 0x0200
-    3ee0:	50 91 01 02 	lds	r21, 0x0201
-    3ee4:	a0 e0       	ldi	r26, 0x00	; 0
-    3ee6:	b1 e0       	ldi	r27, 0x01	; 1
+    3efa:	40 91 00 02 	lds	r20, 0x0200
+    3efe:	50 91 01 02 	lds	r21, 0x0201
+    3f02:	a0 e0       	ldi	r26, 0x00	; 0
+    3f04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3ee8:	2c 91       	ld	r18, X
-    3eea:	30 e0       	ldi	r19, 0x00	; 0
+    3f06:	2c 91       	ld	r18, X
+    3f08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3eec:	11 96       	adiw	r26, 0x01	; 1
-    3eee:	8c 91       	ld	r24, X
-    3ef0:	11 97       	sbiw	r26, 0x01	; 1
-    3ef2:	90 e0       	ldi	r25, 0x00	; 0
-    3ef4:	98 2f       	mov	r25, r24
-    3ef6:	88 27       	eor	r24, r24
-    3ef8:	82 2b       	or	r24, r18
-    3efa:	93 2b       	or	r25, r19
+    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))
 #endif
 
 /* main program starts here */
 int main(void) {
-    3efc:	12 96       	adiw	r26, 0x02	; 2
+    3f1a:	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);
-    3efe:	fa 01       	movw	r30, r20
-    3f00:	0c 01       	movw	r0, r24
-    3f02:	d7 be       	out	0x37, r13	; 55
-    3f04:	e8 95       	spm
-    3f06:	11 24       	eor	r1, r1
+    3f1c:	fa 01       	movw	r30, r20
+    3f1e:	0c 01       	movw	r0, r24
+    3f20:	d7 be       	out	0x37, r13	; 55
+    3f22:	e8 95       	spm
+    3f24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f08:	4e 5f       	subi	r20, 0xFE	; 254
-    3f0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f26:	4e 5f       	subi	r20, 0xFE	; 254
+    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f0c:	f1 e0       	ldi	r31, 0x01	; 1
-    3f0e:	a0 38       	cpi	r26, 0x80	; 128
-    3f10:	bf 07       	cpc	r27, r31
-    3f12:	51 f7       	brne	.-44     	; 0x3ee8 <main+0xe8>
+    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>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f14:	e0 91 00 02 	lds	r30, 0x0200
-    3f18:	f0 91 01 02 	lds	r31, 0x0201
-    3f1c:	f7 be       	out	0x37, r15	; 55
-    3f1e:	e8 95       	spm
+    3f32:	e0 91 00 02 	lds	r30, 0x0200
+    3f36:	f0 91 01 02 	lds	r31, 0x0201
+    3f3a:	e7 be       	out	0x37, r14	; 55
+    3f3c:	e8 95       	spm
       boot_spm_busy_wait();
-    3f20:	07 b6       	in	r0, 0x37	; 55
-    3f22:	00 fc       	sbrc	r0, 0
-    3f24:	fd cf       	rjmp	.-6      	; 0x3f20 <main+0x120>
+    3f3e:	07 b6       	in	r0, 0x37	; 55
+    3f40:	00 fc       	sbrc	r0, 0
+    3f42:	fd cf       	rjmp	.-6      	; 0x3f3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f26:	e7 be       	out	0x37, r14	; 55
-    3f28:	e8 95       	spm
-    3f2a:	27 c0       	rjmp	.+78     	; 0x3f7a <main+0x17a>
+    3f44:	f7 be       	out	0x37, r15	; 55
+    3f46:	e8 95       	spm
+    3f48:	27 c0       	rjmp	.+78     	; 0x3f98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f2c:	84 37       	cpi	r24, 0x74	; 116
-    3f2e:	b9 f4       	brne	.+46     	; 0x3f5e <main+0x15e>
+    3f4a:	84 37       	cpi	r24, 0x74	; 116
+    3f4c:	b9 f4       	brne	.+46     	; 0x3f7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    3f30:	37 d0       	rcall	.+110    	; 0x3fa0 <getLen>
+    3f4e:	37 d0       	rcall	.+110    	; 0x3fbe <getLen>
       verifySpace();
-    3f32:	46 d0       	rcall	.+140    	; 0x3fc0 <verifySpace>
+    3f50:	46 d0       	rcall	.+140    	; 0x3fde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    3f34:	e0 91 00 02 	lds	r30, 0x0200
-    3f38:	f0 91 01 02 	lds	r31, 0x0201
-    3f3c:	31 96       	adiw	r30, 0x01	; 1
-    3f3e:	f0 93 01 02 	sts	0x0201, r31
-    3f42:	e0 93 00 02 	sts	0x0200, r30
-    3f46:	31 97       	sbiw	r30, 0x01	; 1
-    3f48:	e4 91       	lpm	r30, Z+
-    3f4a:	8e 2f       	mov	r24, r30
-    3f4c:	19 d0       	rcall	.+50     	; 0x3f80 <putch>
+    3f52:	e0 91 00 02 	lds	r30, 0x0200
+    3f56:	f0 91 01 02 	lds	r31, 0x0201
+    3f5a:	31 96       	adiw	r30, 0x01	; 1
+    3f5c:	f0 93 01 02 	sts	0x0201, r31
+    3f60:	e0 93 00 02 	sts	0x0200, r30
+    3f64:	31 97       	sbiw	r30, 0x01	; 1
+    3f66:	e4 91       	lpm	r30, Z+
+    3f68:	8e 2f       	mov	r24, r30
+    3f6a:	19 d0       	rcall	.+50     	; 0x3f9e <putch>
       while (--length);
-    3f4e:	80 91 02 02 	lds	r24, 0x0202
-    3f52:	81 50       	subi	r24, 0x01	; 1
-    3f54:	80 93 02 02 	sts	0x0202, r24
-    3f58:	88 23       	and	r24, r24
-    3f5a:	61 f7       	brne	.-40     	; 0x3f34 <main+0x134>
-    3f5c:	0e c0       	rjmp	.+28     	; 0x3f7a <main+0x17a>
+    3f6c:	80 91 02 02 	lds	r24, 0x0202
+    3f70:	81 50       	subi	r24, 0x01	; 1
+    3f72:	80 93 02 02 	sts	0x0202, r24
+    3f76:	88 23       	and	r24, r24
+    3f78:	61 f7       	brne	.-40     	; 0x3f52 <main+0x152>
+    3f7a:	0e c0       	rjmp	.+28     	; 0x3f98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f5e:	85 37       	cpi	r24, 0x75	; 117
-    3f60:	39 f4       	brne	.+14     	; 0x3f70 <main+0x170>
+    3f7c:	85 37       	cpi	r24, 0x75	; 117
+    3f7e:	39 f4       	brne	.+14     	; 0x3f8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f62:	2e d0       	rcall	.+92     	; 0x3fc0 <verifySpace>
+    3f80:	2e d0       	rcall	.+92     	; 0x3fde <verifySpace>
       putch(SIGNATURE_0);
-    3f64:	8e e1       	ldi	r24, 0x1E	; 30
-    3f66:	0c d0       	rcall	.+24     	; 0x3f80 <putch>
+    3f82:	8e e1       	ldi	r24, 0x1E	; 30
+    3f84:	0c d0       	rcall	.+24     	; 0x3f9e <putch>
       putch(SIGNATURE_1);
-    3f68:	84 e9       	ldi	r24, 0x94	; 148
-    3f6a:	0a d0       	rcall	.+20     	; 0x3f80 <putch>
+    3f86:	84 e9       	ldi	r24, 0x94	; 148
+    3f88:	0a d0       	rcall	.+20     	; 0x3f9e <putch>
       putch(SIGNATURE_2);
-    3f6c:	86 e0       	ldi	r24, 0x06	; 6
-    3f6e:	9a cf       	rjmp	.-204    	; 0x3ea4 <main+0xa4>
+    3f8a:	86 e0       	ldi	r24, 0x06	; 6
+    3f8c:	8b cf       	rjmp	.-234    	; 0x3ea4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    3f70:	81 35       	cpi	r24, 0x51	; 81
-    3f72:	11 f4       	brne	.+4      	; 0x3f78 <main+0x178>
+    3f8e:	81 35       	cpi	r24, 0x51	; 81
+    3f90:	11 f4       	brne	.+4      	; 0x3f96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f74:	88 e0       	ldi	r24, 0x08	; 8
-    3f76:	19 d0       	rcall	.+50     	; 0x3faa <watchdogConfig>
+    3f92:	88 e0       	ldi	r24, 0x08	; 8
+    3f94:	19 d0       	rcall	.+50     	; 0x3fc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f78:	23 d0       	rcall	.+70     	; 0x3fc0 <verifySpace>
+    3f96:	23 d0       	rcall	.+70     	; 0x3fde <verifySpace>
     }
     putch(STK_OK);
-    3f7a:	80 e1       	ldi	r24, 0x10	; 16
-    3f7c:	01 d0       	rcall	.+2      	; 0x3f80 <putch>
-    3f7e:	6b cf       	rjmp	.-298    	; 0x3e56 <main+0x56>
+    3f98:	80 e1       	ldi	r24, 0x10	; 16
+    3f9a:	01 d0       	rcall	.+2      	; 0x3f9e <putch>
+    3f9c:	5c cf       	rjmp	.-328    	; 0x3e56 <main+0x56>
 
-00003f80 <putch>:
+00003f9e <putch>:
   }
 }
 
 void putch(char ch) {
-    3f80:	98 2f       	mov	r25, r24
+    3f9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    3f82:	80 91 c0 00 	lds	r24, 0x00C0
-    3f86:	85 ff       	sbrs	r24, 5
-    3f88:	fc cf       	rjmp	.-8      	; 0x3f82 <putch+0x2>
+    3fa0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa4:	85 ff       	sbrs	r24, 5
+    3fa6:	fc cf       	rjmp	.-8      	; 0x3fa0 <putch+0x2>
   UDR0 = ch;
-    3f8a:	90 93 c6 00 	sts	0x00C6, r25
+    3fa8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3f8e:	08 95       	ret
+    3fac:	08 95       	ret
 
-00003f90 <getch>:
+00003fae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3f90:	a8 95       	wdr
+    3fae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    3f92:	80 91 c0 00 	lds	r24, 0x00C0
-    3f96:	87 ff       	sbrs	r24, 7
-    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <getch+0x2>
+    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fb4:	87 ff       	sbrs	r24, 7
+    3fb6:	fc cf       	rjmp	.-8      	; 0x3fb0 <getch+0x2>
   ch = UDR0;
-    3f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    3f9e:	08 95       	ret
+    3fbc:	08 95       	ret
 
-00003fa0 <getLen>:
+00003fbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    3fa0:	f7 df       	rcall	.-18     	; 0x3f90 <getch>
+    3fbe:	f7 df       	rcall	.-18     	; 0x3fae <getch>
   length = getch();
-    3fa2:	f6 df       	rcall	.-20     	; 0x3f90 <getch>
-    3fa4:	80 93 02 02 	sts	0x0202, r24
+    3fc0:	f6 df       	rcall	.-20     	; 0x3fae <getch>
+    3fc2:	80 93 02 02 	sts	0x0202, r24
   return getch();
 }
-    3fa8:	f3 cf       	rjmp	.-26     	; 0x3f90 <getch>
+    3fc6:	f3 cf       	rjmp	.-26     	; 0x3fae <getch>
 
-00003faa <watchdogConfig>:
+00003fc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3faa:	e0 e6       	ldi	r30, 0x60	; 96
-    3fac:	f0 e0       	ldi	r31, 0x00	; 0
-    3fae:	98 e1       	ldi	r25, 0x18	; 24
-    3fb0:	90 83       	st	Z, r25
+    3fc8:	e0 e6       	ldi	r30, 0x60	; 96
+    3fca:	f0 e0       	ldi	r31, 0x00	; 0
+    3fcc:	98 e1       	ldi	r25, 0x18	; 24
+    3fce:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fb2:	80 83       	st	Z, r24
+    3fd0:	80 83       	st	Z, r24
 }
-    3fb4:	08 95       	ret
+    3fd2:	08 95       	ret
 
-00003fb6 <appStart>:
+00003fd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fb6:	80 e0       	ldi	r24, 0x00	; 0
-    3fb8:	f8 df       	rcall	.-16     	; 0x3faa <watchdogConfig>
+    3fd4:	80 e0       	ldi	r24, 0x00	; 0
+    3fd6:	f8 df       	rcall	.-16     	; 0x3fc8 <watchdogConfig>
   __asm__ __volatile__ (
-    3fba:	ee 27       	eor	r30, r30
-    3fbc:	ff 27       	eor	r31, r31
-    3fbe:	09 94       	ijmp
+    3fd8:	ee 27       	eor	r30, r30
+    3fda:	ff 27       	eor	r31, r31
+    3fdc:	09 94       	ijmp
 
-00003fc0 <verifySpace>:
+00003fde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    3fc0:	e7 df       	rcall	.-50     	; 0x3f90 <getch>
-    3fc2:	80 32       	cpi	r24, 0x20	; 32
-    3fc4:	09 f0       	breq	.+2      	; 0x3fc8 <verifySpace+0x8>
-    3fc6:	f7 df       	rcall	.-18     	; 0x3fb6 <appStart>
+    3fde:	e7 df       	rcall	.-50     	; 0x3fae <getch>
+    3fe0:	80 32       	cpi	r24, 0x20	; 32
+    3fe2:	09 f0       	breq	.+2      	; 0x3fe6 <verifySpace+0x8>
+    3fe4:	f7 df       	rcall	.-18     	; 0x3fd4 <appStart>
   putch(STK_INSYNC);
-    3fc8:	84 e1       	ldi	r24, 0x14	; 20
+    3fe6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fca:	da cf       	rjmp	.-76     	; 0x3f80 <putch>
+    3fe8:	da cf       	rjmp	.-76     	; 0x3f9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fcc:	1f 93       	push	r17
-    3fce:	18 2f       	mov	r17, r24
+    3fea:	1f 93       	push	r17
+    3fec:	18 2f       	mov	r17, r24
 
-00003fd0 <getNch>:
+00003fee <getNch>:
   do getch(); while (--count);
-    3fd0:	df df       	rcall	.-66     	; 0x3f90 <getch>
-    3fd2:	11 50       	subi	r17, 0x01	; 1
-    3fd4:	e9 f7       	brne	.-6      	; 0x3fd0 <getNch>
+    3fee:	df df       	rcall	.-66     	; 0x3fae <getch>
+    3ff0:	11 50       	subi	r17, 0x01	; 1
+    3ff2:	e9 f7       	brne	.-6      	; 0x3fee <getNch>
   verifySpace();
-    3fd6:	f4 df       	rcall	.-24     	; 0x3fc0 <verifySpace>
+    3ff4:	f4 df       	rcall	.-24     	; 0x3fde <verifySpace>
 }
-    3fd8:	1f 91       	pop	r17
-    3fda:	08 95       	ret
+    3ff6:	1f 91       	pop	r17
+    3ff8:	08 95       	ret

+ 27 - 25
optiboot/bootloaders/optiboot/optiboot_pro_8MHz.hex

@@ -1,32 +1,34 @@
 :103E000085E08093810082E08093C00088E1809308
 :103E1000C10086E08093C20088E08093C40084B72C
-:103E200014BE81FFC8D08DE0C0D0259A86E028E17D
+:103E200014BE81FFD7D08DE0CFD0259A86E028E15F
 :103E30003EEF91E0309385002093840096BBB09BC9
 :103E4000FECF1D9AA8958150A9F7DD24D394A5E053
-:103E5000FA2EF1E1EF2E9CD0813421F481E0B6D02E
+:103E5000EA2EF1E1FF2EABD0813421F481E0C5D010
 :103E600083E020C0823411F484E103C0853419F466
-:103E700085E0ACD082C0853581F48AD0082F10E06F
-:103E800087D090E0982F8827802B912B880F991F3F
-:103E900090930102809300026FC0863529F484E07C
-:103EA00095D080E06DD069C0843609F03FC078D0ED
-:103EB000E0910002F091010283E087BFE895C0E045
-:103EC000D1E066D0899380910202815080930202F2
-:103ED0008823B9F775D007B600FCFDCF40910002EA
-:103EE00050910102A0E0B1E02C9130E011968C914C
-:103EF000119790E0982F8827822B932B1296FA0126
-:103F00000C01D7BEE89511244E5F5F4FF1E0A03859
-:103F1000BF0751F7E0910002F0910102F7BEE8956A
-:103F200007B600FCFDCFE7BEE89527C08437B9F49B
-:103F300037D046D0E0910002F09101023196F09323
-:103F40000102E09300023197E4918E2F19D0809105
-:103F50000202815080930202882361F70EC08537E8
-:103F600039F42ED08EE10CD084E90AD086E09ACFC5
-:103F7000813511F488E019D023D080E101D06BCFD6
-:103F8000982F8091C00085FFFCCF9093C6000895C4
-:103F9000A8958091C00087FFFCCF8091C60008954E
-:103FA000F7DFF6DF80930202F3CFE0E6F0E098E17E
-:103FB00090838083089580E0F8DFEE27FF2709943F
-:103FC000E7DF803209F0F7DF84E1DACF1F93182FA3
-:0C3FD000DFDF1150E9F7F4DF1F910895C6
+:103E700085E0BBD091C0853581F499D0082F10E042
+:103E800096D090E0982F8827802B912B880F991F30
+:103E900090930102809300027EC0863529F484E06D
+:103EA000A4D080E07CD078C0843609F04EC087D0A2
+:103EB000E0910002F091010288E3E030F80718F485
+:103EC00083E087BFE895C0E0D1E071D0899380910D
+:103ED00002028150809302028823B9F7E091000228
+:103EE000F091010288E3E030F80718F083E087BF23
+:103EF000E89575D007B600FCFDCF409100025091C7
+:103F00000102A0E0B1E02C9130E011968C91119764
+:103F100090E0982F8827822B932B1296FA010C01A0
+:103F2000D7BEE89511244E5F5F4FF1E0A038BF0780
+:103F300051F7E0910002F0910102E7BEE89507B663
+:103F400000FCFDCFF7BEE89527C08437B9F437D021
+:103F500046D0E0910002F09101023196F093010207
+:103F6000E09300023197E4918E2F19D080910202E4
+:103F7000815080930202882361F70EC0853739F49F
+:103F80002ED08EE10CD084E90AD086E08BCF81352B
+:103F900011F488E019D023D080E101D05CCF982FB4
+:103FA0008091C00085FFFCCF9093C6000895A8952E
+:103FB0008091C00087FFFCCF8091C6000895F7DF95
+:103FC000F6DF80930202F3CFE0E6F0E098E1908321
+:103FD0008083089580E0F8DFEE27FF270994E7DF6C
+:103FE000803209F0F7DF84E1DACF1F93182FDFDF8B
+:0A3FF0001150E9F7F4DF1F91089566
 :0400000300003E00BB
 :00000001FF

+ 181 - 164
optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst

@@ -3,25 +3,25 @@ optiboot_pro_8MHz.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001dc  00003e00  00003e00  00000054  2**1
+  0 .text         000001fa  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000230  2**0
+  1 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 0000006a  00000000  00000000  00000258  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000276  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000283  00000000  00000000  000002c2  2**0
+  3 .debug_info   00000284  00000000  00000000  000002e0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001ae  00000000  00000000  00000545  2**0
+  4 .debug_abbrev 000001ae  00000000  00000000  00000564  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003db  00000000  00000000  000006f3  2**0
+  5 .debug_line   000003e3  00000000  00000000  00000712  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  00000090  00000000  00000000  00000ad0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000af8  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000140  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000140  00000000  00000000  00000b88  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001d1  00000000  00000000  00000ca0  2**0
+  8 .debug_loc    000001e1  00000000  00000000  00000cc8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000068  00000000  00000000  00000e71  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000ea9  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
@@ -61,12 +61,12 @@ int main(void) {
     3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
     3e22:	81 ff       	sbrs	r24, 1
-    3e24:	c8 d0       	rcall	.+400    	; 0x3fb6 <appStart>
+    3e24:	d7 d0       	rcall	.+430    	; 0x3fd4 <appStart>
 
   // Set up watchdog to trigger after 500ms
   watchdogConfig(WATCHDOG_500MS);
     3e26:	8d e0       	ldi	r24, 0x0D	; 13
-    3e28:	c0 d0       	rcall	.+384    	; 0x3faa <watchdogConfig>
+    3e28:	cf d0       	rcall	.+414    	; 0x3fc8 <watchdogConfig>
 
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
@@ -127,21 +127,21 @@ void watchdogReset() {
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
     3e4e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e50:	fa 2e       	mov	r15, r26
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
     3e52:	f1 e1       	ldi	r31, 0x11	; 17
-    3e54:	ef 2e       	mov	r14, r31
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 
   /* Forever loop */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e56:	9c d0       	rcall	.+312    	; 0x3f90 <getch>
+    3e56:	ab d0       	rcall	.+342    	; 0x3fae <getch>
 
     if(ch == STK_GET_PARAMETER) {
     3e58:	81 34       	cpi	r24, 0x41	; 65
@@ -149,7 +149,7 @@ void watchdogReset() {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
     3e5c:	81 e0       	ldi	r24, 0x01	; 1
-    3e5e:	b6 d0       	rcall	.+364    	; 0x3fcc <verifySpace+0xc>
+    3e5e:	c5 d0       	rcall	.+394    	; 0x3fea <verifySpace+0xc>
       putch(0x03);
     3e60:	83 e0       	ldi	r24, 0x03	; 3
     3e62:	20 c0       	rjmp	.+64     	; 0x3ea4 <main+0xa4>
@@ -168,8 +168,8 @@ void watchdogReset() {
       // SET DEVICE EXT is ignored
       getNch(5);
     3e70:	85 e0       	ldi	r24, 0x05	; 5
-    3e72:	ac d0       	rcall	.+344    	; 0x3fcc <verifySpace+0xc>
-    3e74:	82 c0       	rjmp	.+260    	; 0x3f7a <main+0x17a>
+    3e72:	bb d0       	rcall	.+374    	; 0x3fea <verifySpace+0xc>
+    3e74:	91 c0       	rjmp	.+290    	; 0x3f98 <main+0x198>
     }
     else if(ch == STK_LOAD_ADDRESS) {
     3e76:	85 35       	cpi	r24, 0x55	; 85
@@ -177,11 +177,11 @@ void watchdogReset() {
       // LOAD ADDRESS
       uint16_t newAddress;
       newAddress = getch();
-    3e7a:	8a d0       	rcall	.+276    	; 0x3f90 <getch>
+    3e7a:	99 d0       	rcall	.+306    	; 0x3fae <getch>
       newAddress = (newAddress & 0xff) | (getch() << 8);
     3e7c:	08 2f       	mov	r16, r24
     3e7e:	10 e0       	ldi	r17, 0x00	; 0
-    3e80:	87 d0       	rcall	.+270    	; 0x3f90 <getch>
+    3e80:	96 d0       	rcall	.+300    	; 0x3fae <getch>
     3e82:	90 e0       	ldi	r25, 0x00	; 0
     3e84:	98 2f       	mov	r25, r24
     3e86:	88 27       	eor	r24, r24
@@ -197,7 +197,7 @@ void watchdogReset() {
       address = newAddress;
     3e90:	90 93 01 02 	sts	0x0201, r25
     3e94:	80 93 00 02 	sts	0x0200, r24
-    3e98:	6f c0       	rjmp	.+222    	; 0x3f78 <main+0x178>
+    3e98:	7e c0       	rjmp	.+252    	; 0x3f96 <main+0x196>
       verifySpace();
     }
     else if(ch == STK_UNIVERSAL) {
@@ -206,320 +206,337 @@ void watchdogReset() {
       // UNIVERSAL command is ignored
       getNch(4);
     3e9e:	84 e0       	ldi	r24, 0x04	; 4
-    3ea0:	95 d0       	rcall	.+298    	; 0x3fcc <verifySpace+0xc>
+    3ea0:	a4 d0       	rcall	.+328    	; 0x3fea <verifySpace+0xc>
       putch(0x00);
     3ea2:	80 e0       	ldi	r24, 0x00	; 0
-    3ea4:	6d d0       	rcall	.+218    	; 0x3f80 <putch>
-    3ea6:	69 c0       	rjmp	.+210    	; 0x3f7a <main+0x17a>
+    3ea4:	7c d0       	rcall	.+248    	; 0x3f9e <putch>
+    3ea6:	78 c0       	rjmp	.+240    	; 0x3f98 <main+0x198>
     }
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     3ea8:	84 36       	cpi	r24, 0x64	; 100
     3eaa:	09 f0       	breq	.+2      	; 0x3eae <main+0xae>
-    3eac:	3f c0       	rjmp	.+126    	; 0x3f2c <main+0x12c>
+    3eac:	4e c0       	rjmp	.+156    	; 0x3f4a <main+0x14a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint16_t addrPtr;
 
       getLen();
-    3eae:	78 d0       	rcall	.+240    	; 0x3fa0 <getLen>
+    3eae:	87 d0       	rcall	.+270    	; 0x3fbe <getLen>
 
-      // Immediately start page erase - this will 4.5ms
-      __boot_page_erase_short((uint16_t)(void*)address);
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
     3eb0:	e0 91 00 02 	lds	r30, 0x0200
     3eb4:	f0 91 01 02 	lds	r31, 0x0201
-    3eb8:	83 e0       	ldi	r24, 0x03	; 3
-    3eba:	87 bf       	out	0x37, r24	; 55
-    3ebc:	e8 95       	spm
-    3ebe:	c0 e0       	ldi	r28, 0x00	; 0
-    3ec0:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	88 e3       	ldi	r24, 0x38	; 56
+    3eba:	e0 30       	cpi	r30, 0x00	; 0
+    3ebc:	f8 07       	cpc	r31, r24
+    3ebe:	18 f4       	brcc	.+6      	; 0x3ec6 <main+0xc6>
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	87 bf       	out	0x37, r24	; 55
+    3ec4:	e8 95       	spm
+    3ec6:	c0 e0       	ldi	r28, 0x00	; 0
+    3ec8:	d1 e0       	ldi	r29, 0x01	; 1
       
       // While that is going on, read in page contents
       bufPtr = buff;
       do *bufPtr++ = getch();
-    3ec2:	66 d0       	rcall	.+204    	; 0x3f90 <getch>
-    3ec4:	89 93       	st	Y+, r24
+    3eca:	71 d0       	rcall	.+226    	; 0x3fae <getch>
+    3ecc:	89 93       	st	Y+, r24
       while (--length);
-    3ec6:	80 91 02 02 	lds	r24, 0x0202
-    3eca:	81 50       	subi	r24, 0x01	; 1
-    3ecc:	80 93 02 02 	sts	0x0202, r24
-    3ed0:	88 23       	and	r24, r24
-    3ed2:	b9 f7       	brne	.-18     	; 0x3ec2 <main+0xc2>
+    3ece:	80 91 02 02 	lds	r24, 0x0202
+    3ed2:	81 50       	subi	r24, 0x01	; 1
+    3ed4:	80 93 02 02 	sts	0x0202, r24
+    3ed8:	88 23       	and	r24, r24
+    3eda:	b9 f7       	brne	.-18     	; 0x3eca <main+0xca>
+
+      // 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);
+    3edc:	e0 91 00 02 	lds	r30, 0x0200
+    3ee0:	f0 91 01 02 	lds	r31, 0x0201
+    3ee4:	88 e3       	ldi	r24, 0x38	; 56
+    3ee6:	e0 30       	cpi	r30, 0x00	; 0
+    3ee8:	f8 07       	cpc	r31, r24
+    3eea:	18 f0       	brcs	.+6      	; 0x3ef2 <main+0xf2>
+    3eec:	83 e0       	ldi	r24, 0x03	; 3
+    3eee:	87 bf       	out	0x37, r24	; 55
+    3ef0:	e8 95       	spm
 
       // Read command terminator, start reply
       verifySpace();
-    3ed4:	75 d0       	rcall	.+234    	; 0x3fc0 <verifySpace>
+    3ef2:	75 d0       	rcall	.+234    	; 0x3fde <verifySpace>
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       boot_spm_busy_wait();
-    3ed6:	07 b6       	in	r0, 0x37	; 55
-    3ed8:	00 fc       	sbrc	r0, 0
-    3eda:	fd cf       	rjmp	.-6      	; 0x3ed6 <main+0xd6>
+    3ef4:	07 b6       	in	r0, 0x37	; 55
+    3ef6:	00 fc       	sbrc	r0, 0
+    3ef8:	fd cf       	rjmp	.-6      	; 0x3ef4 <main+0xf4>
       }
 #endif
 
       // Copy buffer into programming buffer
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
-    3edc:	40 91 00 02 	lds	r20, 0x0200
-    3ee0:	50 91 01 02 	lds	r21, 0x0201
-    3ee4:	a0 e0       	ldi	r26, 0x00	; 0
-    3ee6:	b1 e0       	ldi	r27, 0x01	; 1
+    3efa:	40 91 00 02 	lds	r20, 0x0200
+    3efe:	50 91 01 02 	lds	r21, 0x0201
+    3f02:	a0 e0       	ldi	r26, 0x00	; 0
+    3f04:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       do {
         uint16_t a;
         a = *bufPtr++;
-    3ee8:	2c 91       	ld	r18, X
-    3eea:	30 e0       	ldi	r19, 0x00	; 0
+    3f06:	2c 91       	ld	r18, X
+    3f08:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
-    3eec:	11 96       	adiw	r26, 0x01	; 1
-    3eee:	8c 91       	ld	r24, X
-    3ef0:	11 97       	sbiw	r26, 0x01	; 1
-    3ef2:	90 e0       	ldi	r25, 0x00	; 0
-    3ef4:	98 2f       	mov	r25, r24
-    3ef6:	88 27       	eor	r24, r24
-    3ef8:	82 2b       	or	r24, r18
-    3efa:	93 2b       	or	r25, r19
+    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))
 #endif
 
 /* main program starts here */
 int main(void) {
-    3efc:	12 96       	adiw	r26, 0x02	; 2
+    3f1a:	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);
-    3efe:	fa 01       	movw	r30, r20
-    3f00:	0c 01       	movw	r0, r24
-    3f02:	d7 be       	out	0x37, r13	; 55
-    3f04:	e8 95       	spm
-    3f06:	11 24       	eor	r1, r1
+    3f1c:	fa 01       	movw	r30, r20
+    3f1e:	0c 01       	movw	r0, r24
+    3f20:	d7 be       	out	0x37, r13	; 55
+    3f22:	e8 95       	spm
+    3f24:	11 24       	eor	r1, r1
         addrPtr += 2;
-    3f08:	4e 5f       	subi	r20, 0xFE	; 254
-    3f0a:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f26:	4e 5f       	subi	r20, 0xFE	; 254
+    3f28:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
-    3f0c:	f1 e0       	ldi	r31, 0x01	; 1
-    3f0e:	a0 38       	cpi	r26, 0x80	; 128
-    3f10:	bf 07       	cpc	r27, r31
-    3f12:	51 f7       	brne	.-44     	; 0x3ee8 <main+0xe8>
+    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>
       
       // Write from programming buffer
       __boot_page_write_short((uint16_t)(void*)address);
-    3f14:	e0 91 00 02 	lds	r30, 0x0200
-    3f18:	f0 91 01 02 	lds	r31, 0x0201
-    3f1c:	f7 be       	out	0x37, r15	; 55
-    3f1e:	e8 95       	spm
+    3f32:	e0 91 00 02 	lds	r30, 0x0200
+    3f36:	f0 91 01 02 	lds	r31, 0x0201
+    3f3a:	e7 be       	out	0x37, r14	; 55
+    3f3c:	e8 95       	spm
       boot_spm_busy_wait();
-    3f20:	07 b6       	in	r0, 0x37	; 55
-    3f22:	00 fc       	sbrc	r0, 0
-    3f24:	fd cf       	rjmp	.-6      	; 0x3f20 <main+0x120>
+    3f3e:	07 b6       	in	r0, 0x37	; 55
+    3f40:	00 fc       	sbrc	r0, 0
+    3f42:	fd cf       	rjmp	.-6      	; 0x3f3e <main+0x13e>
 
 #if defined(RWWSRE)
       // Reenable read access to flash
       boot_rww_enable();
-    3f26:	e7 be       	out	0x37, r14	; 55
-    3f28:	e8 95       	spm
-    3f2a:	27 c0       	rjmp	.+78     	; 0x3f7a <main+0x17a>
+    3f44:	f7 be       	out	0x37, r15	; 55
+    3f46:	e8 95       	spm
+    3f48:	27 c0       	rjmp	.+78     	; 0x3f98 <main+0x198>
 #endif
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f2c:	84 37       	cpi	r24, 0x74	; 116
-    3f2e:	b9 f4       	brne	.+46     	; 0x3f5e <main+0x15e>
+    3f4a:	84 37       	cpi	r24, 0x74	; 116
+    3f4c:	b9 f4       	brne	.+46     	; 0x3f7c <main+0x17c>
       // READ PAGE - we only read flash
       getLen();
-    3f30:	37 d0       	rcall	.+110    	; 0x3fa0 <getLen>
+    3f4e:	37 d0       	rcall	.+110    	; 0x3fbe <getLen>
       verifySpace();
-    3f32:	46 d0       	rcall	.+140    	; 0x3fc0 <verifySpace>
+    3f50:	46 d0       	rcall	.+140    	; 0x3fde <verifySpace>
         putch(result);
         address++;
       }
       while (--length);
 #else
       do putch(pgm_read_byte_near(address++));
-    3f34:	e0 91 00 02 	lds	r30, 0x0200
-    3f38:	f0 91 01 02 	lds	r31, 0x0201
-    3f3c:	31 96       	adiw	r30, 0x01	; 1
-    3f3e:	f0 93 01 02 	sts	0x0201, r31
-    3f42:	e0 93 00 02 	sts	0x0200, r30
-    3f46:	31 97       	sbiw	r30, 0x01	; 1
-    3f48:	e4 91       	lpm	r30, Z+
-    3f4a:	8e 2f       	mov	r24, r30
-    3f4c:	19 d0       	rcall	.+50     	; 0x3f80 <putch>
+    3f52:	e0 91 00 02 	lds	r30, 0x0200
+    3f56:	f0 91 01 02 	lds	r31, 0x0201
+    3f5a:	31 96       	adiw	r30, 0x01	; 1
+    3f5c:	f0 93 01 02 	sts	0x0201, r31
+    3f60:	e0 93 00 02 	sts	0x0200, r30
+    3f64:	31 97       	sbiw	r30, 0x01	; 1
+    3f66:	e4 91       	lpm	r30, Z+
+    3f68:	8e 2f       	mov	r24, r30
+    3f6a:	19 d0       	rcall	.+50     	; 0x3f9e <putch>
       while (--length);
-    3f4e:	80 91 02 02 	lds	r24, 0x0202
-    3f52:	81 50       	subi	r24, 0x01	; 1
-    3f54:	80 93 02 02 	sts	0x0202, r24
-    3f58:	88 23       	and	r24, r24
-    3f5a:	61 f7       	brne	.-40     	; 0x3f34 <main+0x134>
-    3f5c:	0e c0       	rjmp	.+28     	; 0x3f7a <main+0x17a>
+    3f6c:	80 91 02 02 	lds	r24, 0x0202
+    3f70:	81 50       	subi	r24, 0x01	; 1
+    3f72:	80 93 02 02 	sts	0x0202, r24
+    3f76:	88 23       	and	r24, r24
+    3f78:	61 f7       	brne	.-40     	; 0x3f52 <main+0x152>
+    3f7a:	0e c0       	rjmp	.+28     	; 0x3f98 <main+0x198>
 #endif
 #endif
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f5e:	85 37       	cpi	r24, 0x75	; 117
-    3f60:	39 f4       	brne	.+14     	; 0x3f70 <main+0x170>
+    3f7c:	85 37       	cpi	r24, 0x75	; 117
+    3f7e:	39 f4       	brne	.+14     	; 0x3f8e <main+0x18e>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f62:	2e d0       	rcall	.+92     	; 0x3fc0 <verifySpace>
+    3f80:	2e d0       	rcall	.+92     	; 0x3fde <verifySpace>
       putch(SIGNATURE_0);
-    3f64:	8e e1       	ldi	r24, 0x1E	; 30
-    3f66:	0c d0       	rcall	.+24     	; 0x3f80 <putch>
+    3f82:	8e e1       	ldi	r24, 0x1E	; 30
+    3f84:	0c d0       	rcall	.+24     	; 0x3f9e <putch>
       putch(SIGNATURE_1);
-    3f68:	84 e9       	ldi	r24, 0x94	; 148
-    3f6a:	0a d0       	rcall	.+20     	; 0x3f80 <putch>
+    3f86:	84 e9       	ldi	r24, 0x94	; 148
+    3f88:	0a d0       	rcall	.+20     	; 0x3f9e <putch>
       putch(SIGNATURE_2);
-    3f6c:	86 e0       	ldi	r24, 0x06	; 6
-    3f6e:	9a cf       	rjmp	.-204    	; 0x3ea4 <main+0xa4>
+    3f8a:	86 e0       	ldi	r24, 0x06	; 6
+    3f8c:	8b cf       	rjmp	.-234    	; 0x3ea4 <main+0xa4>
     }
     else if (ch == 'Q') {
-    3f70:	81 35       	cpi	r24, 0x51	; 81
-    3f72:	11 f4       	brne	.+4      	; 0x3f78 <main+0x178>
+    3f8e:	81 35       	cpi	r24, 0x51	; 81
+    3f90:	11 f4       	brne	.+4      	; 0x3f96 <main+0x196>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f74:	88 e0       	ldi	r24, 0x08	; 8
-    3f76:	19 d0       	rcall	.+50     	; 0x3faa <watchdogConfig>
+    3f92:	88 e0       	ldi	r24, 0x08	; 8
+    3f94:	19 d0       	rcall	.+50     	; 0x3fc8 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f78:	23 d0       	rcall	.+70     	; 0x3fc0 <verifySpace>
+    3f96:	23 d0       	rcall	.+70     	; 0x3fde <verifySpace>
     }
     putch(STK_OK);
-    3f7a:	80 e1       	ldi	r24, 0x10	; 16
-    3f7c:	01 d0       	rcall	.+2      	; 0x3f80 <putch>
-    3f7e:	6b cf       	rjmp	.-298    	; 0x3e56 <main+0x56>
+    3f98:	80 e1       	ldi	r24, 0x10	; 16
+    3f9a:	01 d0       	rcall	.+2      	; 0x3f9e <putch>
+    3f9c:	5c cf       	rjmp	.-328    	; 0x3e56 <main+0x56>
 
-00003f80 <putch>:
+00003f9e <putch>:
   }
 }
 
 void putch(char ch) {
-    3f80:	98 2f       	mov	r25, r24
+    3f9e:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
-    3f82:	80 91 c0 00 	lds	r24, 0x00C0
-    3f86:	85 ff       	sbrs	r24, 5
-    3f88:	fc cf       	rjmp	.-8      	; 0x3f82 <putch+0x2>
+    3fa0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa4:	85 ff       	sbrs	r24, 5
+    3fa6:	fc cf       	rjmp	.-8      	; 0x3fa0 <putch+0x2>
   UDR0 = ch;
-    3f8a:	90 93 c6 00 	sts	0x00C6, r25
+    3fa8:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
     :
       "r25"
   );
 #endif
 }
-    3f8e:	08 95       	ret
+    3fac:	08 95       	ret
 
-00003f90 <getch>:
+00003fae <getch>:
   return getch();
 }
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3f90:	a8 95       	wdr
+    3fae:	a8 95       	wdr
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UCSR0A & _BV(RXC0)));
-    3f92:	80 91 c0 00 	lds	r24, 0x00C0
-    3f96:	87 ff       	sbrs	r24, 7
-    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <getch+0x2>
+    3fb0:	80 91 c0 00 	lds	r24, 0x00C0
+    3fb4:	87 ff       	sbrs	r24, 7
+    3fb6:	fc cf       	rjmp	.-8      	; 0x3fb0 <getch+0x2>
   ch = UDR0;
-    3f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    3fb8:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
 #endif
 
   return ch;
 }
-    3f9e:	08 95       	ret
+    3fbc:	08 95       	ret
 
-00003fa0 <getLen>:
+00003fbe <getLen>:
   } while (--count);
 }
 #endif
 
 uint8_t getLen() {
   getch();
-    3fa0:	f7 df       	rcall	.-18     	; 0x3f90 <getch>
+    3fbe:	f7 df       	rcall	.-18     	; 0x3fae <getch>
   length = getch();
-    3fa2:	f6 df       	rcall	.-20     	; 0x3f90 <getch>
-    3fa4:	80 93 02 02 	sts	0x0202, r24
+    3fc0:	f6 df       	rcall	.-20     	; 0x3fae <getch>
+    3fc2:	80 93 02 02 	sts	0x0202, r24
   return getch();
 }
-    3fa8:	f3 cf       	rjmp	.-26     	; 0x3f90 <getch>
+    3fc6:	f3 cf       	rjmp	.-26     	; 0x3fae <getch>
 
-00003faa <watchdogConfig>:
+00003fc8 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3faa:	e0 e6       	ldi	r30, 0x60	; 96
-    3fac:	f0 e0       	ldi	r31, 0x00	; 0
-    3fae:	98 e1       	ldi	r25, 0x18	; 24
-    3fb0:	90 83       	st	Z, r25
+    3fc8:	e0 e6       	ldi	r30, 0x60	; 96
+    3fca:	f0 e0       	ldi	r31, 0x00	; 0
+    3fcc:	98 e1       	ldi	r25, 0x18	; 24
+    3fce:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fb2:	80 83       	st	Z, r24
+    3fd0:	80 83       	st	Z, r24
 }
-    3fb4:	08 95       	ret
+    3fd2:	08 95       	ret
 
-00003fb6 <appStart>:
+00003fd4 <appStart>:
 
 void appStart() {
   watchdogConfig(WATCHDOG_OFF);
-    3fb6:	80 e0       	ldi	r24, 0x00	; 0
-    3fb8:	f8 df       	rcall	.-16     	; 0x3faa <watchdogConfig>
+    3fd4:	80 e0       	ldi	r24, 0x00	; 0
+    3fd6:	f8 df       	rcall	.-16     	; 0x3fc8 <watchdogConfig>
   __asm__ __volatile__ (
-    3fba:	ee 27       	eor	r30, r30
-    3fbc:	ff 27       	eor	r31, r31
-    3fbe:	09 94       	ijmp
+    3fd8:	ee 27       	eor	r30, r30
+    3fda:	ff 27       	eor	r31, r31
+    3fdc:	09 94       	ijmp
 
-00003fc0 <verifySpace>:
+00003fde <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
-    3fc0:	e7 df       	rcall	.-50     	; 0x3f90 <getch>
-    3fc2:	80 32       	cpi	r24, 0x20	; 32
-    3fc4:	09 f0       	breq	.+2      	; 0x3fc8 <verifySpace+0x8>
-    3fc6:	f7 df       	rcall	.-18     	; 0x3fb6 <appStart>
+    3fde:	e7 df       	rcall	.-50     	; 0x3fae <getch>
+    3fe0:	80 32       	cpi	r24, 0x20	; 32
+    3fe2:	09 f0       	breq	.+2      	; 0x3fe6 <verifySpace+0x8>
+    3fe4:	f7 df       	rcall	.-18     	; 0x3fd4 <appStart>
   putch(STK_INSYNC);
-    3fc8:	84 e1       	ldi	r24, 0x14	; 20
+    3fe6:	84 e1       	ldi	r24, 0x14	; 20
 }
-    3fca:	da cf       	rjmp	.-76     	; 0x3f80 <putch>
+    3fe8:	da cf       	rjmp	.-76     	; 0x3f9e <putch>
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fcc:	1f 93       	push	r17
-    3fce:	18 2f       	mov	r17, r24
+    3fea:	1f 93       	push	r17
+    3fec:	18 2f       	mov	r17, r24
 
-00003fd0 <getNch>:
+00003fee <getNch>:
   do getch(); while (--count);
-    3fd0:	df df       	rcall	.-66     	; 0x3f90 <getch>
-    3fd2:	11 50       	subi	r17, 0x01	; 1
-    3fd4:	e9 f7       	brne	.-6      	; 0x3fd0 <getNch>
+    3fee:	df df       	rcall	.-66     	; 0x3fae <getch>
+    3ff0:	11 50       	subi	r17, 0x01	; 1
+    3ff2:	e9 f7       	brne	.-6      	; 0x3fee <getNch>
   verifySpace();
-    3fd6:	f4 df       	rcall	.-24     	; 0x3fc0 <verifySpace>
+    3ff4:	f4 df       	rcall	.-24     	; 0x3fde <verifySpace>
 }
-    3fd8:	1f 91       	pop	r17
-    3fda:	08 95       	ret
+    3ff6:	1f 91       	pop	r17
+    3ff8:	08 95       	ret