Parcourir la source

Update some .hex/.lst files to v7, delete some others
as per https://github.com/Optiboot/optiboot/issues/78

WestfW il y a 6 ans
Parent
commit
9b83da3489

+ 41 - 40
optiboot/bootloaders/optiboot/optiboot_atmega1280.hex

@@ -1,43 +1,44 @@
 :020000021000EC
-:10FC0000112494B714BE892F8D7011F0892F0ED155
-:10FC100085E08093810082E08093C00088E180933A
-:10FC2000C10086E08093C20080E18093C4008EE032
-:10FC3000E7D0279A86E020E33CEF91E030938500FF
-:10FC40002093840096BBB09BFECF1F9AA89581504D
-:10FC5000A9F7CC24DD248824839425E0A22E91E109
-:10FC6000992EC2D0813471F4BFD0182FCFD0123862
-:10FC700011F482E005C0113811F486E001C083E080
-:10FC8000ABD0A7C0823411F484E103C0853419F4E9
-:10FC900085E0C4D09EC08535A1F4A6D0082F10E021
-:10FCA000A3D0E82EFF24FE2CEE24E02AF12A8F2D8B
-:10FCB000881F8827881F8BBFEE0CFF1CA7D0670109
-:10FCC00088C0863521F484E0A9D080E0D9CF84367D
-:10FCD00009F052C089D090E0182F002785D090E01D
-:10FCE000082B192B81D0B82EE801E12CA2E0FA2EC6
-:10FCF0007BD0F70181937F012197D1F787D0F5E47D
-:10FD0000BF1689F4E601E12CF2E0FF2E08C0CE0117
-:10FD10002196F70161917F0197D0015010400115A4
-:10FD20001105A9F756C083E0F60187BFE89507B62D
-:10FD300000FCFDCFB801A601A0E0B2E02C9130E0BC
-:10FD400011968C91119790E0982F8827822B932BF6
-:10FD50001296FA010C0187BEE89511244E5F5F4FA1
-:10FD60006250704059F7F601A7BEE89507B600FC4F
-:10FD7000FDCF97BEE8952DC08437F1F435D090E0E3
-:10FD8000D82FCC2731D090E0C82BD92B2DD0182FCD
-:10FD90003DD0153449F48601C8010F5F1F4F4CD088
-:10FDA0001BD02197C9F715C08601F80187918F01F3
-:10FDB00013D02197D1F70DC0853731F427D08EE1CC
-:10FDC0000BD087E909D05BCF813511F488E018D0DA
-:10FDD0001DD080E101D045CF982F8091C00085FFD4
-:10FDE000FCCF9093C60008958091C00087FFFCCFA0
-:10FDF0008091C00084FD01C0A8958091C60008953F
-:10FE0000E0E6F0E098E1908380830895EDDF8032B2
-:10FE100019F088E0F5DFFFCF84E1DECF1F93182FC4
-:10FE2000E3DF1150E9F7F2DF1F910895282E80E0FB
-:10FE3000E7DFEE27FF270994F999FECF92BD81BD38
-:10FE4000F89A992780B50895262FF999FECF1FBA01
-:10FE500092BD81BD20BD0FB6F894FA9AF99A0FBEF3
-:04FE6000019608956A
-:02FFFE000206F9
+:10FC0000112484B7882349F0982F9A70923029F0F4
+:10FC100081FF02C097EF94BF10D185E080938100EF
+:10FC200082E08093C00088E18093C10086E08093E9
+:10FC3000C20080E18093C4008EE0EAD0279A86E07B
+:10FC400020E33CEF91E0309385002093840096BB45
+:10FC5000B09BFECF1F9AA8954091C00047FD02C0FF
+:10FC6000815089F7FF24F39455E0E52E61E1D62E0B
+:10FC7000C3D08134C1F4C0D0C82FD0D0C23809F469
+:10FC80003AC0C13869F487E00CC0843709F482C0F7
+:10FC9000853709F0A2C0C2D08EE1A7D087E9A5D0F0
+:10FCA00083E0A3D09FC0823411F484E103C0853483
+:10FCB00019F485E0BBD096C0853579F49DD0082F26
+:10FCC0009BD0182F87FF03C08BB7816002C08BB712
+:10FCD0008E7F8BBF000F111F84C0863581F48CD0BE
+:10FCE0008D3459F489D0CBB787D0C170880FC82B19
+:10FCF000CBBF81E09BD080E0D4CF83E0FBCF8436C4
+:10FD000009F0C3CF79D0C82FD0E0DC2FCC2774D036
+:10FD1000C82B72D0C82E5E01812C32E0932E6CD09D
+:10FD2000F40181934F01F1E0AF1AB108C1F776D029
+:10FD300085E4C81212C0DE5F4801A12C92E0B92E02
+:10FD4000AC16BD0609F44EC0F50161915F01C40116
+:10FD500082D0FFEF8F1A9F0AF3CF83E0F80187BFAD
+:10FD6000E89507B600FCFDCFA0E0B2E0F8018D9168
+:10FD70009D910C01F7BEE8951124229732962097A9
+:10FD8000B1F7F801E7BEE89507B600FCFDCFD7BE96
+:10FD9000E89528C031D0C82FD0E0DC2FCC272CD05C
+:10FDA0005E01A82A29D0982E39D0E801F5E49F12E7
+:10FDB0000BC0CE0148D019D081E0A81AB108219615
+:10FDC000A114B104B1F70EC0FE018791EF010DD06F
+:10FDD000E1E0AE1AB108C1F705C0813511F488E041
+:10FDE00017D01CD080E101D043CF9091C00095FF87
+:10FDF000FCCF8093C60008958091C00087FFFCCFA0
+:10FE00008091C00084FD01C0A8958091C60008952E
+:10FE1000E0E6F0E098E1908380830895EDDF8032A2
+:10FE200019F088E0F5DFFFCF84E1DFCFCF93C82F53
+:10FE3000E3DFC150E9F7CF91F1CF282E80E0E8DF72
+:10FE4000E0E0FF270994F999FECF92BD81BDF89AB1
+:10FE5000992780B50895262FF999FECF1FBA92BD34
+:10FE600081BD20BD0FB6F894FA9AF99A0FBE01969B
+:02FE70000895F3
+:02FFFE000007FA
 :040000031000FC00ED
 :00000001FF

+ 449 - 407
optiboot/bootloaders/optiboot/optiboot_atmega1280.lst

@@ -3,682 +3,724 @@ optiboot_atmega1280.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         00000264  0001fc00  0001fc00  00000074  2**1
+  0 .data         00000000  00800200  0001fe72  00000306  2**0
+                  CONTENTS, ALLOC, LOAD, DATA
+  1 .text         00000272  0001fc00  0001fc00  00000094  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  0001fffe  0001fffe  000002d8  2**0
+  2 .version      00000002  0001fffe  0001fffe  00000306  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .stab         00000180  00000000  00000000  000002dc  2**2
+  3 .comment      0000002f  00000000  00000000  00000308  2**0
+                  CONTENTS, READONLY
+  4 .debug_aranges 00000028  00000000  00000000  00000337  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .stabstr      000000bb  00000000  00000000  0000045c  2**0
+  5 .debug_info   00000632  00000000  00000000  0000035f  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_aranges 00000028  00000000  00000000  00000517  2**0
+  6 .debug_abbrev 00000286  00000000  00000000  00000991  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_pubnames 00000074  00000000  00000000  0000053f  2**0
+  7 .debug_line   00000385  00000000  00000000  00000c17  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_info   000003f0  00000000  00000000  000005b3  2**0
+  8 .debug_frame  0000008c  00000000  00000000  00000f9c  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_abbrev 000001fe  00000000  00000000  000009a3  2**0
+  9 .debug_str    0000021e  00000000  00000000  00001028  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_line   0000044b  00000000  00000000  00000ba1  2**0
+ 10 .debug_loc    00000421  00000000  00000000  00001246  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_frame  00000080  00000000  00000000  00000fec  2**2
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_str    0000017c  00000000  00000000  0000106c  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 11 .debug_loc    000003b3  00000000  00000000  000011e8  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 12 .debug_ranges 000000d0  00000000  00000000  0000159b  2**0
+ 11 .debug_ranges 00000078  00000000  00000000  00001667  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 0001fc00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
+  //  SP points to RAMEND
+  //  r1 contains zero
+  //
+  // If not, uncomment the following instructions:
+  // cli();
+  asm volatile ("clr __zero_reg__");
    1fc00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
+   * 
+   * Code by MarkG55
+   * see discusion in https://github.com/Optiboot/optiboot/issues/97
    */
+#if !defined(__AVR_ATmega16__)
   ch = MCUSR;
-   1fc02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-   1fc04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-   1fc06:	89 2f       	mov	r24, r25
-   1fc08:	8d 70       	andi	r24, 0x0D	; 13
-   1fc0a:	11 f0       	breq	.+4      	; 0x1fc10 <main+0x10>
-      appStart(ch);
-   1fc0c:	89 2f       	mov	r24, r25
-   1fc0e:	0e d1       	rcall	.+540    	; 0x1fe2c <appStart>
+   1fc02:	84 b7       	in	r24, 0x34	; 52
+#else
+  ch = MCUCSR;
+#endif
+  // Skip all logic and run bootloader if MCUSR is cleared (application request)
+  if (ch != 0) {
+   1fc04:	88 23       	and	r24, r24
+   1fc06:	49 f0       	breq	.+18     	; 0x1fc1a <main+0x1a>
+       *  2. we clear WDRF if it's set with EXTRF to avoid loops
+       * One problematic scenario: broken application code sets watchdog timer 
+       * without clearing MCUSR before and triggers it quickly. But it's
+       * recoverable by power-on with pushed reset button.
+       */
+      if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) { 
+   1fc08:	98 2f       	mov	r25, r24
+   1fc0a:	9a 70       	andi	r25, 0x0A	; 10
+   1fc0c:	92 30       	cpi	r25, 0x02	; 2
+   1fc0e:	29 f0       	breq	.+10     	; 0x1fc1a <main+0x1a>
+	  if (ch & _BV(EXTRF)) {
+   1fc10:	81 ff       	sbrs	r24, 1
+   1fc12:	02 c0       	rjmp	.+4      	; 0x1fc18 <main+0x18>
+	       * prevent entering bootloader.
+	       * '&' operation is skipped to spare few bytes as bits in MCUSR
+	       * can only be cleared.
+	       */
+#if !defined(__AVR_ATmega16__)
+	      MCUSR = ~(_BV(WDRF));  
+   1fc14:	97 ef       	ldi	r25, 0xF7	; 247
+   1fc16:	94 bf       	out	0x34, r25	; 52
+#else
+	      MCUCSR = ~(_BV(WDRF));  
+#endif
+	  }
+	  appStart(ch);
+   1fc18:	10 d1       	rcall	.+544    	; 0x1fe3a <appStart>
+      }
+  }
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
   TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-   1fc10:	85 e0       	ldi	r24, 0x05	; 5
-   1fc12:	80 93 81 00 	sts	0x0081, r24
+   1fc1a:	85 e0       	ldi	r24, 0x05	; 5
+   1fc1c:	80 93 81 00 	sts	0x0081, r24	; 0x800081 <__TEXT_REGION_LENGTH__+0x7e0081>
   UCSRA = _BV(U2X); //Double speed mode USART
   UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
   UART_SRA = _BV(U2X0); //Double speed mode USART0
-   1fc16:	82 e0       	ldi	r24, 0x02	; 2
-   1fc18:	80 93 c0 00 	sts	0x00C0, r24
+   1fc20:	82 e0       	ldi	r24, 0x02	; 2
+   1fc22:	80 93 c0 00 	sts	0x00C0, r24	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-   1fc1c:	88 e1       	ldi	r24, 0x18	; 24
-   1fc1e:	80 93 c1 00 	sts	0x00C1, r24
+   1fc26:	88 e1       	ldi	r24, 0x18	; 24
+   1fc28:	80 93 c1 00 	sts	0x00C1, r24	; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7e00c1>
   UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-   1fc22:	86 e0       	ldi	r24, 0x06	; 6
-   1fc24:	80 93 c2 00 	sts	0x00C2, r24
+   1fc2c:	86 e0       	ldi	r24, 0x06	; 6
+   1fc2e:	80 93 c2 00 	sts	0x00C2, r24	; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7e00c2>
   UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-   1fc28:	80 e1       	ldi	r24, 0x10	; 16
-   1fc2a:	80 93 c4 00 	sts	0x00C4, r24
+   1fc32:	80 e1       	ldi	r24, 0x10	; 16
+   1fc34:	80 93 c4 00 	sts	0x00C4, r24	; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7e00c4>
 #endif
 #endif
 
-  // Set up watchdog to trigger after 500ms
+  // Set up watchdog to trigger after 1s
   watchdogConfig(WATCHDOG_1S);
-   1fc2e:	8e e0       	ldi	r24, 0x0E	; 14
-   1fc30:	e7 d0       	rcall	.+462    	; 0x1fe00 <watchdogConfig>
+   1fc38:	8e e0       	ldi	r24, 0x0E	; 14
+   1fc3a:	ea d0       	rcall	.+468    	; 0x1fe10 <watchdogConfig>
 
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
-   1fc32:	27 9a       	sbi	0x04, 7	; 4
-   1fc34:	86 e0       	ldi	r24, 0x06	; 6
+   1fc3c:	27 9a       	sbi	0x04, 7	; 4
+   1fc3e:	86 e0       	ldi	r24, 0x06	; 6
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-   1fc36:	20 e3       	ldi	r18, 0x30	; 48
-   1fc38:	3c ef       	ldi	r19, 0xFC	; 252
+   1fc40:	20 e3       	ldi	r18, 0x30	; 48
+   1fc42:	3c ef       	ldi	r19, 0xFC	; 252
     TIFR1 = _BV(TOV1);
-   1fc3a:	91 e0       	ldi	r25, 0x01	; 1
+   1fc44:	91 e0       	ldi	r25, 0x01	; 1
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-   1fc3c:	30 93 85 00 	sts	0x0085, r19
-   1fc40:	20 93 84 00 	sts	0x0084, r18
+   1fc46:	30 93 85 00 	sts	0x0085, r19	; 0x800085 <__TEXT_REGION_LENGTH__+0x7e0085>
+   1fc4a:	20 93 84 00 	sts	0x0084, r18	; 0x800084 <__TEXT_REGION_LENGTH__+0x7e0084>
     TIFR1 = _BV(TOV1);
-   1fc44:	96 bb       	out	0x16, r25	; 22
+   1fc4e:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
-   1fc46:	b0 9b       	sbis	0x16, 0	; 22
-   1fc48:	fe cf       	rjmp	.-4      	; 0x1fc46 <main+0x46>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
+   1fc50:	b0 9b       	sbis	0x16, 0	; 22
+   1fc52:	fe cf       	rjmp	.-4      	; 0x1fc50 <main+0x50>
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
     LED_PORT ^= _BV(LED);
 #else
     LED_PIN |= _BV(LED);
-   1fc4a:	1f 9a       	sbi	0x03, 7	; 3
+   1fc54:	1f 9a       	sbi	0x03, 7	; 3
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-   1fc4c:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
+   1fc56:	a8 95       	wdr
+     * While in theory, the STK500 initial commands would be buffered
+     *  by the UART hardware, avrdude sends several attempts in rather
+     *  quick succession, some of which will be lost and cause us to
+     *  get out of sync.  So if we see any data; stop blinking.
+     */
+    if (UART_SRA & _BV(RXC0))
+   1fc58:	40 91 c0 00 	lds	r20, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+   1fc5c:	47 fd       	sbrc	r20, 7
+   1fc5e:	02 c0       	rjmp	.+4      	; 0x1fc64 <main+0x64>
+   1fc60:	81 50       	subi	r24, 0x01	; 1
 #else
-    LED_PIN |= _BV(LED);
+// This doesn't seem to work?
+//    if ((UART_PIN & (1<<UART_RX_BIT)) == 0)
+//	break;  // detect start bit on soft uart too.
 #endif
-    watchdogReset();
   } while (--count);
-   1fc4e:	81 50       	subi	r24, 0x01	; 1
-   1fc50:	a9 f7       	brne	.-22     	; 0x1fc3c <main+0x3c>
-   1fc52:	cc 24       	eor	r12, r12
-   1fc54:	dd 24       	eor	r13, r13
+   1fc62:	89 f7       	brne	.-30     	; 0x1fc46 <main+0x46>
+
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-   1fc56:	88 24       	eor	r8, r8
-   1fc58:	83 94       	inc	r8
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+   1fc64:	ff 24       	eor	r15, r15
+   1fc66:	f3 94       	inc	r15
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-   1fc5a:	25 e0       	ldi	r18, 0x05	; 5
-   1fc5c:	a2 2e       	mov	r10, r18
+	    __boot_page_write_short(address.word);
+   1fc68:	55 e0       	ldi	r21, 0x05	; 5
+   1fc6a:	e5 2e       	mov	r14, r21
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
-	    boot_rww_enable();
-   1fc5e:	91 e1       	ldi	r25, 0x11	; 17
-   1fc60:	99 2e       	mov	r9, r25
+	    __boot_rww_enable_short();
+   1fc6c:	61 e1       	ldi	r22, 0x11	; 17
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-   1fc62:	c2 d0       	rcall	.+388    	; 0x1fde8 <getch>
+   1fc6e:	d6 2e       	mov	r13, r22
 
     if(ch == STK_GET_PARAMETER) {
-   1fc64:	81 34       	cpi	r24, 0x41	; 65
-   1fc66:	71 f4       	brne	.+28     	; 0x1fc84 <main+0x84>
+   1fc70:	c3 d0       	rcall	.+390    	; 0x1fdf8 <getch>
       unsigned char which = getch();
-   1fc68:	bf d0       	rcall	.+382    	; 0x1fde8 <getch>
-   1fc6a:	18 2f       	mov	r17, r24
+   1fc72:	81 34       	cpi	r24, 0x41	; 65
+   1fc74:	c1 f4       	brne	.+48     	; 0x1fca6 <main+0xa6>
+   1fc76:	c0 d0       	rcall	.+384    	; 0x1fdf8 <getch>
       verifySpace();
-   1fc6c:	cf d0       	rcall	.+414    	; 0x1fe0c <verifySpace>
+   1fc78:	c8 2f       	mov	r28, r24
+   1fc7a:	d0 d0       	rcall	.+416    	; 0x1fe1c <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
-      if (which == 0x82) {
-   1fc6e:	12 38       	cpi	r17, 0x82	; 130
-   1fc70:	11 f4       	brne	.+4      	; 0x1fc76 <main+0x76>
+      if (which == STK_SW_MINOR) {
+   1fc7c:	c2 38       	cpi	r28, 0x82	; 130
+   1fc7e:	09 f4       	brne	.+2      	; 0x1fc82 <main+0x82>
+   1fc80:	3a c0       	rjmp	.+116    	; 0x1fcf6 <main+0xf6>
 	  putch(optiboot_version & 0xFF);
-   1fc72:	82 e0       	ldi	r24, 0x02	; 2
-   1fc74:	05 c0       	rjmp	.+10     	; 0x1fc80 <main+0x80>
-      } else if (which == 0x81) {
-   1fc76:	11 38       	cpi	r17, 0x81	; 129
-   1fc78:	11 f4       	brne	.+4      	; 0x1fc7e <main+0x7e>
+      } else if (which == STK_SW_MAJOR) {
+   1fc82:	c1 38       	cpi	r28, 0x81	; 129
+   1fc84:	69 f4       	brne	.+26     	; 0x1fca0 <main+0xa0>
 	  putch(optiboot_version >> 8);
-   1fc7a:	86 e0       	ldi	r24, 0x06	; 6
-   1fc7c:	01 c0       	rjmp	.+2      	; 0x1fc80 <main+0x80>
+   1fc86:	87 e0       	ldi	r24, 0x07	; 7
+   1fc88:	0c c0       	rjmp	.+24     	; 0x1fca2 <main+0xa2>
+      writebuffer(desttype, buff, address, savelength);
+
+
+    }
+    /* Read memory block mode, length is big endian.  */
+    else if(ch == STK_READ_PAGE) {
+   1fc8a:	84 37       	cpi	r24, 0x74	; 116
+   1fc8c:	09 f4       	brne	.+2      	; 0x1fc90 <main+0x90>
+
+      read_mem(desttype, address, length);
+    }
+
+    /* Get device signature bytes  */
+    else if(ch == STK_READ_SIGN) {
+   1fc8e:	82 c0       	rjmp	.+260    	; 0x1fd94 <main+0x194>
+   1fc90:	85 37       	cpi	r24, 0x75	; 117
+      // READ SIGN - return what Avrdude wants to hear
+      verifySpace();
+   1fc92:	09 f0       	breq	.+2      	; 0x1fc96 <main+0x96>
+      putch(SIGNATURE_0);
+   1fc94:	a2 c0       	rjmp	.+324    	; 0x1fdda <main+0x1da>
+   1fc96:	c2 d0       	rcall	.+388    	; 0x1fe1c <verifySpace>
+   1fc98:	8e e1       	ldi	r24, 0x1E	; 30
+      putch(SIGNATURE_1);
+   1fc9a:	a7 d0       	rcall	.+334    	; 0x1fdea <putch>
+   1fc9c:	87 e9       	ldi	r24, 0x97	; 151
+   1fc9e:	a5 d0       	rcall	.+330    	; 0x1fdea <putch>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-   1fc7e:	83 e0       	ldi	r24, 0x03	; 3
-   1fc80:	ab d0       	rcall	.+342    	; 0x1fdd8 <putch>
-   1fc82:	a7 c0       	rjmp	.+334    	; 0x1fdd2 <main+0x1d2>
+   1fca0:	83 e0       	ldi	r24, 0x03	; 3
+   1fca2:	a3 d0       	rcall	.+326    	; 0x1fdea <putch>
+   1fca4:	9f c0       	rjmp	.+318    	; 0x1fde4 <main+0x1e4>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-   1fc84:	82 34       	cpi	r24, 0x42	; 66
-   1fc86:	11 f4       	brne	.+4      	; 0x1fc8c <main+0x8c>
+   1fca6:	82 34       	cpi	r24, 0x42	; 66
+   1fca8:	11 f4       	brne	.+4      	; 0x1fcae <main+0xae>
       // SET DEVICE is ignored
       getNch(20);
-   1fc88:	84 e1       	ldi	r24, 0x14	; 20
-   1fc8a:	03 c0       	rjmp	.+6      	; 0x1fc92 <main+0x92>
+   1fcaa:	84 e1       	ldi	r24, 0x14	; 20
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-   1fc8c:	85 34       	cpi	r24, 0x45	; 69
-   1fc8e:	19 f4       	brne	.+6      	; 0x1fc96 <main+0x96>
+   1fcac:	03 c0       	rjmp	.+6      	; 0x1fcb4 <main+0xb4>
       // SET DEVICE EXT is ignored
       getNch(5);
-   1fc90:	85 e0       	ldi	r24, 0x05	; 5
-   1fc92:	c4 d0       	rcall	.+392    	; 0x1fe1c <getNch>
-   1fc94:	9e c0       	rjmp	.+316    	; 0x1fdd2 <main+0x1d2>
+   1fcae:	85 34       	cpi	r24, 0x45	; 69
+   1fcb0:	19 f4       	brne	.+6      	; 0x1fcb8 <main+0xb8>
+   1fcb2:	85 e0       	ldi	r24, 0x05	; 5
+   1fcb4:	bb d0       	rcall	.+374    	; 0x1fe2c <getNch>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-   1fc96:	85 35       	cpi	r24, 0x55	; 85
-   1fc98:	a1 f4       	brne	.+40     	; 0x1fcc2 <main+0xc2>
+   1fcb6:	96 c0       	rjmp	.+300    	; 0x1fde4 <main+0x1e4>
+   1fcb8:	85 35       	cpi	r24, 0x55	; 85
       // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-   1fc9a:	a6 d0       	rcall	.+332    	; 0x1fde8 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-   1fc9c:	08 2f       	mov	r16, r24
-   1fc9e:	10 e0       	ldi	r17, 0x00	; 0
-   1fca0:	a3 d0       	rcall	.+326    	; 0x1fde8 <getch>
-   1fca2:	e8 2e       	mov	r14, r24
-   1fca4:	ff 24       	eor	r15, r15
-   1fca6:	fe 2c       	mov	r15, r14
-   1fca8:	ee 24       	eor	r14, r14
-   1fcaa:	e0 2a       	or	r14, r16
-   1fcac:	f1 2a       	or	r15, r17
+      address.bytes[0] = getch();
+   1fcba:	79 f4       	brne	.+30     	; 0x1fcda <main+0xda>
+   1fcbc:	9d d0       	rcall	.+314    	; 0x1fdf8 <getch>
+   1fcbe:	08 2f       	mov	r16, r24
+      address.bytes[1] = getch();
+   1fcc0:	9b d0       	rcall	.+310    	; 0x1fdf8 <getch>
+   1fcc2:	18 2f       	mov	r17, r24
+   1fcc4:	87 ff       	sbrs	r24, 7
 #ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
-   1fcae:	8f 2d       	mov	r24, r15
-   1fcb0:	88 1f       	adc	r24, r24
-   1fcb2:	88 27       	eor	r24, r24
-   1fcb4:	88 1f       	adc	r24, r24
-   1fcb6:	8b bf       	out	0x3b, r24	; 59
+      // Transfer top bit to LSB in RAMPZ
+      if (address.bytes[1] & 0x80) {
+   1fcc6:	03 c0       	rjmp	.+6      	; 0x1fcce <main+0xce>
+        RAMPZ |= 0x01;
+   1fcc8:	8b b7       	in	r24, 0x3b	; 59
+   1fcca:	81 60       	ori	r24, 0x01	; 1
+      }
+      else {
+        RAMPZ &= 0xFE;
+   1fccc:	02 c0       	rjmp	.+4      	; 0x1fcd2 <main+0xd2>
+   1fcce:	8b b7       	in	r24, 0x3b	; 59
+      }
 #endif
-      newAddress += newAddress; // Convert from word address to byte address
-   1fcb8:	ee 0c       	add	r14, r14
-   1fcba:	ff 1c       	adc	r15, r15
-      address = newAddress;
+      address.word *= 2; // Convert from word address to byte address
+   1fcd0:	8e 7f       	andi	r24, 0xFE	; 254
+   1fcd2:	8b bf       	out	0x3b, r24	; 59
+   1fcd4:	00 0f       	add	r16, r16
       verifySpace();
-   1fcbc:	a7 d0       	rcall	.+334    	; 0x1fe0c <verifySpace>
-   1fcbe:	67 01       	movw	r12, r14
-   1fcc0:	88 c0       	rjmp	.+272    	; 0x1fdd2 <main+0x1d2>
     }
     else if(ch == STK_UNIVERSAL) {
-   1fcc2:	86 35       	cpi	r24, 0x56	; 86
-   1fcc4:	21 f4       	brne	.+8      	; 0x1fcce <main+0xce>
-      // UNIVERSAL command is ignored
+   1fcd6:	11 1f       	adc	r17, r17
+#ifdef RAMPZ
+      // LOAD_EXTENDED_ADDRESS is needed in STK_UNIVERSAL for addressing more than 128kB
+      if ( AVR_OP_LOAD_EXT_ADDR == getch() ) {
+   1fcd8:	84 c0       	rjmp	.+264    	; 0x1fde2 <main+0x1e2>
+   1fcda:	86 35       	cpi	r24, 0x56	; 86
+   1fcdc:	81 f4       	brne	.+32     	; 0x1fcfe <main+0xfe>
+   1fcde:	8c d0       	rcall	.+280    	; 0x1fdf8 <getch>
+        // get address
+        getch();  // get '0'
+   1fce0:	8d 34       	cpi	r24, 0x4D	; 77
+   1fce2:	59 f4       	brne	.+22     	; 0x1fcfa <main+0xfa>
+        RAMPZ = (RAMPZ & 0x01) | ((getch() << 1) & 0xff);  // get address and put it in RAMPZ
+   1fce4:	89 d0       	rcall	.+274    	; 0x1fdf8 <getch>
+   1fce6:	cb b7       	in	r28, 0x3b	; 59
+   1fce8:	87 d0       	rcall	.+270    	; 0x1fdf8 <getch>
+   1fcea:	c1 70       	andi	r28, 0x01	; 1
+   1fcec:	88 0f       	add	r24, r24
+   1fcee:	c8 2b       	or	r28, r24
+        getNch(1); // get last '0'
+   1fcf0:	cb bf       	out	0x3b, r28	; 59
+   1fcf2:	81 e0       	ldi	r24, 0x01	; 1
+        // response
+        putch(0x00);
+   1fcf4:	9b d0       	rcall	.+310    	; 0x1fe2c <getNch>
+   1fcf6:	80 e0       	ldi	r24, 0x00	; 0
+      }
+      else {
+        // everything else is ignored
+        getNch(3);
+   1fcf8:	d4 cf       	rjmp	.-88     	; 0x1fca2 <main+0xa2>
+   1fcfa:	83 e0       	ldi	r24, 0x03	; 3
       getNch(4);
-   1fcc6:	84 e0       	ldi	r24, 0x04	; 4
-   1fcc8:	a9 d0       	rcall	.+338    	; 0x1fe1c <getNch>
       putch(0x00);
-   1fcca:	80 e0       	ldi	r24, 0x00	; 0
-   1fccc:	d9 cf       	rjmp	.-78     	; 0x1fc80 <main+0x80>
+#endif
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-   1fcce:	84 36       	cpi	r24, 0x64	; 100
-   1fcd0:	09 f0       	breq	.+2      	; 0x1fcd4 <main+0xd4>
-   1fcd2:	52 c0       	rjmp	.+164    	; 0x1fd78 <main+0x178>
+   1fcfc:	fb cf       	rjmp	.-10     	; 0x1fcf4 <main+0xf4>
+   1fcfe:	84 36       	cpi	r24, 0x64	; 100
+      // PROGRAM PAGE - we support flash programming only, not EEPROM
+      uint8_t desttype;
+      uint8_t *bufPtr;
+      pagelen_t savelength;
+
+      GETLENGTH(length);
+   1fd00:	09 f0       	breq	.+2      	; 0x1fd04 <main+0x104>
+   1fd02:	c3 cf       	rjmp	.-122    	; 0x1fc8a <main+0x8a>
+   1fd04:	79 d0       	rcall	.+242    	; 0x1fdf8 <getch>
+   1fd06:	c8 2f       	mov	r28, r24
+   1fd08:	d0 e0       	ldi	r29, 0x00	; 0
+   1fd0a:	dc 2f       	mov	r29, r28
+   1fd0c:	cc 27       	eor	r28, r28
+   1fd0e:	74 d0       	rcall	.+232    	; 0x1fdf8 <getch>
+      savelength = length;
+      desttype = getch();
+   1fd10:	c8 2b       	or	r28, r24
+   1fd12:	72 d0       	rcall	.+228    	; 0x1fdf8 <getch>
+   1fd14:	c8 2e       	mov	r12, r24
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
       pagelen_t savelength;
 
       GETLENGTH(length);
-   1fcd4:	89 d0       	rcall	.+274    	; 0x1fde8 <getch>
-   1fcd6:	90 e0       	ldi	r25, 0x00	; 0
-   1fcd8:	18 2f       	mov	r17, r24
-   1fcda:	00 27       	eor	r16, r16
-   1fcdc:	85 d0       	rcall	.+266    	; 0x1fde8 <getch>
-   1fcde:	90 e0       	ldi	r25, 0x00	; 0
-   1fce0:	08 2b       	or	r16, r24
-   1fce2:	19 2b       	or	r17, r25
+   1fd16:	5e 01       	movw	r10, r28
       savelength = length;
       desttype = getch();
-   1fce4:	81 d0       	rcall	.+258    	; 0x1fde8 <getch>
-   1fce6:	b8 2e       	mov	r11, r24
-   1fce8:	e8 01       	movw	r28, r16
-   1fcea:	e1 2c       	mov	r14, r1
-   1fcec:	a2 e0       	ldi	r26, 0x02	; 2
-   1fcee:	fa 2e       	mov	r15, r26
+   1fd18:	81 2c       	mov	r8, r1
+   1fd1a:	32 e0       	ldi	r19, 0x02	; 2
+   1fd1c:	93 2e       	mov	r9, r19
 
       // read a page worth of contents
-      bufPtr = buff;
+      bufPtr = buff.bptr;
       do *bufPtr++ = getch();
-   1fcf0:	7b d0       	rcall	.+246    	; 0x1fde8 <getch>
-   1fcf2:	f7 01       	movw	r30, r14
-   1fcf4:	81 93       	st	Z+, r24
-   1fcf6:	7f 01       	movw	r14, r30
+   1fd1e:	6c d0       	rcall	.+216    	; 0x1fdf8 <getch>
+   1fd20:	f4 01       	movw	r30, r8
+   1fd22:	81 93       	st	Z+, r24
+   1fd24:	4f 01       	movw	r8, r30
+   1fd26:	f1 e0       	ldi	r31, 0x01	; 1
       while (--length);
-   1fcf8:	21 97       	sbiw	r28, 0x01	; 1
-   1fcfa:	d1 f7       	brne	.-12     	; 0x1fcf0 <main+0xf0>
+   1fd28:	af 1a       	sub	r10, r31
+   1fd2a:	b1 08       	sbc	r11, r1
+   1fd2c:	c1 f7       	brne	.-16     	; 0x1fd1e <main+0x11e>
 
       // Read command terminator, start reply
       verifySpace();
-   1fcfc:	87 d0       	rcall	.+270    	; 0x1fe0c <verifySpace>
+   1fd2e:	76 d0       	rcall	.+236    	; 0x1fe1c <verifySpace>
+   1fd30:	85 e4       	ldi	r24, 0x45	; 69
  * void writebuffer(memtype, buffer, address, length)
  */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+			       addr16_t address, pagelen_t len)
 {
     switch (memtype) {
-   1fcfe:	f5 e4       	ldi	r31, 0x45	; 69
-   1fd00:	bf 16       	cp	r11, r31
-   1fd02:	89 f4       	brne	.+34     	; 0x1fd26 <main+0x126>
-   1fd04:	e6 01       	movw	r28, r12
-   1fd06:	e1 2c       	mov	r14, r1
-   1fd08:	f2 e0       	ldi	r31, 0x02	; 2
-   1fd0a:	ff 2e       	mov	r15, r31
-   1fd0c:	08 c0       	rjmp	.+16     	; 0x1fd1e <main+0x11e>
-   1fd0e:	ce 01       	movw	r24, r28
+   1fd32:	c8 12       	cpse	r12, r24
+   1fd34:	12 c0       	rjmp	.+36     	; 0x1fd5a <main+0x15a>
+   1fd36:	de 5f       	subi	r29, 0xFE	; 254
+   1fd38:	48 01       	movw	r8, r16
+   1fd3a:	a1 2c       	mov	r10, r1
+   1fd3c:	92 e0       	ldi	r25, 0x02	; 2
+   1fd3e:	b9 2e       	mov	r11, r25
+   1fd40:	ac 16       	cp	r10, r28
     case 'E': // EEPROM
 #if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
         while(len--) {
-	    eeprom_write_byte((uint8_t *)(address++), *mybuff++);
-   1fd10:	21 96       	adiw	r28, 0x01	; 1
-   1fd12:	f7 01       	movw	r30, r14
-   1fd14:	61 91       	ld	r22, Z+
-   1fd16:	7f 01       	movw	r14, r30
-   1fd18:	97 d0       	rcall	.+302    	; 0x1fe48 <__eewr_byte_m1280>
-   1fd1a:	01 50       	subi	r16, 0x01	; 1
-   1fd1c:	10 40       	sbci	r17, 0x00	; 0
-			       uint16_t address, pagelen_t len)
-{
-    switch (memtype) {
-    case 'E': // EEPROM
-#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
-        while(len--) {
-   1fd1e:	01 15       	cp	r16, r1
-   1fd20:	11 05       	cpc	r17, r1
-   1fd22:	a9 f7       	brne	.-22     	; 0x1fd0e <main+0x10e>
-   1fd24:	56 c0       	rjmp	.+172    	; 0x1fdd2 <main+0x1d2>
+   1fd42:	bd 06       	cpc	r11, r29
+   1fd44:	09 f4       	brne	.+2      	; 0x1fd48 <main+0x148>
+   1fd46:	4e c0       	rjmp	.+156    	; 0x1fde4 <main+0x1e4>
+   1fd48:	f5 01       	movw	r30, r10
+	    eeprom_write_byte((address.bptr++), *(mybuff.bptr++));
+   1fd4a:	61 91       	ld	r22, Z+
+   1fd4c:	5f 01       	movw	r10, r30
+   1fd4e:	c4 01       	movw	r24, r8
+   1fd50:	82 d0       	rcall	.+260    	; 0x1fe56 <eeprom_write_byte>
+   1fd52:	ff ef       	ldi	r31, 0xFF	; 255
+   1fd54:	8f 1a       	sub	r8, r31
+   1fd56:	9f 0a       	sbc	r9, r31
+   1fd58:	f3 cf       	rjmp	.-26     	; 0x1fd40 <main+0x140>
+   1fd5a:	83 e0       	ldi	r24, 0x03	; 3
+   1fd5c:	f8 01       	movw	r30, r16
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-   1fd26:	83 e0       	ldi	r24, 0x03	; 3
-   1fd28:	f6 01       	movw	r30, r12
-   1fd2a:	87 bf       	out	0x37, r24	; 55
-   1fd2c:	e8 95       	spm
+	    __boot_page_erase_short(address.word);
+   1fd5e:	87 bf       	out	0x37, r24	; 55
+   1fd60:	e8 95       	spm
+   1fd62:	07 b6       	in	r0, 0x37	; 55
+   1fd64:	00 fc       	sbrc	r0, 0
 	    boot_spm_busy_wait();
-   1fd2e:	07 b6       	in	r0, 0x37	; 55
-   1fd30:	00 fc       	sbrc	r0, 0
-   1fd32:	fd cf       	rjmp	.-6      	; 0x1fd2e <main+0x12e>
-   1fd34:	b8 01       	movw	r22, r16
-   1fd36:	a6 01       	movw	r20, r12
-   1fd38:	a0 e0       	ldi	r26, 0x00	; 0
-   1fd3a:	b2 e0       	ldi	r27, 0x02	; 2
+   1fd66:	fd cf       	rjmp	.-6      	; 0x1fd62 <main+0x162>
+   1fd68:	a0 e0       	ldi	r26, 0x00	; 0
+   1fd6a:	b2 e0       	ldi	r27, 0x02	; 2
+   1fd6c:	f8 01       	movw	r30, r16
+   1fd6e:	8d 91       	ld	r24, X+
+
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-   1fd3c:	2c 91       	ld	r18, X
-   1fd3e:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-   1fd40:	11 96       	adiw	r26, 0x01	; 1
-   1fd42:	8c 91       	ld	r24, X
-   1fd44:	11 97       	sbiw	r26, 0x01	; 1
-   1fd46:	90 e0       	ldi	r25, 0x00	; 0
-   1fd48:	98 2f       	mov	r25, r24
-   1fd4a:	88 27       	eor	r24, r24
-   1fd4c:	82 2b       	or	r24, r18
-   1fd4e:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-   1fd50:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-   1fd52:	fa 01       	movw	r30, r20
-   1fd54:	0c 01       	movw	r0, r24
-   1fd56:	87 be       	out	0x37, r8	; 55
-   1fd58:	e8 95       	spm
-   1fd5a:	11 24       	eor	r1, r1
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+   1fd70:	9d 91       	ld	r25, X+
+   1fd72:	0c 01       	movw	r0, r24
+   1fd74:	f7 be       	out	0x37, r15	; 55
+   1fd76:	e8 95       	spm
+   1fd78:	11 24       	eor	r1, r1
 		addrPtr += 2;
-   1fd5c:	4e 5f       	subi	r20, 0xFE	; 254
-   1fd5e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-   1fd60:	62 50       	subi	r22, 0x02	; 2
-   1fd62:	70 40       	sbci	r23, 0x00	; 0
-   1fd64:	59 f7       	brne	.-42     	; 0x1fd3c <main+0x13c>
+   1fd7a:	22 97       	sbiw	r28, 0x02	; 2
+   1fd7c:	32 96       	adiw	r30, 0x02	; 2
+   1fd7e:	20 97       	sbiw	r28, 0x00	; 0
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-   1fd66:	f6 01       	movw	r30, r12
-   1fd68:	a7 be       	out	0x37, r10	; 55
-   1fd6a:	e8 95       	spm
+	    __boot_page_write_short(address.word);
+   1fd80:	b1 f7       	brne	.-20     	; 0x1fd6e <main+0x16e>
+   1fd82:	f8 01       	movw	r30, r16
+   1fd84:	e7 be       	out	0x37, r14	; 55
 	    boot_spm_busy_wait();
-   1fd6c:	07 b6       	in	r0, 0x37	; 55
-   1fd6e:	00 fc       	sbrc	r0, 0
-   1fd70:	fd cf       	rjmp	.-6      	; 0x1fd6c <main+0x16c>
+   1fd86:	e8 95       	spm
 #if defined(RWWSRE)
 	    // Reenable read access to flash
-	    boot_rww_enable();
-   1fd72:	97 be       	out	0x37, r9	; 55
-   1fd74:	e8 95       	spm
-   1fd76:	2d c0       	rjmp	.+90     	; 0x1fdd2 <main+0x1d2>
-      writebuffer(desttype, buff, address, savelength);
-
+	    __boot_rww_enable_short();
+   1fd88:	07 b6       	in	r0, 0x37	; 55
+   1fd8a:	00 fc       	sbrc	r0, 0
+   1fd8c:	fd cf       	rjmp	.-6      	; 0x1fd88 <main+0x188>
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-   1fd78:	84 37       	cpi	r24, 0x74	; 116
-   1fd7a:	f1 f4       	brne	.+60     	; 0x1fdb8 <main+0x1b8>
       uint8_t desttype;
       GETLENGTH(length);
-   1fd7c:	35 d0       	rcall	.+106    	; 0x1fde8 <getch>
-   1fd7e:	90 e0       	ldi	r25, 0x00	; 0
-   1fd80:	d8 2f       	mov	r29, r24
-   1fd82:	cc 27       	eor	r28, r28
-   1fd84:	31 d0       	rcall	.+98     	; 0x1fde8 <getch>
-   1fd86:	90 e0       	ldi	r25, 0x00	; 0
-   1fd88:	c8 2b       	or	r28, r24
-   1fd8a:	d9 2b       	or	r29, r25
+   1fd8e:	d7 be       	out	0x37, r13	; 55
+   1fd90:	e8 95       	spm
+   1fd92:	28 c0       	rjmp	.+80     	; 0x1fde4 <main+0x1e4>
+   1fd94:	31 d0       	rcall	.+98     	; 0x1fdf8 <getch>
+   1fd96:	c8 2f       	mov	r28, r24
+   1fd98:	d0 e0       	ldi	r29, 0x00	; 0
+   1fd9a:	dc 2f       	mov	r29, r28
+   1fd9c:	cc 27       	eor	r28, r28
+   1fd9e:	2c d0       	rcall	.+88     	; 0x1fdf8 <getch>
 
       desttype = getch();
-   1fd8c:	2d d0       	rcall	.+90     	; 0x1fde8 <getch>
-   1fd8e:	18 2f       	mov	r17, r24
+   1fda0:	5e 01       	movw	r10, r28
+   1fda2:	a8 2a       	or	r10, r24
+   1fda4:	29 d0       	rcall	.+82     	; 0x1fdf8 <getch>
 
       verifySpace();
-   1fd90:	3d d0       	rcall	.+122    	; 0x1fe0c <verifySpace>
+   1fda6:	98 2e       	mov	r9, r24
+   1fda8:	39 d0       	rcall	.+114    	; 0x1fe1c <verifySpace>
+   1fdaa:	e8 01       	movw	r28, r16
 
-static inline void read_mem(uint8_t memtype, uint16_t address, pagelen_t length)
+static inline void read_mem(uint8_t memtype, addr16_t address, pagelen_t length)
 {
     uint8_t ch;
 
     switch (memtype) {
-   1fd92:	15 34       	cpi	r17, 0x45	; 69
-   1fd94:	49 f4       	brne	.+18     	; 0x1fda8 <main+0x1a8>
-   1fd96:	86 01       	movw	r16, r12
-   1fd98:	c8 01       	movw	r24, r16
+   1fdac:	f5 e4       	ldi	r31, 0x45	; 69
 
 #if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
     case 'E': // EEPROM
 	do {
-	    putch(eeprom_read_byte((uint8_t *)(address++)));
-   1fd9a:	0f 5f       	subi	r16, 0xFF	; 255
-   1fd9c:	1f 4f       	sbci	r17, 0xFF	; 255
-   1fd9e:	4c d0       	rcall	.+152    	; 0x1fe38 <__eerd_byte_m1280>
-   1fda0:	1b d0       	rcall	.+54     	; 0x1fdd8 <putch>
+	    putch(eeprom_read_byte((address.bptr++)));
+   1fdae:	9f 12       	cpse	r9, r31
+   1fdb0:	0b c0       	rjmp	.+22     	; 0x1fdc8 <main+0x1c8>
+   1fdb2:	ce 01       	movw	r24, r28
+   1fdb4:	48 d0       	rcall	.+144    	; 0x1fe46 <eeprom_read_byte>
 	} while (--length);
-   1fda2:	21 97       	sbiw	r28, 0x01	; 1
-   1fda4:	c9 f7       	brne	.-14     	; 0x1fd98 <main+0x198>
-   1fda6:	15 c0       	rjmp	.+42     	; 0x1fdd2 <main+0x1d2>
-   1fda8:	86 01       	movw	r16, r12
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+   1fdb6:	19 d0       	rcall	.+50     	; 0x1fdea <putch>
+   1fdb8:	81 e0       	ldi	r24, 0x01	; 1
+   1fdba:	a8 1a       	sub	r10, r24
+   1fdbc:	b1 08       	sbc	r11, r1
+   1fdbe:	21 96       	adiw	r28, 0x01	; 1
+   1fdc0:	a1 14       	cp	r10, r1
+   1fdc2:	b1 04       	cpc	r11, r1
+   1fdc4:	b1 f7       	brne	.-20     	; 0x1fdb2 <main+0x1b2>
+	    // Since RAMPZ should already be set, we need to use EPLM directly.
+	    // Also, we can use the autoincrement version of lpm to update "address"
+	    //      do putch(pgm_read_byte_near(address++));
+	    //      while (--length);
+	    // read a Flash and increment the address (may increment RAMPZ)
+	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+   1fdc6:	0e c0       	rjmp	.+28     	; 0x1fde4 <main+0x1e4>
+   1fdc8:	fe 01       	movw	r30, r28
+   1fdca:	87 91       	elpm	r24, Z+
 #else
 	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
 #endif
 	    putch(ch);
-   1fdaa:	f8 01       	movw	r30, r16
-   1fdac:	87 91       	elpm	r24, Z+
-   1fdae:	8f 01       	movw	r16, r30
-   1fdb0:	13 d0       	rcall	.+38     	; 0x1fdd8 <putch>
+   1fdcc:	ef 01       	movw	r28, r30
+   1fdce:	0d d0       	rcall	.+26     	; 0x1fdea <putch>
 	} while (--length);
-   1fdb2:	21 97       	sbiw	r28, 0x01	; 1
-   1fdb4:	d1 f7       	brne	.-12     	; 0x1fdaa <main+0x1aa>
-   1fdb6:	0d c0       	rjmp	.+26     	; 0x1fdd2 <main+0x1d2>
-	  
-      read_mem(desttype, address, length);
-    }
-
-    /* Get device signature bytes  */
-    else if(ch == STK_READ_SIGN) {
-   1fdb8:	85 37       	cpi	r24, 0x75	; 117
-   1fdba:	31 f4       	brne	.+12     	; 0x1fdc8 <main+0x1c8>
-      // READ SIGN - return what Avrdude wants to hear
+   1fdd0:	e1 e0       	ldi	r30, 0x01	; 1
+   1fdd2:	ae 1a       	sub	r10, r30
+   1fdd4:	b1 08       	sbc	r11, r1
+   1fdd6:	c1 f7       	brne	.-16     	; 0x1fdc8 <main+0x1c8>
+   1fdd8:	05 c0       	rjmp	.+10     	; 0x1fde4 <main+0x1e4>
       verifySpace();
-   1fdbc:	27 d0       	rcall	.+78     	; 0x1fe0c <verifySpace>
       putch(SIGNATURE_0);
-   1fdbe:	8e e1       	ldi	r24, 0x1E	; 30
-   1fdc0:	0b d0       	rcall	.+22     	; 0x1fdd8 <putch>
       putch(SIGNATURE_1);
-   1fdc2:	87 e9       	ldi	r24, 0x97	; 151
-   1fdc4:	09 d0       	rcall	.+18     	; 0x1fdd8 <putch>
-   1fdc6:	5b cf       	rjmp	.-330    	; 0x1fc7e <main+0x7e>
       putch(SIGNATURE_2);
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-   1fdc8:	81 35       	cpi	r24, 0x51	; 81
-   1fdca:	11 f4       	brne	.+4      	; 0x1fdd0 <main+0x1d0>
+   1fdda:	81 35       	cpi	r24, 0x51	; 81
+   1fddc:	11 f4       	brne	.+4      	; 0x1fde2 <main+0x1e2>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-   1fdcc:	88 e0       	ldi	r24, 0x08	; 8
-   1fdce:	18 d0       	rcall	.+48     	; 0x1fe00 <watchdogConfig>
+   1fdde:	88 e0       	ldi	r24, 0x08	; 8
+   1fde0:	17 d0       	rcall	.+46     	; 0x1fe10 <watchdogConfig>
+   1fde2:	1c d0       	rcall	.+56     	; 0x1fe1c <verifySpace>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-   1fdd0:	1d d0       	rcall	.+58     	; 0x1fe0c <verifySpace>
+   1fde4:	80 e1       	ldi	r24, 0x10	; 16
+   1fde6:	01 d0       	rcall	.+2      	; 0x1fdea <putch>
     }
     putch(STK_OK);
-   1fdd2:	80 e1       	ldi	r24, 0x10	; 16
-   1fdd4:	01 d0       	rcall	.+2      	; 0x1fdd8 <putch>
-   1fdd6:	45 cf       	rjmp	.-374    	; 0x1fc62 <main+0x62>
+   1fde8:	43 cf       	rjmp	.-378    	; 0x1fc70 <main+0x70>
 
-0001fdd8 <putch>:
+0001fdea <putch>:
+   1fdea:	90 91 c0 00 	lds	r25, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   }
+   1fdee:	95 ff       	sbrs	r25, 5
 }
 
 void putch(char ch) {
-   1fdd8:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-   1fdda:	80 91 c0 00 	lds	r24, 0x00C0
-   1fdde:	85 ff       	sbrs	r24, 5
-   1fde0:	fc cf       	rjmp	.-8      	; 0x1fdda <putch+0x2>
+   1fdf0:	fc cf       	rjmp	.-8      	; 0x1fdea <putch>
   UART_UDR = ch;
-   1fde2:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-   1fde6:	08 95       	ret
+   1fdf2:	80 93 c6 00 	sts	0x00C6, r24	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+   1fdf6:	08 95       	ret
 
-0001fde8 <getch>:
+0001fdf8 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-   1fde8:	80 91 c0 00 	lds	r24, 0x00C0
-   1fdec:	87 ff       	sbrs	r24, 7
-   1fdee:	fc cf       	rjmp	.-8      	; 0x1fde8 <getch>
+   1fdf8:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+   1fdfc:	87 ff       	sbrs	r24, 7
+   1fdfe:	fc cf       	rjmp	.-8      	; 0x1fdf8 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-   1fdf0:	80 91 c0 00 	lds	r24, 0x00C0
-   1fdf4:	84 fd       	sbrc	r24, 4
-   1fdf6:	01 c0       	rjmp	.+2      	; 0x1fdfa <getch+0x12>
+   1fe00:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+   1fe04:	84 fd       	sbrc	r24, 4
+   1fe06:	01 c0       	rjmp	.+2      	; 0x1fe0a <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-   1fdf8:	a8 95       	wdr
+   1fe08:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
-  
+
   ch = UART_UDR;
-   1fdfa:	80 91 c6 00 	lds	r24, 0x00C6
+   1fe0a:	80 91 c6 00 	lds	r24, 0x00C6	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-   1fdfe:	08 95       	ret
+   1fe0e:	08 95       	ret
 
-0001fe00 <watchdogConfig>:
+0001fe10 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-   1fe00:	e0 e6       	ldi	r30, 0x60	; 96
-   1fe02:	f0 e0       	ldi	r31, 0x00	; 0
-   1fe04:	98 e1       	ldi	r25, 0x18	; 24
-   1fe06:	90 83       	st	Z, r25
+   1fe10:	e0 e6       	ldi	r30, 0x60	; 96
+   1fe12:	f0 e0       	ldi	r31, 0x00	; 0
+   1fe14:	98 e1       	ldi	r25, 0x18	; 24
+   1fe16:	90 83       	st	Z, r25
   WDTCSR = x;
-   1fe08:	80 83       	st	Z, r24
-}
-   1fe0a:	08 95       	ret
+   1fe18:	80 83       	st	Z, r24
+   1fe1a:	08 95       	ret
 
-0001fe0c <verifySpace>:
+0001fe1c <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-   1fe0c:	ed df       	rcall	.-38     	; 0x1fde8 <getch>
-   1fe0e:	80 32       	cpi	r24, 0x20	; 32
-   1fe10:	19 f0       	breq	.+6      	; 0x1fe18 <verifySpace+0xc>
+   1fe1c:	ed df       	rcall	.-38     	; 0x1fdf8 <getch>
+   1fe1e:	80 32       	cpi	r24, 0x20	; 32
+   1fe20:	19 f0       	breq	.+6      	; 0x1fe28 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-   1fe12:	88 e0       	ldi	r24, 0x08	; 8
-   1fe14:	f5 df       	rcall	.-22     	; 0x1fe00 <watchdogConfig>
-   1fe16:	ff cf       	rjmp	.-2      	; 0x1fe16 <verifySpace+0xa>
+   1fe22:	88 e0       	ldi	r24, 0x08	; 8
+   1fe24:	f5 df       	rcall	.-22     	; 0x1fe10 <watchdogConfig>
+   1fe26:	ff cf       	rjmp	.-2      	; 0x1fe26 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-   1fe18:	84 e1       	ldi	r24, 0x14	; 20
-}
-   1fe1a:	de cf       	rjmp	.-68     	; 0x1fdd8 <putch>
+   1fe28:	84 e1       	ldi	r24, 0x14	; 20
+   1fe2a:	df cf       	rjmp	.-66     	; 0x1fdea <putch>
 
-0001fe1c <getNch>:
+0001fe2c <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-   1fe1c:	1f 93       	push	r17
-   1fe1e:	18 2f       	mov	r17, r24
+   1fe2c:	cf 93       	push	r28
+   1fe2e:	c8 2f       	mov	r28, r24
   do getch(); while (--count);
-   1fe20:	e3 df       	rcall	.-58     	; 0x1fde8 <getch>
-   1fe22:	11 50       	subi	r17, 0x01	; 1
-   1fe24:	e9 f7       	brne	.-6      	; 0x1fe20 <getNch+0x4>
+   1fe30:	e3 df       	rcall	.-58     	; 0x1fdf8 <getch>
+   1fe32:	c1 50       	subi	r28, 0x01	; 1
+   1fe34:	e9 f7       	brne	.-6      	; 0x1fe30 <getNch+0x4>
   verifySpace();
-   1fe26:	f2 df       	rcall	.-28     	; 0x1fe0c <verifySpace>
-}
-   1fe28:	1f 91       	pop	r17
-   1fe2a:	08 95       	ret
+   1fe36:	cf 91       	pop	r28
+   1fe38:	f1 cf       	rjmp	.-30     	; 0x1fe1c <verifySpace>
 
-0001fe2c <appStart>:
+0001fe3a <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-   1fe2c:	28 2e       	mov	r2, r24
+   1fe3a:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-   1fe2e:	80 e0       	ldi	r24, 0x00	; 0
-   1fe30:	e7 df       	rcall	.-50     	; 0x1fe00 <watchdogConfig>
+   1fe3c:	80 e0       	ldi	r24, 0x00	; 0
+   1fe3e:	e8 df       	rcall	.-48     	; 0x1fe10 <watchdogConfig>
+   1fe40:	e0 e0       	ldi	r30, 0x00	; 0
+  // Note that appstart_vec is defined so that this works with either
+  // real or virtual boot partitions.
   __asm__ __volatile__ (
-   1fe32:	ee 27       	eor	r30, r30
-   1fe34:	ff 27       	eor	r31, r31
-   1fe36:	09 94       	ijmp
-
-0001fe38 <__eerd_byte_m1280>:
-   1fe38:	f9 99       	sbic	0x1f, 1	; 31
-   1fe3a:	fe cf       	rjmp	.-4      	; 0x1fe38 <__eerd_byte_m1280>
-   1fe3c:	92 bd       	out	0x22, r25	; 34
-   1fe3e:	81 bd       	out	0x21, r24	; 33
-   1fe40:	f8 9a       	sbi	0x1f, 0	; 31
-   1fe42:	99 27       	eor	r25, r25
-   1fe44:	80 b5       	in	r24, 0x20	; 32
-   1fe46:	08 95       	ret
-
-0001fe48 <__eewr_byte_m1280>:
-   1fe48:	26 2f       	mov	r18, r22
-
-0001fe4a <__eewr_r18_m1280>:
-   1fe4a:	f9 99       	sbic	0x1f, 1	; 31
-   1fe4c:	fe cf       	rjmp	.-4      	; 0x1fe4a <__eewr_r18_m1280>
-   1fe4e:	1f ba       	out	0x1f, r1	; 31
-   1fe50:	92 bd       	out	0x22, r25	; 34
-   1fe52:	81 bd       	out	0x21, r24	; 33
-   1fe54:	20 bd       	out	0x20, r18	; 32
-   1fe56:	0f b6       	in	r0, 0x3f	; 63
-   1fe58:	f8 94       	cli
-   1fe5a:	fa 9a       	sbi	0x1f, 2	; 31
-   1fe5c:	f9 9a       	sbi	0x1f, 1	; 31
-   1fe5e:	0f be       	out	0x3f, r0	; 63
-   1fe60:	01 96       	adiw	r24, 0x01	; 1
-   1fe62:	08 95       	ret
+   1fe42:	ff 27       	eor	r31, r31
+   1fe44:	09 94       	ijmp
+
+0001fe46 <eeprom_read_byte>:
+   1fe46:	f9 99       	sbic	0x1f, 1	; 31
+   1fe48:	fe cf       	rjmp	.-4      	; 0x1fe46 <eeprom_read_byte>
+   1fe4a:	92 bd       	out	0x22, r25	; 34
+   1fe4c:	81 bd       	out	0x21, r24	; 33
+   1fe4e:	f8 9a       	sbi	0x1f, 0	; 31
+   1fe50:	99 27       	eor	r25, r25
+   1fe52:	80 b5       	in	r24, 0x20	; 32
+   1fe54:	08 95       	ret
+
+0001fe56 <eeprom_write_byte>:
+   1fe56:	26 2f       	mov	r18, r22
+
+0001fe58 <eeprom_write_r18>:
+   1fe58:	f9 99       	sbic	0x1f, 1	; 31
+   1fe5a:	fe cf       	rjmp	.-4      	; 0x1fe58 <eeprom_write_r18>
+   1fe5c:	1f ba       	out	0x1f, r1	; 31
+   1fe5e:	92 bd       	out	0x22, r25	; 34
+   1fe60:	81 bd       	out	0x21, r24	; 33
+   1fe62:	20 bd       	out	0x20, r18	; 32
+   1fe64:	0f b6       	in	r0, 0x3f	; 63
+   1fe66:	f8 94       	cli
+   1fe68:	fa 9a       	sbi	0x1f, 2	; 31
+   1fe6a:	f9 9a       	sbi	0x1f, 1	; 31
+   1fe6c:	0f be       	out	0x3f, r0	; 63
+   1fe6e:	01 96       	adiw	r24, 0x01	; 1
+   1fe70:	08 95       	ret

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

@@ -1,33 +1,31 @@
-:107E0000112494B714BE892F8D7011F0892FDED004
-:107E100085E08093810082E08093C00088E18093B8
-:107E2000C10086E08093C20080E18093C4008EE0B0
-:107E3000B7D0259A86E020E33CEF91E030938500AF
-:107E40002093840096BBB09BFECF1D9AA8958150CD
-:107E5000A9F7EE24FF24B3E0AB2EBB24B394A5E036
-:107E6000DA2EF1E1CF2E90D0813471F48DD0082F2D
-:107E70009DD0023811F482E005C0013811F486E08B
-:107E800001C083E079D075C0823411F484E103C06D
-:107E9000853419F485E092D06CC0853579F474D0BE
-:107EA000E82EFF2471D0082F10E0102F00270E2994
-:107EB0001F29000F111F7AD078015BC0863521F48D
-:107EC00084E07CD080E0DECF843609F035C05CD021
-:107ED0005BD0182F59D0082FC0E0D1E055D089933E
-:107EE0001C17E1F763D0053409F4FFCFF701A7BEF3
-:107EF000E89507B600FCFDCFA701A0E0B1E02C910A
-:107F000030E011968C91119790E0982F8827822B62
-:107F1000932B1296FA010C01B7BEE89511244E5F1F
-:107F20005F4F1A1761F7F701D7BEE89507B600FC57
-:107F3000FDCFC7BEE8951DC0843769F425D024D095
-:107F4000082F22D033D0E701FE018591EF0114D034
-:107F50000150D1F70EC0853739F428D08EE10CD00E
-:107F600085E90AD08FE08ECF813511F488E018D0F2
-:107F70001DD080E101D077CF982F8091C00085FF80
-:107F8000FCCF9093C60008958091C00087FFFCCF7E
-:107F90008091C00084FD01C0A8958091C60008951D
-:107FA000E0E6F0E098E1908380830895EDDF803291
-:107FB00019F088E0F5DFFFCF84E1DECF1F93182FA3
-:107FC000E3DF1150E9F7F2DF1F910895282E80E0DA
-:087FD000E7DFEE27FF2709940B
-:027FFE00020679
+:107E0000112484B7882349F0982F9A70923029F072
+:107E100081FF02C097EF94BFCCD085E080938100B2
+:107E200082E08093C00088E18093C10086E0809367
+:107E3000C20080E18093C4008EE0A6D0259A86E03F
+:107E400020E33CEF91E0309385002093840096BBC3
+:107E5000B09BFECF1D9AA8954091C00047FD02C07F
+:107E6000815089F7EE24E39495E0D92E21E1C22ECA
+:107E70007FD0813461F47CD0182F8CD01238E9F097
+:107E8000113811F487E001C083E06BD067C0823401
+:107E900011F484E103C0853419F485E083D05EC019
+:107EA000853539F465D0C82F63D0D82FCC0FDD1FAE
+:107EB00054C0863521F484E075D080E0E6CF843666
+:107EC00009F02EC055D054D0F82E52D0B82E00E074
+:107ED00011E04ED0F80181938F01FE12FACF5AD0F3
+:107EE000F5E4BF1201C0FFCF83E0FE0187BFE89534
+:107EF00007B600FCFDCFA0E0B1E0FE018D919D91A1
+:107F00000C01E7BEE89511243296FA12F7CFFE0174
+:107F1000D7BEE89507B600FCFDCFC7BEE8951EC0EA
+:107F2000843771F425D024D0F82E22D033D08E019E
+:107F3000F80185918F0115D0FA94F110F9CF0EC098
+:107F4000853739F427D08EE10CD085E90AD08FE04F
+:107F50009CCF813511F488E017D01CD080E101D08E
+:107F600087CF9091C00095FFFCCF8093C600089505
+:107F70008091C00087FFFCCF8091C00084FD01C0CC
+:107F8000A8958091C6000895E0E6F0E098E190831E
+:107F900080830895EDDF803219F088E0F5DFFFCFB0
+:107FA00084E1DFCFCF93C82FE3DFC150E9F7CF9152
+:0E7FB000F1CF282E80E0E8DFE0E0FF27099403
+:027FFE0000077A
 :0400000300007E007B
 :00000001FF

+ 312 - 316
optiboot/bootloaders/optiboot/optiboot_atmega328.lst

@@ -3,586 +3,582 @@ optiboot_atmega328.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001d8  00007e00  00007e00  00000074  2**1
+  0 .data         00000000  00800100  00007fbe  00000252  2**0
+                  CONTENTS, ALLOC, LOAD, DATA
+  1 .text         000001be  00007e00  00007e00  00000094  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00007ffe  00007ffe  0000024c  2**0
+  2 .version      00000002  00007ffe  00007ffe  00000252  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
+  3 .comment      0000002f  00000000  00000000  00000254  2**0
+                  CONTENTS, READONLY
+  4 .debug_aranges 00000028  00000000  00000000  00000283  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000276  2**0
+  5 .debug_info   000005c8  00000000  00000000  000002ab  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003ea  00000000  00000000  000002ea  2**0
+  6 .debug_abbrev 00000282  00000000  00000000  00000873  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001ef  00000000  00000000  000006d4  2**0
+  7 .debug_line   000002f9  00000000  00000000  00000af5  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000042b  00000000  00000000  000008c3  2**0
+  8 .debug_frame  0000008c  00000000  00000000  00000df0  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000cf0  2**2
+  9 .debug_str    000001fa  00000000  00000000  00000e7c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    0000017c  00000000  00000000  00000d70  2**0
+ 10 .debug_loc    00000331  00000000  00000000  00001076  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000300  00000000  00000000  00000eec  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011ec  2**0
+ 11 .debug_ranges 00000060  00000000  00000000  000013a7  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00007e00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
+  //  SP points to RAMEND
+  //  r1 contains zero
+  //
+  // If not, uncomment the following instructions:
+  // cli();
+  asm volatile ("clr __zero_reg__");
     7e00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
+   * 
+   * Code by MarkG55
+   * see discusion in https://github.com/Optiboot/optiboot/issues/97
    */
+#if !defined(__AVR_ATmega16__)
   ch = MCUSR;
-    7e02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-    7e04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-    7e06:	89 2f       	mov	r24, r25
-    7e08:	8d 70       	andi	r24, 0x0D	; 13
-    7e0a:	11 f0       	breq	.+4      	; 0x7e10 <main+0x10>
-      appStart(ch);
-    7e0c:	89 2f       	mov	r24, r25
-    7e0e:	de d0       	rcall	.+444    	; 0x7fcc <appStart>
+    7e02:	84 b7       	in	r24, 0x34	; 52
+#else
+  ch = MCUCSR;
+#endif
+  // Skip all logic and run bootloader if MCUSR is cleared (application request)
+  if (ch != 0) {
+    7e04:	88 23       	and	r24, r24
+    7e06:	49 f0       	breq	.+18     	; 0x7e1a <main+0x1a>
+       *  2. we clear WDRF if it's set with EXTRF to avoid loops
+       * One problematic scenario: broken application code sets watchdog timer 
+       * without clearing MCUSR before and triggers it quickly. But it's
+       * recoverable by power-on with pushed reset button.
+       */
+      if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) { 
+    7e08:	98 2f       	mov	r25, r24
+    7e0a:	9a 70       	andi	r25, 0x0A	; 10
+    7e0c:	92 30       	cpi	r25, 0x02	; 2
+    7e0e:	29 f0       	breq	.+10     	; 0x7e1a <main+0x1a>
+	  if (ch & _BV(EXTRF)) {
+    7e10:	81 ff       	sbrs	r24, 1
+    7e12:	02 c0       	rjmp	.+4      	; 0x7e18 <main+0x18>
+	       * prevent entering bootloader.
+	       * '&' operation is skipped to spare few bytes as bits in MCUSR
+	       * can only be cleared.
+	       */
+#if !defined(__AVR_ATmega16__)
+	      MCUSR = ~(_BV(WDRF));  
+    7e14:	97 ef       	ldi	r25, 0xF7	; 247
+    7e16:	94 bf       	out	0x34, r25	; 52
+#else
+	      MCUCSR = ~(_BV(WDRF));  
+#endif
+	  }
+	  appStart(ch);
+    7e18:	cc d0       	rcall	.+408    	; 0x7fb2 <appStart>
+      }
+  }
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
   TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    7e10:	85 e0       	ldi	r24, 0x05	; 5
-    7e12:	80 93 81 00 	sts	0x0081, r24
+    7e1a:	85 e0       	ldi	r24, 0x05	; 5
+    7e1c:	80 93 81 00 	sts	0x0081, r24	; 0x800081 <__TEXT_REGION_LENGTH__+0x7e0081>
   UCSRA = _BV(U2X); //Double speed mode USART
   UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
   UART_SRA = _BV(U2X0); //Double speed mode USART0
-    7e16:	82 e0       	ldi	r24, 0x02	; 2
-    7e18:	80 93 c0 00 	sts	0x00C0, r24
+    7e20:	82 e0       	ldi	r24, 0x02	; 2
+    7e22:	80 93 c0 00 	sts	0x00C0, r24	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-    7e1c:	88 e1       	ldi	r24, 0x18	; 24
-    7e1e:	80 93 c1 00 	sts	0x00C1, r24
+    7e26:	88 e1       	ldi	r24, 0x18	; 24
+    7e28:	80 93 c1 00 	sts	0x00C1, r24	; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7e00c1>
   UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-    7e22:	86 e0       	ldi	r24, 0x06	; 6
-    7e24:	80 93 c2 00 	sts	0x00C2, r24
+    7e2c:	86 e0       	ldi	r24, 0x06	; 6
+    7e2e:	80 93 c2 00 	sts	0x00C2, r24	; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7e00c2>
   UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-    7e28:	80 e1       	ldi	r24, 0x10	; 16
-    7e2a:	80 93 c4 00 	sts	0x00C4, r24
+    7e32:	80 e1       	ldi	r24, 0x10	; 16
+    7e34:	80 93 c4 00 	sts	0x00C4, r24	; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7e00c4>
 #endif
 #endif
 
-  // Set up watchdog to trigger after 500ms
+  // Set up watchdog to trigger after 1s
   watchdogConfig(WATCHDOG_1S);
-    7e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    7e30:	b7 d0       	rcall	.+366    	; 0x7fa0 <watchdogConfig>
+    7e38:	8e e0       	ldi	r24, 0x0E	; 14
+    7e3a:	a6 d0       	rcall	.+332    	; 0x7f88 <watchdogConfig>
 
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
-    7e32:	25 9a       	sbi	0x04, 5	; 4
-    7e34:	86 e0       	ldi	r24, 0x06	; 6
+    7e3c:	25 9a       	sbi	0x04, 5	; 4
+    7e3e:	86 e0       	ldi	r24, 0x06	; 6
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-    7e36:	20 e3       	ldi	r18, 0x30	; 48
-    7e38:	3c ef       	ldi	r19, 0xFC	; 252
+    7e40:	20 e3       	ldi	r18, 0x30	; 48
+    7e42:	3c ef       	ldi	r19, 0xFC	; 252
     TIFR1 = _BV(TOV1);
-    7e3a:	91 e0       	ldi	r25, 0x01	; 1
+    7e44:	91 e0       	ldi	r25, 0x01	; 1
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-    7e3c:	30 93 85 00 	sts	0x0085, r19
-    7e40:	20 93 84 00 	sts	0x0084, r18
+    7e46:	30 93 85 00 	sts	0x0085, r19	; 0x800085 <__TEXT_REGION_LENGTH__+0x7e0085>
+    7e4a:	20 93 84 00 	sts	0x0084, r18	; 0x800084 <__TEXT_REGION_LENGTH__+0x7e0084>
     TIFR1 = _BV(TOV1);
-    7e44:	96 bb       	out	0x16, r25	; 22
+    7e4e:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
-    7e46:	b0 9b       	sbis	0x16, 0	; 22
-    7e48:	fe cf       	rjmp	.-4      	; 0x7e46 <main+0x46>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
+    7e50:	b0 9b       	sbis	0x16, 0	; 22
+    7e52:	fe cf       	rjmp	.-4      	; 0x7e50 <main+0x50>
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
     LED_PORT ^= _BV(LED);
 #else
     LED_PIN |= _BV(LED);
-    7e4a:	1d 9a       	sbi	0x03, 5	; 3
+    7e54:	1d 9a       	sbi	0x03, 5	; 3
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    7e4c:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
+    7e56:	a8 95       	wdr
+     * While in theory, the STK500 initial commands would be buffered
+     *  by the UART hardware, avrdude sends several attempts in rather
+     *  quick succession, some of which will be lost and cause us to
+     *  get out of sync.  So if we see any data; stop blinking.
+     */
+    if (UART_SRA & _BV(RXC0))
+    7e58:	40 91 c0 00 	lds	r20, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    7e5c:	47 fd       	sbrc	r20, 7
+    7e5e:	02 c0       	rjmp	.+4      	; 0x7e64 <main+0x64>
+    7e60:	81 50       	subi	r24, 0x01	; 1
 #else
-    LED_PIN |= _BV(LED);
+// This doesn't seem to work?
+//    if ((UART_PIN & (1<<UART_RX_BIT)) == 0)
+//	break;  // detect start bit on soft uart too.
 #endif
-    watchdogReset();
   } while (--count);
-    7e4e:	81 50       	subi	r24, 0x01	; 1
-    7e50:	a9 f7       	brne	.-22     	; 0x7e3c <main+0x3c>
-    7e52:	ee 24       	eor	r14, r14
-    7e54:	ff 24       	eor	r15, r15
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    7e56:	b3 e0       	ldi	r27, 0x03	; 3
-    7e58:	ab 2e       	mov	r10, r27
+    7e62:	89 f7       	brne	.-30     	; 0x7e46 <main+0x46>
+
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7e5a:	bb 24       	eor	r11, r11
-    7e5c:	b3 94       	inc	r11
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    7e64:	ee 24       	eor	r14, r14
+    7e66:	e3 94       	inc	r14
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    7e5e:	a5 e0       	ldi	r26, 0x05	; 5
-    7e60:	da 2e       	mov	r13, r26
+	    __boot_page_write_short(address.word);
+    7e68:	95 e0       	ldi	r25, 0x05	; 5
+    7e6a:	d9 2e       	mov	r13, r25
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
-	    boot_rww_enable();
-    7e62:	f1 e1       	ldi	r31, 0x11	; 17
-    7e64:	cf 2e       	mov	r12, r31
+	    __boot_rww_enable_short();
+    7e6c:	21 e1       	ldi	r18, 0x11	; 17
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    7e66:	90 d0       	rcall	.+288    	; 0x7f88 <getch>
+    7e6e:	c2 2e       	mov	r12, r18
 
     if(ch == STK_GET_PARAMETER) {
-    7e68:	81 34       	cpi	r24, 0x41	; 65
-    7e6a:	71 f4       	brne	.+28     	; 0x7e88 <main+0x88>
+    7e70:	7f d0       	rcall	.+254    	; 0x7f70 <getch>
       unsigned char which = getch();
-    7e6c:	8d d0       	rcall	.+282    	; 0x7f88 <getch>
-    7e6e:	08 2f       	mov	r16, r24
+    7e72:	81 34       	cpi	r24, 0x41	; 65
+    7e74:	61 f4       	brne	.+24     	; 0x7e8e <main+0x8e>
+    7e76:	7c d0       	rcall	.+248    	; 0x7f70 <getch>
       verifySpace();
-    7e70:	9d d0       	rcall	.+314    	; 0x7fac <verifySpace>
+    7e78:	18 2f       	mov	r17, r24
+    7e7a:	8c d0       	rcall	.+280    	; 0x7f94 <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
-      if (which == 0x82) {
-    7e72:	02 38       	cpi	r16, 0x82	; 130
-    7e74:	11 f4       	brne	.+4      	; 0x7e7a <main+0x7a>
+      if (which == STK_SW_MINOR) {
+    7e7c:	12 38       	cpi	r17, 0x82	; 130
+    7e7e:	e9 f0       	breq	.+58     	; 0x7eba <main+0xba>
 	  putch(optiboot_version & 0xFF);
-    7e76:	82 e0       	ldi	r24, 0x02	; 2
-    7e78:	05 c0       	rjmp	.+10     	; 0x7e84 <main+0x84>
-      } else if (which == 0x81) {
-    7e7a:	01 38       	cpi	r16, 0x81	; 129
-    7e7c:	11 f4       	brne	.+4      	; 0x7e82 <main+0x82>
+      } else if (which == STK_SW_MAJOR) {
+    7e80:	11 38       	cpi	r17, 0x81	; 129
 	  putch(optiboot_version >> 8);
-    7e7e:	86 e0       	ldi	r24, 0x06	; 6
-    7e80:	01 c0       	rjmp	.+2      	; 0x7e84 <main+0x84>
+    7e82:	11 f4       	brne	.+4      	; 0x7e88 <main+0x88>
+    7e84:	87 e0       	ldi	r24, 0x07	; 7
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    7e82:	83 e0       	ldi	r24, 0x03	; 3
-    7e84:	79 d0       	rcall	.+242    	; 0x7f78 <putch>
-    7e86:	75 c0       	rjmp	.+234    	; 0x7f72 <main+0x172>
+    7e86:	01 c0       	rjmp	.+2      	; 0x7e8a <main+0x8a>
+    7e88:	83 e0       	ldi	r24, 0x03	; 3
+    7e8a:	6b d0       	rcall	.+214    	; 0x7f62 <putch>
+    7e8c:	67 c0       	rjmp	.+206    	; 0x7f5c <main+0x15c>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    7e88:	82 34       	cpi	r24, 0x42	; 66
-    7e8a:	11 f4       	brne	.+4      	; 0x7e90 <main+0x90>
+    7e8e:	82 34       	cpi	r24, 0x42	; 66
       // SET DEVICE is ignored
       getNch(20);
-    7e8c:	84 e1       	ldi	r24, 0x14	; 20
-    7e8e:	03 c0       	rjmp	.+6      	; 0x7e96 <main+0x96>
+    7e90:	11 f4       	brne	.+4      	; 0x7e96 <main+0x96>
+    7e92:	84 e1       	ldi	r24, 0x14	; 20
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    7e90:	85 34       	cpi	r24, 0x45	; 69
-    7e92:	19 f4       	brne	.+6      	; 0x7e9a <main+0x9a>
+    7e94:	03 c0       	rjmp	.+6      	; 0x7e9c <main+0x9c>
       // SET DEVICE EXT is ignored
       getNch(5);
-    7e94:	85 e0       	ldi	r24, 0x05	; 5
-    7e96:	92 d0       	rcall	.+292    	; 0x7fbc <getNch>
-    7e98:	6c c0       	rjmp	.+216    	; 0x7f72 <main+0x172>
+    7e96:	85 34       	cpi	r24, 0x45	; 69
+    7e98:	19 f4       	brne	.+6      	; 0x7ea0 <main+0xa0>
+    7e9a:	85 e0       	ldi	r24, 0x05	; 5
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    7e9a:	85 35       	cpi	r24, 0x55	; 85
-    7e9c:	79 f4       	brne	.+30     	; 0x7ebc <main+0xbc>
+    7e9c:	83 d0       	rcall	.+262    	; 0x7fa4 <getNch>
+    7e9e:	5e c0       	rjmp	.+188    	; 0x7f5c <main+0x15c>
       // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    7e9e:	74 d0       	rcall	.+232    	; 0x7f88 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    7ea0:	e8 2e       	mov	r14, r24
-    7ea2:	ff 24       	eor	r15, r15
-    7ea4:	71 d0       	rcall	.+226    	; 0x7f88 <getch>
-    7ea6:	08 2f       	mov	r16, r24
-    7ea8:	10 e0       	ldi	r17, 0x00	; 0
-    7eaa:	10 2f       	mov	r17, r16
-    7eac:	00 27       	eor	r16, r16
-    7eae:	0e 29       	or	r16, r14
-    7eb0:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
+      address.bytes[0] = getch();
+    7ea0:	85 35       	cpi	r24, 0x55	; 85
+    7ea2:	39 f4       	brne	.+14     	; 0x7eb2 <main+0xb2>
+    7ea4:	65 d0       	rcall	.+202    	; 0x7f70 <getch>
+      address.bytes[1] = getch();
+    7ea6:	c8 2f       	mov	r28, r24
+    7ea8:	63 d0       	rcall	.+198    	; 0x7f70 <getch>
+      }
+      else {
+        RAMPZ &= 0xFE;
+      }
 #endif
-      newAddress += newAddress; // Convert from word address to byte address
-    7eb2:	00 0f       	add	r16, r16
-    7eb4:	11 1f       	adc	r17, r17
-      address = newAddress;
+      address.word *= 2; // Convert from word address to byte address
+    7eaa:	d8 2f       	mov	r29, r24
+    7eac:	cc 0f       	add	r28, r28
+    7eae:	dd 1f       	adc	r29, r29
       verifySpace();
-    7eb6:	7a d0       	rcall	.+244    	; 0x7fac <verifySpace>
-    7eb8:	78 01       	movw	r14, r16
-    7eba:	5b c0       	rjmp	.+182    	; 0x7f72 <main+0x172>
     }
     else if(ch == STK_UNIVERSAL) {
-    7ebc:	86 35       	cpi	r24, 0x56	; 86
-    7ebe:	21 f4       	brne	.+8      	; 0x7ec8 <main+0xc8>
+    7eb0:	54 c0       	rjmp	.+168    	; 0x7f5a <main+0x15a>
+        getNch(3);
+        putch(0x00);
+      }
+#else
       // UNIVERSAL command is ignored
       getNch(4);
-    7ec0:	84 e0       	ldi	r24, 0x04	; 4
-    7ec2:	7c d0       	rcall	.+248    	; 0x7fbc <getNch>
+    7eb2:	86 35       	cpi	r24, 0x56	; 86
+    7eb4:	21 f4       	brne	.+8      	; 0x7ebe <main+0xbe>
       putch(0x00);
-    7ec4:	80 e0       	ldi	r24, 0x00	; 0
-    7ec6:	de cf       	rjmp	.-68     	; 0x7e84 <main+0x84>
+    7eb6:	84 e0       	ldi	r24, 0x04	; 4
+    7eb8:	75 d0       	rcall	.+234    	; 0x7fa4 <getNch>
+#endif
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    7ec8:	84 36       	cpi	r24, 0x64	; 100
-    7eca:	09 f0       	breq	.+2      	; 0x7ece <main+0xce>
-    7ecc:	35 c0       	rjmp	.+106    	; 0x7f38 <main+0x138>
+    7eba:	80 e0       	ldi	r24, 0x00	; 0
+    7ebc:	e6 cf       	rjmp	.-52     	; 0x7e8a <main+0x8a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
       pagelen_t savelength;
 
       GETLENGTH(length);
-    7ece:	5c d0       	rcall	.+184    	; 0x7f88 <getch>
-    7ed0:	5b d0       	rcall	.+182    	; 0x7f88 <getch>
-    7ed2:	18 2f       	mov	r17, r24
+    7ebe:	84 36       	cpi	r24, 0x64	; 100
+    7ec0:	09 f0       	breq	.+2      	; 0x7ec4 <main+0xc4>
+    7ec2:	2e c0       	rjmp	.+92     	; 0x7f20 <main+0x120>
+    7ec4:	55 d0       	rcall	.+170    	; 0x7f70 <getch>
       savelength = length;
       desttype = getch();
-    7ed4:	59 d0       	rcall	.+178    	; 0x7f88 <getch>
-    7ed6:	08 2f       	mov	r16, r24
-    7ed8:	c0 e0       	ldi	r28, 0x00	; 0
-    7eda:	d1 e0       	ldi	r29, 0x01	; 1
+    7ec6:	54 d0       	rcall	.+168    	; 0x7f70 <getch>
+    7ec8:	f8 2e       	mov	r15, r24
+    7eca:	52 d0       	rcall	.+164    	; 0x7f70 <getch>
+    7ecc:	b8 2e       	mov	r11, r24
+    7ece:	00 e0       	ldi	r16, 0x00	; 0
 
       // read a page worth of contents
-      bufPtr = buff;
+      bufPtr = buff.bptr;
       do *bufPtr++ = getch();
-    7edc:	55 d0       	rcall	.+170    	; 0x7f88 <getch>
-    7ede:	89 93       	st	Y+, r24
+    7ed0:	11 e0       	ldi	r17, 0x01	; 1
+    7ed2:	4e d0       	rcall	.+156    	; 0x7f70 <getch>
+    7ed4:	f8 01       	movw	r30, r16
+    7ed6:	81 93       	st	Z+, r24
+    7ed8:	8f 01       	movw	r16, r30
       while (--length);
-    7ee0:	1c 17       	cp	r17, r28
-    7ee2:	e1 f7       	brne	.-8      	; 0x7edc <main+0xdc>
+    7eda:	fe 12       	cpse	r15, r30
+    7edc:	fa cf       	rjmp	.-12     	; 0x7ed2 <main+0xd2>
 
       // Read command terminator, start reply
       verifySpace();
-    7ee4:	63 d0       	rcall	.+198    	; 0x7fac <verifySpace>
+    7ede:	5a d0       	rcall	.+180    	; 0x7f94 <verifySpace>
+    7ee0:	f5 e4       	ldi	r31, 0x45	; 69
  * void writebuffer(memtype, buffer, address, length)
  */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+			       addr16_t address, pagelen_t len)
 {
     switch (memtype) {
-    7ee6:	05 34       	cpi	r16, 0x45	; 69
-    7ee8:	09 f4       	brne	.+2      	; 0x7eec <main+0xec>
-    7eea:	ff cf       	rjmp	.-2      	; 0x7eea <main+0xea>
+    7ee2:	bf 12       	cpse	r11, r31
+    7ee4:	01 c0       	rjmp	.+2      	; 0x7ee8 <main+0xe8>
+    7ee6:	ff cf       	rjmp	.-2      	; 0x7ee6 <main+0xe6>
+    7ee8:	83 e0       	ldi	r24, 0x03	; 3
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    7eec:	f7 01       	movw	r30, r14
-    7eee:	a7 be       	out	0x37, r10	; 55
-    7ef0:	e8 95       	spm
+	    __boot_page_erase_short(address.word);
+    7eea:	fe 01       	movw	r30, r28
+    7eec:	87 bf       	out	0x37, r24	; 55
+    7eee:	e8 95       	spm
+    7ef0:	07 b6       	in	r0, 0x37	; 55
 	    boot_spm_busy_wait();
-    7ef2:	07 b6       	in	r0, 0x37	; 55
-    7ef4:	00 fc       	sbrc	r0, 0
-    7ef6:	fd cf       	rjmp	.-6      	; 0x7ef2 <main+0xf2>
-    7ef8:	a7 01       	movw	r20, r14
-    7efa:	a0 e0       	ldi	r26, 0x00	; 0
-    7efc:	b1 e0       	ldi	r27, 0x01	; 1
+    7ef2:	00 fc       	sbrc	r0, 0
+    7ef4:	fd cf       	rjmp	.-6      	; 0x7ef0 <main+0xf0>
+    7ef6:	a0 e0       	ldi	r26, 0x00	; 0
+    7ef8:	b1 e0       	ldi	r27, 0x01	; 1
+    7efa:	fe 01       	movw	r30, r28
+    7efc:	8d 91       	ld	r24, X+
+
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-    7efe:	2c 91       	ld	r18, X
-    7f00:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-    7f02:	11 96       	adiw	r26, 0x01	; 1
-    7f04:	8c 91       	ld	r24, X
-    7f06:	11 97       	sbiw	r26, 0x01	; 1
-    7f08:	90 e0       	ldi	r25, 0x00	; 0
-    7f0a:	98 2f       	mov	r25, r24
-    7f0c:	88 27       	eor	r24, r24
-    7f0e:	82 2b       	or	r24, r18
-    7f10:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    7f12:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7f14:	fa 01       	movw	r30, r20
-    7f16:	0c 01       	movw	r0, r24
-    7f18:	b7 be       	out	0x37, r11	; 55
-    7f1a:	e8 95       	spm
-    7f1c:	11 24       	eor	r1, r1
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    7efe:	9d 91       	ld	r25, X+
+    7f00:	0c 01       	movw	r0, r24
+    7f02:	e7 be       	out	0x37, r14	; 55
+    7f04:	e8 95       	spm
+    7f06:	11 24       	eor	r1, r1
+    7f08:	32 96       	adiw	r30, 0x02	; 2
 		addrPtr += 2;
-    7f1e:	4e 5f       	subi	r20, 0xFE	; 254
-    7f20:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    7f22:	1a 17       	cp	r17, r26
-    7f24:	61 f7       	brne	.-40     	; 0x7efe <main+0xfe>
+    7f0a:	fa 12       	cpse	r15, r26
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    7f26:	f7 01       	movw	r30, r14
-    7f28:	d7 be       	out	0x37, r13	; 55
-    7f2a:	e8 95       	spm
+	    __boot_page_write_short(address.word);
+    7f0c:	f7 cf       	rjmp	.-18     	; 0x7efc <main+0xfc>
+    7f0e:	fe 01       	movw	r30, r28
 	    boot_spm_busy_wait();
-    7f2c:	07 b6       	in	r0, 0x37	; 55
-    7f2e:	00 fc       	sbrc	r0, 0
-    7f30:	fd cf       	rjmp	.-6      	; 0x7f2c <main+0x12c>
+    7f10:	d7 be       	out	0x37, r13	; 55
+    7f12:	e8 95       	spm
 #if defined(RWWSRE)
 	    // Reenable read access to flash
-	    boot_rww_enable();
-    7f32:	c7 be       	out	0x37, r12	; 55
-    7f34:	e8 95       	spm
-    7f36:	1d c0       	rjmp	.+58     	; 0x7f72 <main+0x172>
+	    __boot_rww_enable_short();
+    7f14:	07 b6       	in	r0, 0x37	; 55
+    7f16:	00 fc       	sbrc	r0, 0
+    7f18:	fd cf       	rjmp	.-6      	; 0x7f14 <main+0x114>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    7f38:	84 37       	cpi	r24, 0x74	; 116
-    7f3a:	69 f4       	brne	.+26     	; 0x7f56 <main+0x156>
+    7f1a:	c7 be       	out	0x37, r12	; 55
+    7f1c:	e8 95       	spm
       uint8_t desttype;
       GETLENGTH(length);
-    7f3c:	25 d0       	rcall	.+74     	; 0x7f88 <getch>
-    7f3e:	24 d0       	rcall	.+72     	; 0x7f88 <getch>
-    7f40:	08 2f       	mov	r16, r24
+    7f1e:	1e c0       	rjmp	.+60     	; 0x7f5c <main+0x15c>
+    7f20:	84 37       	cpi	r24, 0x74	; 116
+    7f22:	71 f4       	brne	.+28     	; 0x7f40 <main+0x140>
 
       desttype = getch();
-    7f42:	22 d0       	rcall	.+68     	; 0x7f88 <getch>
+    7f24:	25 d0       	rcall	.+74     	; 0x7f70 <getch>
 
       verifySpace();
-    7f44:	33 d0       	rcall	.+102    	; 0x7fac <verifySpace>
-    7f46:	e7 01       	movw	r28, r14
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+    7f26:	24 d0       	rcall	.+72     	; 0x7f70 <getch>
+    7f28:	f8 2e       	mov	r15, r24
+    7f2a:	22 d0       	rcall	.+68     	; 0x7f70 <getch>
+	    //      while (--length);
+	    // read a Flash and increment the address (may increment RAMPZ)
+	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
 #else
 	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+    7f2c:	33 d0       	rcall	.+102    	; 0x7f94 <verifySpace>
+    7f2e:	8e 01       	movw	r16, r28
 #endif
 	    putch(ch);
-    7f48:	fe 01       	movw	r30, r28
-    7f4a:	85 91       	lpm	r24, Z+
-    7f4c:	ef 01       	movw	r28, r30
-    7f4e:	14 d0       	rcall	.+40     	; 0x7f78 <putch>
+    7f30:	f8 01       	movw	r30, r16
 	} while (--length);
-    7f50:	01 50       	subi	r16, 0x01	; 1
-    7f52:	d1 f7       	brne	.-12     	; 0x7f48 <main+0x148>
-    7f54:	0e c0       	rjmp	.+28     	; 0x7f72 <main+0x172>
-	  
+    7f32:	85 91       	lpm	r24, Z+
+    7f34:	8f 01       	movw	r16, r30
+    7f36:	15 d0       	rcall	.+42     	; 0x7f62 <putch>
+    7f38:	fa 94       	dec	r15
+
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    7f56:	85 37       	cpi	r24, 0x75	; 117
-    7f58:	39 f4       	brne	.+14     	; 0x7f68 <main+0x168>
+    7f3a:	f1 10       	cpse	r15, r1
+    7f3c:	f9 cf       	rjmp	.-14     	; 0x7f30 <main+0x130>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    7f5a:	28 d0       	rcall	.+80     	; 0x7fac <verifySpace>
+    7f3e:	0e c0       	rjmp	.+28     	; 0x7f5c <main+0x15c>
+    7f40:	85 37       	cpi	r24, 0x75	; 117
       putch(SIGNATURE_0);
-    7f5c:	8e e1       	ldi	r24, 0x1E	; 30
-    7f5e:	0c d0       	rcall	.+24     	; 0x7f78 <putch>
+    7f42:	39 f4       	brne	.+14     	; 0x7f52 <main+0x152>
+    7f44:	27 d0       	rcall	.+78     	; 0x7f94 <verifySpace>
+    7f46:	8e e1       	ldi	r24, 0x1E	; 30
       putch(SIGNATURE_1);
-    7f60:	85 e9       	ldi	r24, 0x95	; 149
-    7f62:	0a d0       	rcall	.+20     	; 0x7f78 <putch>
+    7f48:	0c d0       	rcall	.+24     	; 0x7f62 <putch>
+    7f4a:	85 e9       	ldi	r24, 0x95	; 149
+    7f4c:	0a d0       	rcall	.+20     	; 0x7f62 <putch>
       putch(SIGNATURE_2);
-    7f64:	8f e0       	ldi	r24, 0x0F	; 15
-    7f66:	8e cf       	rjmp	.-228    	; 0x7e84 <main+0x84>
+    7f4e:	8f e0       	ldi	r24, 0x0F	; 15
+    7f50:	9c cf       	rjmp	.-200    	; 0x7e8a <main+0x8a>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    7f68:	81 35       	cpi	r24, 0x51	; 81
-    7f6a:	11 f4       	brne	.+4      	; 0x7f70 <main+0x170>
+    7f52:	81 35       	cpi	r24, 0x51	; 81
+    7f54:	11 f4       	brne	.+4      	; 0x7f5a <main+0x15a>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    7f6c:	88 e0       	ldi	r24, 0x08	; 8
-    7f6e:	18 d0       	rcall	.+48     	; 0x7fa0 <watchdogConfig>
+    7f56:	88 e0       	ldi	r24, 0x08	; 8
+    7f58:	17 d0       	rcall	.+46     	; 0x7f88 <watchdogConfig>
+    7f5a:	1c d0       	rcall	.+56     	; 0x7f94 <verifySpace>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    7f70:	1d d0       	rcall	.+58     	; 0x7fac <verifySpace>
+    7f5c:	80 e1       	ldi	r24, 0x10	; 16
+    7f5e:	01 d0       	rcall	.+2      	; 0x7f62 <putch>
     }
     putch(STK_OK);
-    7f72:	80 e1       	ldi	r24, 0x10	; 16
-    7f74:	01 d0       	rcall	.+2      	; 0x7f78 <putch>
-    7f76:	77 cf       	rjmp	.-274    	; 0x7e66 <main+0x66>
+    7f60:	87 cf       	rjmp	.-242    	; 0x7e70 <main+0x70>
 
-00007f78 <putch>:
+00007f62 <putch>:
+    7f62:	90 91 c0 00 	lds	r25, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   }
+    7f66:	95 ff       	sbrs	r25, 5
 }
 
 void putch(char ch) {
-    7f78:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    7f7a:	80 91 c0 00 	lds	r24, 0x00C0
-    7f7e:	85 ff       	sbrs	r24, 5
-    7f80:	fc cf       	rjmp	.-8      	; 0x7f7a <putch+0x2>
+    7f68:	fc cf       	rjmp	.-8      	; 0x7f62 <putch>
   UART_UDR = ch;
-    7f82:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-    7f86:	08 95       	ret
+    7f6a:	80 93 c6 00 	sts	0x00C6, r24	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+    7f6e:	08 95       	ret
 
-00007f88 <getch>:
+00007f70 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    7f88:	80 91 c0 00 	lds	r24, 0x00C0
-    7f8c:	87 ff       	sbrs	r24, 7
-    7f8e:	fc cf       	rjmp	.-8      	; 0x7f88 <getch>
+    7f70:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    7f74:	87 ff       	sbrs	r24, 7
+    7f76:	fc cf       	rjmp	.-8      	; 0x7f70 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    7f90:	80 91 c0 00 	lds	r24, 0x00C0
-    7f94:	84 fd       	sbrc	r24, 4
-    7f96:	01 c0       	rjmp	.+2      	; 0x7f9a <getch+0x12>
+    7f78:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    7f7c:	84 fd       	sbrc	r24, 4
+    7f7e:	01 c0       	rjmp	.+2      	; 0x7f82 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    7f98:	a8 95       	wdr
+    7f80:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
-  
+
   ch = UART_UDR;
-    7f9a:	80 91 c6 00 	lds	r24, 0x00C6
+    7f82:	80 91 c6 00 	lds	r24, 0x00C6	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    7f9e:	08 95       	ret
+    7f86:	08 95       	ret
 
-00007fa0 <watchdogConfig>:
+00007f88 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7fa0:	e0 e6       	ldi	r30, 0x60	; 96
-    7fa2:	f0 e0       	ldi	r31, 0x00	; 0
-    7fa4:	98 e1       	ldi	r25, 0x18	; 24
-    7fa6:	90 83       	st	Z, r25
+    7f88:	e0 e6       	ldi	r30, 0x60	; 96
+    7f8a:	f0 e0       	ldi	r31, 0x00	; 0
+    7f8c:	98 e1       	ldi	r25, 0x18	; 24
+    7f8e:	90 83       	st	Z, r25
   WDTCSR = x;
-    7fa8:	80 83       	st	Z, r24
-}
-    7faa:	08 95       	ret
+    7f90:	80 83       	st	Z, r24
+    7f92:	08 95       	ret
 
-00007fac <verifySpace>:
+00007f94 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    7fac:	ed df       	rcall	.-38     	; 0x7f88 <getch>
-    7fae:	80 32       	cpi	r24, 0x20	; 32
-    7fb0:	19 f0       	breq	.+6      	; 0x7fb8 <verifySpace+0xc>
+    7f94:	ed df       	rcall	.-38     	; 0x7f70 <getch>
+    7f96:	80 32       	cpi	r24, 0x20	; 32
+    7f98:	19 f0       	breq	.+6      	; 0x7fa0 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    7fb2:	88 e0       	ldi	r24, 0x08	; 8
-    7fb4:	f5 df       	rcall	.-22     	; 0x7fa0 <watchdogConfig>
-    7fb6:	ff cf       	rjmp	.-2      	; 0x7fb6 <verifySpace+0xa>
+    7f9a:	88 e0       	ldi	r24, 0x08	; 8
+    7f9c:	f5 df       	rcall	.-22     	; 0x7f88 <watchdogConfig>
+    7f9e:	ff cf       	rjmp	.-2      	; 0x7f9e <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    7fb8:	84 e1       	ldi	r24, 0x14	; 20
-}
-    7fba:	de cf       	rjmp	.-68     	; 0x7f78 <putch>
+    7fa0:	84 e1       	ldi	r24, 0x14	; 20
+    7fa2:	df cf       	rjmp	.-66     	; 0x7f62 <putch>
 
-00007fbc <getNch>:
+00007fa4 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    7fbc:	1f 93       	push	r17
-    7fbe:	18 2f       	mov	r17, r24
+    7fa4:	cf 93       	push	r28
+    7fa6:	c8 2f       	mov	r28, r24
   do getch(); while (--count);
-    7fc0:	e3 df       	rcall	.-58     	; 0x7f88 <getch>
-    7fc2:	11 50       	subi	r17, 0x01	; 1
-    7fc4:	e9 f7       	brne	.-6      	; 0x7fc0 <getNch+0x4>
+    7fa8:	e3 df       	rcall	.-58     	; 0x7f70 <getch>
+    7faa:	c1 50       	subi	r28, 0x01	; 1
+    7fac:	e9 f7       	brne	.-6      	; 0x7fa8 <getNch+0x4>
   verifySpace();
-    7fc6:	f2 df       	rcall	.-28     	; 0x7fac <verifySpace>
-}
-    7fc8:	1f 91       	pop	r17
-    7fca:	08 95       	ret
+    7fae:	cf 91       	pop	r28
+    7fb0:	f1 cf       	rjmp	.-30     	; 0x7f94 <verifySpace>
 
-00007fcc <appStart>:
+00007fb2 <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    7fcc:	28 2e       	mov	r2, r24
+    7fb2:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    7fce:	80 e0       	ldi	r24, 0x00	; 0
-    7fd0:	e7 df       	rcall	.-50     	; 0x7fa0 <watchdogConfig>
+    7fb4:	80 e0       	ldi	r24, 0x00	; 0
+    7fb6:	e8 df       	rcall	.-48     	; 0x7f88 <watchdogConfig>
+    7fb8:	e0 e0       	ldi	r30, 0x00	; 0
+  // Note that appstart_vec is defined so that this works with either
+  // real or virtual boot partitions.
   __asm__ __volatile__ (
-    7fd2:	ee 27       	eor	r30, r30
-    7fd4:	ff 27       	eor	r31, r31
-    7fd6:	09 94       	ijmp
+    7fba:	ff 27       	eor	r31, r31
+    7fbc:	09 94       	ijmp

+ 0 - 33
optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.hex

@@ -1,33 +0,0 @@
-:107E0000112494B714BE892F8D7011F0892FDED004
-:107E100085E08093810082E08093C00088E18093B8
-:107E2000C10086E08093C20088E08093C4008EE0A9
-:107E3000B7D0259A86E028E13EEF91E030938500A7
-:107E40002093840096BBB09BFECF1D9AA8958150CD
-:107E5000A9F7EE24FF24B3E0AB2EBB24B394A5E036
-:107E6000DA2EF1E1CF2E90D0813471F48DD0082F2D
-:107E70009DD0023811F482E005C0013811F486E08B
-:107E800001C083E079D075C0823411F484E103C06D
-:107E9000853419F485E092D06CC0853579F474D0BE
-:107EA000E82EFF2471D0082F10E0102F00270E2994
-:107EB0001F29000F111F7AD078015BC0863521F48D
-:107EC00084E07CD080E0DECF843609F035C05CD021
-:107ED0005BD0182F59D0082FC0E0D1E055D089933E
-:107EE0001C17E1F763D0053409F4FFCFF701A7BEF3
-:107EF000E89507B600FCFDCFA701A0E0B1E02C910A
-:107F000030E011968C91119790E0982F8827822B62
-:107F1000932B1296FA010C01B7BEE89511244E5F1F
-:107F20005F4F1A1761F7F701D7BEE89507B600FC57
-:107F3000FDCFC7BEE8951DC0843769F425D024D095
-:107F4000082F22D033D0E701FE018591EF0114D034
-:107F50000150D1F70EC0853739F428D08EE10CD00E
-:107F600085E90AD08FE08ECF813511F488E018D0F2
-:107F70001DD080E101D077CF982F8091C00085FF80
-:107F8000FCCF9093C60008958091C00087FFFCCF7E
-:107F90008091C00084FD01C0A8958091C60008951D
-:107FA000E0E6F0E098E1908380830895EDDF803291
-:107FB00019F088E0F5DFFFCF84E1DECF1F93182FA3
-:107FC000E3DF1150E9F7F2DF1F910895282E80E0DA
-:087FD000E7DFEE27FF2709940B
-:027FFE00020679
-:0400000300007E007B
-:00000001FF

+ 0 - 588
optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst

@@ -1,588 +0,0 @@
-
-optiboot_atmega328.elf:     file format elf32-avr
-
-Sections:
-Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001d8  00007e00  00007e00  00000074  2**1
-                  CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00007ffe  00007ffe  0000024c  2**0
-                  CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000024e  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000276  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003ea  00000000  00000000  000002ea  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001ef  00000000  00000000  000006d4  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000042b  00000000  00000000  000008c3  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000cf0  2**2
-                  CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    0000017c  00000000  00000000  00000d70  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000300  00000000  00000000  00000eec  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011ec  2**0
-                  CONTENTS, READONLY, DEBUGGING
-
-Disassembly of section .text:
-
-00007e00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    7e00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
-   */
-  ch = MCUSR;
-    7e02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-    7e04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-    7e06:	89 2f       	mov	r24, r25
-    7e08:	8d 70       	andi	r24, 0x0D	; 13
-    7e0a:	11 f0       	breq	.+4      	; 0x7e10 <main+0x10>
-      appStart(ch);
-    7e0c:	89 2f       	mov	r24, r25
-    7e0e:	de d0       	rcall	.+444    	; 0x7fcc <appStart>
-
-#if LED_START_FLASHES > 0
-  // Set up Timer 1 for timeout counter
-  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    7e10:	85 e0       	ldi	r24, 0x05	; 5
-    7e12:	80 93 81 00 	sts	0x0081, r24
-  UCSRA = _BV(U2X); //Double speed mode USART
-  UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
-  UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
-  UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-#else
-  UART_SRA = _BV(U2X0); //Double speed mode USART0
-    7e16:	82 e0       	ldi	r24, 0x02	; 2
-    7e18:	80 93 c0 00 	sts	0x00C0, r24
-  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-    7e1c:	88 e1       	ldi	r24, 0x18	; 24
-    7e1e:	80 93 c1 00 	sts	0x00C1, r24
-  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-    7e22:	86 e0       	ldi	r24, 0x06	; 6
-    7e24:	80 93 c2 00 	sts	0x00C2, r24
-  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-    7e28:	88 e0       	ldi	r24, 0x08	; 8
-    7e2a:	80 93 c4 00 	sts	0x00C4, r24
-#endif
-#endif
-
-  // Set up watchdog to trigger after 500ms
-  watchdogConfig(WATCHDOG_1S);
-    7e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    7e30:	b7 d0       	rcall	.+366    	; 0x7fa0 <watchdogConfig>
-
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
-  /* Set LED pin as output */
-  LED_DDR |= _BV(LED);
-    7e32:	25 9a       	sbi	0x04, 5	; 4
-    7e34:	86 e0       	ldi	r24, 0x06	; 6
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    7e36:	28 e1       	ldi	r18, 0x18	; 24
-    7e38:	3e ef       	ldi	r19, 0xFE	; 254
-    TIFR1 = _BV(TOV1);
-    7e3a:	91 e0       	ldi	r25, 0x01	; 1
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    7e3c:	30 93 85 00 	sts	0x0085, r19
-    7e40:	20 93 84 00 	sts	0x0084, r18
-    TIFR1 = _BV(TOV1);
-    7e44:	96 bb       	out	0x16, r25	; 22
-    while(!(TIFR1 & _BV(TOV1)));
-    7e46:	b0 9b       	sbis	0x16, 0	; 22
-    7e48:	fe cf       	rjmp	.-4      	; 0x7e46 <main+0x46>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-    7e4a:	1d 9a       	sbi	0x03, 5	; 3
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    7e4c:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-#endif
-    watchdogReset();
-  } while (--count);
-    7e4e:	81 50       	subi	r24, 0x01	; 1
-    7e50:	a9 f7       	brne	.-22     	; 0x7e3c <main+0x3c>
-    7e52:	ee 24       	eor	r14, r14
-    7e54:	ff 24       	eor	r15, r15
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    7e56:	b3 e0       	ldi	r27, 0x03	; 3
-    7e58:	ab 2e       	mov	r10, r27
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7e5a:	bb 24       	eor	r11, r11
-    7e5c:	b3 94       	inc	r11
-	    } while (len -= 2);
-
-	    /*
-	     * Actually Write the buffer to flash (and wait for it to finish.)
-	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    7e5e:	a5 e0       	ldi	r26, 0x05	; 5
-    7e60:	da 2e       	mov	r13, r26
-	    boot_spm_busy_wait();
-#if defined(RWWSRE)
-	    // Reenable read access to flash
-	    boot_rww_enable();
-    7e62:	f1 e1       	ldi	r31, 0x11	; 17
-    7e64:	cf 2e       	mov	r12, r31
-#endif
-
-  /* Forever loop: exits by causing WDT reset */
-  for (;;) {
-    /* get character from UART */
-    ch = getch();
-    7e66:	90 d0       	rcall	.+288    	; 0x7f88 <getch>
-
-    if(ch == STK_GET_PARAMETER) {
-    7e68:	81 34       	cpi	r24, 0x41	; 65
-    7e6a:	71 f4       	brne	.+28     	; 0x7e88 <main+0x88>
-      unsigned char which = getch();
-    7e6c:	8d d0       	rcall	.+282    	; 0x7f88 <getch>
-    7e6e:	08 2f       	mov	r16, r24
-      verifySpace();
-    7e70:	9d d0       	rcall	.+314    	; 0x7fac <verifySpace>
-      /*
-       * Send optiboot version as "SW version"
-       * Note that the references to memory are optimized away.
-       */
-      if (which == 0x82) {
-    7e72:	02 38       	cpi	r16, 0x82	; 130
-    7e74:	11 f4       	brne	.+4      	; 0x7e7a <main+0x7a>
-	  putch(optiboot_version & 0xFF);
-    7e76:	82 e0       	ldi	r24, 0x02	; 2
-    7e78:	05 c0       	rjmp	.+10     	; 0x7e84 <main+0x84>
-      } else if (which == 0x81) {
-    7e7a:	01 38       	cpi	r16, 0x81	; 129
-    7e7c:	11 f4       	brne	.+4      	; 0x7e82 <main+0x82>
-	  putch(optiboot_version >> 8);
-    7e7e:	86 e0       	ldi	r24, 0x06	; 6
-    7e80:	01 c0       	rjmp	.+2      	; 0x7e84 <main+0x84>
-      } else {
-	/*
-	 * GET PARAMETER returns a generic 0x03 reply for
-         * other parameters - enough to keep Avrdude happy
-	 */
-	putch(0x03);
-    7e82:	83 e0       	ldi	r24, 0x03	; 3
-    7e84:	79 d0       	rcall	.+242    	; 0x7f78 <putch>
-    7e86:	75 c0       	rjmp	.+234    	; 0x7f72 <main+0x172>
-      }
-    }
-    else if(ch == STK_SET_DEVICE) {
-    7e88:	82 34       	cpi	r24, 0x42	; 66
-    7e8a:	11 f4       	brne	.+4      	; 0x7e90 <main+0x90>
-      // SET DEVICE is ignored
-      getNch(20);
-    7e8c:	84 e1       	ldi	r24, 0x14	; 20
-    7e8e:	03 c0       	rjmp	.+6      	; 0x7e96 <main+0x96>
-    }
-    else if(ch == STK_SET_DEVICE_EXT) {
-    7e90:	85 34       	cpi	r24, 0x45	; 69
-    7e92:	19 f4       	brne	.+6      	; 0x7e9a <main+0x9a>
-      // SET DEVICE EXT is ignored
-      getNch(5);
-    7e94:	85 e0       	ldi	r24, 0x05	; 5
-    7e96:	92 d0       	rcall	.+292    	; 0x7fbc <getNch>
-    7e98:	6c c0       	rjmp	.+216    	; 0x7f72 <main+0x172>
-    }
-    else if(ch == STK_LOAD_ADDRESS) {
-    7e9a:	85 35       	cpi	r24, 0x55	; 85
-    7e9c:	79 f4       	brne	.+30     	; 0x7ebc <main+0xbc>
-      // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    7e9e:	74 d0       	rcall	.+232    	; 0x7f88 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    7ea0:	e8 2e       	mov	r14, r24
-    7ea2:	ff 24       	eor	r15, r15
-    7ea4:	71 d0       	rcall	.+226    	; 0x7f88 <getch>
-    7ea6:	08 2f       	mov	r16, r24
-    7ea8:	10 e0       	ldi	r17, 0x00	; 0
-    7eaa:	10 2f       	mov	r17, r16
-    7eac:	00 27       	eor	r16, r16
-    7eae:	0e 29       	or	r16, r14
-    7eb0:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
-#endif
-      newAddress += newAddress; // Convert from word address to byte address
-    7eb2:	00 0f       	add	r16, r16
-    7eb4:	11 1f       	adc	r17, r17
-      address = newAddress;
-      verifySpace();
-    7eb6:	7a d0       	rcall	.+244    	; 0x7fac <verifySpace>
-    7eb8:	78 01       	movw	r14, r16
-    7eba:	5b c0       	rjmp	.+182    	; 0x7f72 <main+0x172>
-    }
-    else if(ch == STK_UNIVERSAL) {
-    7ebc:	86 35       	cpi	r24, 0x56	; 86
-    7ebe:	21 f4       	brne	.+8      	; 0x7ec8 <main+0xc8>
-      // UNIVERSAL command is ignored
-      getNch(4);
-    7ec0:	84 e0       	ldi	r24, 0x04	; 4
-    7ec2:	7c d0       	rcall	.+248    	; 0x7fbc <getNch>
-      putch(0x00);
-    7ec4:	80 e0       	ldi	r24, 0x00	; 0
-    7ec6:	de cf       	rjmp	.-68     	; 0x7e84 <main+0x84>
-    }
-    /* Write memory, length is big endian and is in bytes */
-    else if(ch == STK_PROG_PAGE) {
-    7ec8:	84 36       	cpi	r24, 0x64	; 100
-    7eca:	09 f0       	breq	.+2      	; 0x7ece <main+0xce>
-    7ecc:	35 c0       	rjmp	.+106    	; 0x7f38 <main+0x138>
-      // PROGRAM PAGE - we support flash programming only, not EEPROM
-      uint8_t desttype;
-      uint8_t *bufPtr;
-      pagelen_t savelength;
-
-      GETLENGTH(length);
-    7ece:	5c d0       	rcall	.+184    	; 0x7f88 <getch>
-    7ed0:	5b d0       	rcall	.+182    	; 0x7f88 <getch>
-    7ed2:	18 2f       	mov	r17, r24
-      savelength = length;
-      desttype = getch();
-    7ed4:	59 d0       	rcall	.+178    	; 0x7f88 <getch>
-    7ed6:	08 2f       	mov	r16, r24
-    7ed8:	c0 e0       	ldi	r28, 0x00	; 0
-    7eda:	d1 e0       	ldi	r29, 0x01	; 1
-
-      // read a page worth of contents
-      bufPtr = buff;
-      do *bufPtr++ = getch();
-    7edc:	55 d0       	rcall	.+170    	; 0x7f88 <getch>
-    7ede:	89 93       	st	Y+, r24
-      while (--length);
-    7ee0:	1c 17       	cp	r17, r28
-    7ee2:	e1 f7       	brne	.-8      	; 0x7edc <main+0xdc>
-
-      // Read command terminator, start reply
-      verifySpace();
-    7ee4:	63 d0       	rcall	.+198    	; 0x7fac <verifySpace>
- * void writebuffer(memtype, buffer, address, length)
- */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
-{
-    switch (memtype) {
-    7ee6:	05 34       	cpi	r16, 0x45	; 69
-    7ee8:	09 f4       	brne	.+2      	; 0x7eec <main+0xec>
-    7eea:	ff cf       	rjmp	.-2      	; 0x7eea <main+0xea>
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    7eec:	f7 01       	movw	r30, r14
-    7eee:	a7 be       	out	0x37, r10	; 55
-    7ef0:	e8 95       	spm
-	    boot_spm_busy_wait();
-    7ef2:	07 b6       	in	r0, 0x37	; 55
-    7ef4:	00 fc       	sbrc	r0, 0
-    7ef6:	fd cf       	rjmp	.-6      	; 0x7ef2 <main+0xf2>
-    7ef8:	a7 01       	movw	r20, r14
-    7efa:	a0 e0       	ldi	r26, 0x00	; 0
-    7efc:	b1 e0       	ldi	r27, 0x01	; 1
-	    /*
-	     * Copy data from the buffer into the flash write buffer.
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-    7efe:	2c 91       	ld	r18, X
-    7f00:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-    7f02:	11 96       	adiw	r26, 0x01	; 1
-    7f04:	8c 91       	ld	r24, X
-    7f06:	11 97       	sbiw	r26, 0x01	; 1
-    7f08:	90 e0       	ldi	r25, 0x00	; 0
-    7f0a:	98 2f       	mov	r25, r24
-    7f0c:	88 27       	eor	r24, r24
-    7f0e:	82 2b       	or	r24, r18
-    7f10:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    7f12:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    7f14:	fa 01       	movw	r30, r20
-    7f16:	0c 01       	movw	r0, r24
-    7f18:	b7 be       	out	0x37, r11	; 55
-    7f1a:	e8 95       	spm
-    7f1c:	11 24       	eor	r1, r1
-		addrPtr += 2;
-    7f1e:	4e 5f       	subi	r20, 0xFE	; 254
-    7f20:	5f 4f       	sbci	r21, 0xFF	; 255
-	    } while (len -= 2);
-    7f22:	1a 17       	cp	r17, r26
-    7f24:	61 f7       	brne	.-40     	; 0x7efe <main+0xfe>
-
-	    /*
-	     * Actually Write the buffer to flash (and wait for it to finish.)
-	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    7f26:	f7 01       	movw	r30, r14
-    7f28:	d7 be       	out	0x37, r13	; 55
-    7f2a:	e8 95       	spm
-	    boot_spm_busy_wait();
-    7f2c:	07 b6       	in	r0, 0x37	; 55
-    7f2e:	00 fc       	sbrc	r0, 0
-    7f30:	fd cf       	rjmp	.-6      	; 0x7f2c <main+0x12c>
-#if defined(RWWSRE)
-	    // Reenable read access to flash
-	    boot_rww_enable();
-    7f32:	c7 be       	out	0x37, r12	; 55
-    7f34:	e8 95       	spm
-    7f36:	1d c0       	rjmp	.+58     	; 0x7f72 <main+0x172>
-      writebuffer(desttype, buff, address, savelength);
-
-
-    }
-    /* Read memory block mode, length is big endian.  */
-    else if(ch == STK_READ_PAGE) {
-    7f38:	84 37       	cpi	r24, 0x74	; 116
-    7f3a:	69 f4       	brne	.+26     	; 0x7f56 <main+0x156>
-      uint8_t desttype;
-      GETLENGTH(length);
-    7f3c:	25 d0       	rcall	.+74     	; 0x7f88 <getch>
-    7f3e:	24 d0       	rcall	.+72     	; 0x7f88 <getch>
-    7f40:	08 2f       	mov	r16, r24
-
-      desttype = getch();
-    7f42:	22 d0       	rcall	.+68     	; 0x7f88 <getch>
-
-      verifySpace();
-    7f44:	33 d0       	rcall	.+102    	; 0x7fac <verifySpace>
-    7f46:	e7 01       	movw	r28, r14
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#else
-	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#endif
-	    putch(ch);
-    7f48:	fe 01       	movw	r30, r28
-    7f4a:	85 91       	lpm	r24, Z+
-    7f4c:	ef 01       	movw	r28, r30
-    7f4e:	14 d0       	rcall	.+40     	; 0x7f78 <putch>
-	} while (--length);
-    7f50:	01 50       	subi	r16, 0x01	; 1
-    7f52:	d1 f7       	brne	.-12     	; 0x7f48 <main+0x148>
-    7f54:	0e c0       	rjmp	.+28     	; 0x7f72 <main+0x172>
-	  
-      read_mem(desttype, address, length);
-    }
-
-    /* Get device signature bytes  */
-    else if(ch == STK_READ_SIGN) {
-    7f56:	85 37       	cpi	r24, 0x75	; 117
-    7f58:	39 f4       	brne	.+14     	; 0x7f68 <main+0x168>
-      // READ SIGN - return what Avrdude wants to hear
-      verifySpace();
-    7f5a:	28 d0       	rcall	.+80     	; 0x7fac <verifySpace>
-      putch(SIGNATURE_0);
-    7f5c:	8e e1       	ldi	r24, 0x1E	; 30
-    7f5e:	0c d0       	rcall	.+24     	; 0x7f78 <putch>
-      putch(SIGNATURE_1);
-    7f60:	85 e9       	ldi	r24, 0x95	; 149
-    7f62:	0a d0       	rcall	.+20     	; 0x7f78 <putch>
-      putch(SIGNATURE_2);
-    7f64:	8f e0       	ldi	r24, 0x0F	; 15
-    7f66:	8e cf       	rjmp	.-228    	; 0x7e84 <main+0x84>
-    }
-    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    7f68:	81 35       	cpi	r24, 0x51	; 81
-    7f6a:	11 f4       	brne	.+4      	; 0x7f70 <main+0x170>
-      // Adaboot no-wait mod
-      watchdogConfig(WATCHDOG_16MS);
-    7f6c:	88 e0       	ldi	r24, 0x08	; 8
-    7f6e:	18 d0       	rcall	.+48     	; 0x7fa0 <watchdogConfig>
-      verifySpace();
-    }
-    else {
-      // This covers the response to commands like STK_ENTER_PROGMODE
-      verifySpace();
-    7f70:	1d d0       	rcall	.+58     	; 0x7fac <verifySpace>
-    }
-    putch(STK_OK);
-    7f72:	80 e1       	ldi	r24, 0x10	; 16
-    7f74:	01 d0       	rcall	.+2      	; 0x7f78 <putch>
-    7f76:	77 cf       	rjmp	.-274    	; 0x7e66 <main+0x66>
-
-00007f78 <putch>:
-  }
-}
-
-void putch(char ch) {
-    7f78:	98 2f       	mov	r25, r24
-#ifndef SOFT_UART
-  while (!(UART_SRA & _BV(UDRE0)));
-    7f7a:	80 91 c0 00 	lds	r24, 0x00C0
-    7f7e:	85 ff       	sbrs	r24, 5
-    7f80:	fc cf       	rjmp	.-8      	; 0x7f7a <putch+0x2>
-  UART_UDR = ch;
-    7f82:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-    7f86:	08 95       	ret
-
-00007f88 <getch>:
-      [uartBit] "I" (UART_RX_BIT)
-    :
-      "r25"
-);
-#else
-  while(!(UART_SRA & _BV(RXC0)))
-    7f88:	80 91 c0 00 	lds	r24, 0x00C0
-    7f8c:	87 ff       	sbrs	r24, 7
-    7f8e:	fc cf       	rjmp	.-8      	; 0x7f88 <getch>
-    ;
-  if (!(UART_SRA & _BV(FE0))) {
-    7f90:	80 91 c0 00 	lds	r24, 0x00C0
-    7f94:	84 fd       	sbrc	r24, 4
-    7f96:	01 c0       	rjmp	.+2      	; 0x7f9a <getch+0x12>
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    7f98:	a8 95       	wdr
-       * don't care that an invalid char is returned...)
-       */
-    watchdogReset();
-  }
-  
-  ch = UART_UDR;
-    7f9a:	80 91 c6 00 	lds	r24, 0x00C6
-  LED_PIN |= _BV(LED);
-#endif
-#endif
-
-  return ch;
-}
-    7f9e:	08 95       	ret
-
-00007fa0 <watchdogConfig>:
-    "wdr\n"
-  );
-}
-
-void watchdogConfig(uint8_t x) {
-  WDTCSR = _BV(WDCE) | _BV(WDE);
-    7fa0:	e0 e6       	ldi	r30, 0x60	; 96
-    7fa2:	f0 e0       	ldi	r31, 0x00	; 0
-    7fa4:	98 e1       	ldi	r25, 0x18	; 24
-    7fa6:	90 83       	st	Z, r25
-  WDTCSR = x;
-    7fa8:	80 83       	st	Z, r24
-}
-    7faa:	08 95       	ret
-
-00007fac <verifySpace>:
-  do getch(); while (--count);
-  verifySpace();
-}
-
-void verifySpace() {
-  if (getch() != CRC_EOP) {
-    7fac:	ed df       	rcall	.-38     	; 0x7f88 <getch>
-    7fae:	80 32       	cpi	r24, 0x20	; 32
-    7fb0:	19 f0       	breq	.+6      	; 0x7fb8 <verifySpace+0xc>
-    watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    7fb2:	88 e0       	ldi	r24, 0x08	; 8
-    7fb4:	f5 df       	rcall	.-22     	; 0x7fa0 <watchdogConfig>
-    7fb6:	ff cf       	rjmp	.-2      	; 0x7fb6 <verifySpace+0xa>
-    while (1)			      // and busy-loop so that WD causes
-      ;				      //  a reset and app start.
-  }
-  putch(STK_INSYNC);
-    7fb8:	84 e1       	ldi	r24, 0x14	; 20
-}
-    7fba:	de cf       	rjmp	.-68     	; 0x7f78 <putch>
-
-00007fbc <getNch>:
-    ::[count] "M" (UART_B_VALUE)
-  );
-}
-#endif
-
-void getNch(uint8_t count) {
-    7fbc:	1f 93       	push	r17
-    7fbe:	18 2f       	mov	r17, r24
-  do getch(); while (--count);
-    7fc0:	e3 df       	rcall	.-58     	; 0x7f88 <getch>
-    7fc2:	11 50       	subi	r17, 0x01	; 1
-    7fc4:	e9 f7       	brne	.-6      	; 0x7fc0 <getNch+0x4>
-  verifySpace();
-    7fc6:	f2 df       	rcall	.-28     	; 0x7fac <verifySpace>
-}
-    7fc8:	1f 91       	pop	r17
-    7fca:	08 95       	ret
-
-00007fcc <appStart>:
-
-void appStart(uint8_t rstFlags) {
-  // save the reset flags in the designated register
-  //  This can be saved in a main program by putting code in .init0 (which
-  //  executes before normal c init code) to save R2 to a global variable.
-  __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    7fcc:	28 2e       	mov	r2, r24
-
-  watchdogConfig(WATCHDOG_OFF);
-    7fce:	80 e0       	ldi	r24, 0x00	; 0
-    7fd0:	e7 df       	rcall	.-50     	; 0x7fa0 <watchdogConfig>
-  __asm__ __volatile__ (
-    7fd2:	ee 27       	eor	r30, r30
-    7fd4:	ff 27       	eor	r31, r31
-    7fd6:	09 94       	ijmp

+ 38 - 32
optiboot/bootloaders/optiboot/optiboot_atmega644p.hex

@@ -1,34 +1,40 @@
-:10FC0000112484B714BE81FFE6D085E08093810083
-:10FC100082E08093C00088E18093C10086E08093F9
-:10FC2000C20080E18093C4008EE0BFD0209A86E0BD
-:10FC300020E33CEF91E0309385002093840096BB55
-:10FC4000B09BFECF189AA8958150A9F7EE24FF2407
-:10FC5000AA24A394B5E0CB2EA1E1BA2EF3E0DF2EC7
-:10FC600098D0813461F495D0082FA5D0023829F1BD
-:10FC7000013811F485E001C083E083D07FC0823475
-:10FC800011F484E103C0853419F485E09CD076C07A
-:10FC9000853579F47ED0E82EFF247BD0082F10E044
-:10FCA000102F00270E291F29000F111F84D0780163
-:10FCB00065C0863521F484E086D080E0DECF8436CE
-:10FCC00009F040C066D065D0082F63D080E0E81608
-:10FCD00080EEF80618F4F701D7BEE895C0E0D1E051
-:10FCE00058D089930C17E1F7F0E0EF16F0EEFF061D
-:10FCF00018F0F701D7BEE8955ED007B600FCFDCF3F
-:10FD0000A701A0E0B1E02C9130E011968C91119701
-:10FD100090E0982F8827822B932B1296FA010C01E2
-:10FD2000A7BEE89511244E5F5F4FF2E0A030BF07F9
-:10FD300051F7F701C7BEE89507B600FCFDCFB7BE87
-:10FD4000E8951CC0843761F424D023D0082F21D03B
-:10FD500032D0F70185917F0114D00150D1F70EC048
-:10FD6000853739F428D08EE10CD086E90AD08AE0B4
-:10FD700084CF813511F488E018D01DD080E101D006
-:10FD80006FCF982F8091C00085FFFCCF9093C60065
-:10FD900008958091C00087FFFCCF8091C00084FD52
-:10FDA00001C0A8958091C6000895E0E6F0E098E1D2
-:10FDB000908380830895EDDF803219F088E0F5DFCD
-:10FDC000FFCF84E1DECF1F93182FE3DF1150E9F757
-:10FDD000F2DF1F910895282E80E0E7DFEE27FF274E
-:02FDE000099484
-:02FFFE000005FC
+:10FC0000112484B7882349F0982F9A70923029F0F4
+:10FC100081FF02C097EF94BFFBD085E08093810005
+:10FC200082E08093C00088E18093C10086E08093E9
+:10FC3000C20080E18093C4008EE0D5D0209A86E097
+:10FC400020E33CEF91E0309385002093840096BB45
+:10FC5000B09BFECF189AA8954091C00047FD02C006
+:10FC6000815089F7FF24F39455E0E52E61E1D62E0B
+:10FC7000AED0813461F4ABD0C82FBBD0C238E9F02C
+:10FC8000C13811F487E001C083E09AD096C0823475
+:10FC900011F484E103C0853419F485E0B2D08DC03D
+:10FCA000853539F494D0082F92D0182F000F111FEA
+:10FCB00083C0863521F484E0A4D080E0E6CF84368A
+:10FCC00009F048C084D0C82FD0E0DC2FCC277FD0EB
+:10FCD000C82B7DD0C82E5E01812C9924939477D0B7
+:10FCE000F40181934F01F1E0AF1AB108C1F781D05F
+:10FCF00085E4C81212C0D3954801A12CBB24B3944B
+:10FD0000AC16BD0609F459C0F50161915F01C4014B
+:10FD10008DD0FFEF8F1A9F0AF3CF83E0F80187BFE2
+:10FD2000E89507B600FCFDCFA0E0B1E0F8018D91A9
+:10FD30009D910C01F7BEE8951124229732962097E9
+:10FD4000B1F7F801E7BEE89507B600FCFDCFD7BED6
+:10FD5000E89533C0843719F53AD0C82FD0E0DC2FAE
+:10FD6000CC2735D05E01A82A32D0982E42D0E801A7
+:10FD7000F5E49F120BC0CE0151D022D081E0A81A29
+:10FD8000B1082196A114B104B1F717C0FE01859105
+:10FD9000EF0116D0E1E0AE1AB108C1F70EC0853709
+:10FDA00039F427D08EE10CD086E90AD08AE06DCFF5
+:10FDB000813511F488E017D01CD080E101D058CFF4
+:10FDC0009091C00095FFFCCF8093C600089580916C
+:10FDD000C00087FFFCCF8091C00084FD01C0A895C2
+:10FDE0008091C6000895E0E6F0E098E1908380837A
+:10FDF0000895EDDF803219F088E0F5DFFFCF84E170
+:10FE0000DFCFCF93C82FE3DFC150E9F7CF91F1CF18
+:10FE1000282E80E0E8DFE0E0FF270994F999FECF83
+:10FE200092BD81BDF89A992780B50895262FF9993A
+:10FE3000FECF1FBA92BD81BD20BD0FB6F894FA9ACD
+:08FE4000F99A0FBE0196089526
+:02FFFE000007FA
 :040000030000FC00FD
 :00000001FF

+ 464 - 367
optiboot/bootloaders/optiboot/optiboot_atmega644p.lst

@@ -3,584 +3,681 @@ optiboot_atmega644p.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001e2  0000fc00  0000fc00  00000054  2**1
+  0 .data         00000000  00800100  0000fe48  000002dc  2**0
+                  CONTENTS, ALLOC, LOAD, DATA
+  1 .text         00000248  0000fc00  0000fc00  00000094  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  0000fffe  0000fffe  00000236  2**0
+  2 .version      00000002  0000fffe  0000fffe  000002dc  2**0
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+  3 .comment      0000002f  00000000  00000000  000002de  2**0
                   CONTENTS, READONLY
-  2 .debug_aranges 00000028  00000000  00000000  00000238  2**0
+  4 .debug_aranges 00000028  00000000  00000000  0000030d  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 0000005f  00000000  00000000  00000260  2**0
+  5 .debug_info   00000625  00000000  00000000  00000335  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   00000294  00000000  00000000  000002bf  2**0
+  6 .debug_abbrev 00000286  00000000  00000000  0000095a  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 0000016b  00000000  00000000  00000553  2**0
+  7 .debug_line   0000035f  00000000  00000000  00000be0  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000421  00000000  00000000  000006be  2**0
+  8 .debug_frame  0000008c  00000000  00000000  00000f40  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000ae0  2**2
+  9 .debug_str    0000021d  00000000  00000000  00000fcc  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000131  00000000  00000000  00000b60  2**0
+ 10 .debug_loc    00000421  00000000  00000000  000011e9  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000266  00000000  00000000  00000c91  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 00000078  00000000  00000000  00000ef7  2**0
+ 11 .debug_ranges 00000060  00000000  00000000  0000160a  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 0000fc00 <main>:
-# define UART_SRL UBRR3L
-# define UART_UDR UDR3
-#endif
-
-/* main program starts here */
-int main(void) {
+  //  SP points to RAMEND
+  //  r1 contains zero
+  //
+  // If not, uncomment the following instructions:
+  // cli();
+  asm volatile ("clr __zero_reg__");
     fc00:	11 24       	eor	r1, r1
-#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__)
-  SP=RAMEND;  // This is done by hardware reset
-#endif
-
-  // Adaboot no-wait mod
+   * 
+   * Code by MarkG55
+   * see discusion in https://github.com/Optiboot/optiboot/issues/97
+   */
+#if !defined(__AVR_ATmega16__)
   ch = MCUSR;
     fc02:	84 b7       	in	r24, 0x34	; 52
-  MCUSR = 0;
-    fc04:	14 be       	out	0x34, r1	; 52
-  if (!(ch & _BV(EXTRF))) appStart(ch);
-    fc06:	81 ff       	sbrs	r24, 1
-    fc08:	e6 d0       	rcall	.+460    	; 0xfdd6 <appStart>
+#else
+  ch = MCUCSR;
+#endif
+  // Skip all logic and run bootloader if MCUSR is cleared (application request)
+  if (ch != 0) {
+    fc04:	88 23       	and	r24, r24
+    fc06:	49 f0       	breq	.+18     	; 0xfc1a <main+0x1a>
+       *  2. we clear WDRF if it's set with EXTRF to avoid loops
+       * One problematic scenario: broken application code sets watchdog timer 
+       * without clearing MCUSR before and triggers it quickly. But it's
+       * recoverable by power-on with pushed reset button.
+       */
+      if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) { 
+    fc08:	98 2f       	mov	r25, r24
+    fc0a:	9a 70       	andi	r25, 0x0A	; 10
+    fc0c:	92 30       	cpi	r25, 0x02	; 2
+    fc0e:	29 f0       	breq	.+10     	; 0xfc1a <main+0x1a>
+	  if (ch & _BV(EXTRF)) {
+    fc10:	81 ff       	sbrs	r24, 1
+    fc12:	02 c0       	rjmp	.+4      	; 0xfc18 <main+0x18>
+	       * prevent entering bootloader.
+	       * '&' operation is skipped to spare few bytes as bits in MCUSR
+	       * can only be cleared.
+	       */
+#if !defined(__AVR_ATmega16__)
+	      MCUSR = ~(_BV(WDRF));  
+    fc14:	97 ef       	ldi	r25, 0xF7	; 247
+    fc16:	94 bf       	out	0x34, r25	; 52
+#else
+	      MCUCSR = ~(_BV(WDRF));  
+#endif
+	  }
+	  appStart(ch);
+    fc18:	fb d0       	rcall	.+502    	; 0xfe10 <appStart>
+      }
+  }
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
   TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    fc0a:	85 e0       	ldi	r24, 0x05	; 5
-    fc0c:	80 93 81 00 	sts	0x0081, r24
+    fc1a:	85 e0       	ldi	r24, 0x05	; 5
+    fc1c:	80 93 81 00 	sts	0x0081, r24	; 0x800081 <__TEXT_REGION_LENGTH__+0x7e0081>
   UCSRA = _BV(U2X); //Double speed mode USART
   UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
   UART_SRA = _BV(U2X0); //Double speed mode USART0
-    fc10:	82 e0       	ldi	r24, 0x02	; 2
-    fc12:	80 93 c0 00 	sts	0x00C0, r24
+    fc20:	82 e0       	ldi	r24, 0x02	; 2
+    fc22:	80 93 c0 00 	sts	0x00C0, r24	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-    fc16:	88 e1       	ldi	r24, 0x18	; 24
-    fc18:	80 93 c1 00 	sts	0x00C1, r24
+    fc26:	88 e1       	ldi	r24, 0x18	; 24
+    fc28:	80 93 c1 00 	sts	0x00C1, r24	; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7e00c1>
   UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-    fc1c:	86 e0       	ldi	r24, 0x06	; 6
-    fc1e:	80 93 c2 00 	sts	0x00C2, r24
+    fc2c:	86 e0       	ldi	r24, 0x06	; 6
+    fc2e:	80 93 c2 00 	sts	0x00C2, r24	; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7e00c2>
   UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-    fc22:	80 e1       	ldi	r24, 0x10	; 16
-    fc24:	80 93 c4 00 	sts	0x00C4, r24
+    fc32:	80 e1       	ldi	r24, 0x10	; 16
+    fc34:	80 93 c4 00 	sts	0x00C4, r24	; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7e00c4>
 #endif
 #endif
 
-  // Set up watchdog to trigger after 500ms
+  // Set up watchdog to trigger after 1s
   watchdogConfig(WATCHDOG_1S);
-    fc28:	8e e0       	ldi	r24, 0x0E	; 14
-    fc2a:	bf d0       	rcall	.+382    	; 0xfdaa <watchdogConfig>
+    fc38:	8e e0       	ldi	r24, 0x0E	; 14
+    fc3a:	d5 d0       	rcall	.+426    	; 0xfde6 <watchdogConfig>
 
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
-    fc2c:	20 9a       	sbi	0x04, 0	; 4
-    fc2e:	86 e0       	ldi	r24, 0x06	; 6
+    fc3c:	20 9a       	sbi	0x04, 0	; 4
+    fc3e:	86 e0       	ldi	r24, 0x06	; 6
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-    fc30:	20 e3       	ldi	r18, 0x30	; 48
-    fc32:	3c ef       	ldi	r19, 0xFC	; 252
+    fc40:	20 e3       	ldi	r18, 0x30	; 48
+    fc42:	3c ef       	ldi	r19, 0xFC	; 252
     TIFR1 = _BV(TOV1);
-    fc34:	91 e0       	ldi	r25, 0x01	; 1
+    fc44:	91 e0       	ldi	r25, 0x01	; 1
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-    fc36:	30 93 85 00 	sts	0x0085, r19
-    fc3a:	20 93 84 00 	sts	0x0084, r18
+    fc46:	30 93 85 00 	sts	0x0085, r19	; 0x800085 <__TEXT_REGION_LENGTH__+0x7e0085>
+    fc4a:	20 93 84 00 	sts	0x0084, r18	; 0x800084 <__TEXT_REGION_LENGTH__+0x7e0084>
     TIFR1 = _BV(TOV1);
-    fc3e:	96 bb       	out	0x16, r25	; 22
+    fc4e:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
-    fc40:	b0 9b       	sbis	0x16, 0	; 22
-    fc42:	fe cf       	rjmp	.-4      	; 0xfc40 <main+0x40>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
+    fc50:	b0 9b       	sbis	0x16, 0	; 22
+    fc52:	fe cf       	rjmp	.-4      	; 0xfc50 <main+0x50>
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
     LED_PORT ^= _BV(LED);
 #else
     LED_PIN |= _BV(LED);
-    fc44:	18 9a       	sbi	0x03, 0	; 3
+    fc54:	18 9a       	sbi	0x03, 0	; 3
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    fc46:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
+    fc56:	a8 95       	wdr
+     * While in theory, the STK500 initial commands would be buffered
+     *  by the UART hardware, avrdude sends several attempts in rather
+     *  quick succession, some of which will be lost and cause us to
+     *  get out of sync.  So if we see any data; stop blinking.
+     */
+    if (UART_SRA & _BV(RXC0))
+    fc58:	40 91 c0 00 	lds	r20, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    fc5c:	47 fd       	sbrc	r20, 7
+    fc5e:	02 c0       	rjmp	.+4      	; 0xfc64 <main+0x64>
+    fc60:	81 50       	subi	r24, 0x01	; 1
 #else
-    LED_PIN |= _BV(LED);
+// This doesn't seem to work?
+//    if ((UART_PIN & (1<<UART_RX_BIT)) == 0)
+//	break;  // detect start bit on soft uart too.
 #endif
-    watchdogReset();
   } while (--count);
-    fc48:	81 50       	subi	r24, 0x01	; 1
-    fc4a:	a9 f7       	brne	.-22     	; 0xfc36 <main+0x36>
-    fc4c:	ee 24       	eor	r14, r14
-    fc4e:	ff 24       	eor	r15, r15
-      ch = SPM_PAGESIZE / 2;
-      do {
-        uint16_t a;
-        a = *bufPtr++;
-        a |= (*bufPtr++) << 8;
-        __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    fc50:	aa 24       	eor	r10, r10
-    fc52:	a3 94       	inc	r10
-        addrPtr += 2;
-      } while (--ch);
-
-      // Write from programming buffer
-      __boot_page_write_short((uint16_t)(void*)address);
-    fc54:	b5 e0       	ldi	r27, 0x05	; 5
-    fc56:	cb 2e       	mov	r12, r27
-      boot_spm_busy_wait();
-
+    fc62:	89 f7       	brne	.-30     	; 0xfc46 <main+0x46>
+
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
+	     */
+	    do {
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    fc64:	ff 24       	eor	r15, r15
+    fc66:	f3 94       	inc	r15
+	    } while (len -= 2);
+
+	    /*
+	     * Actually Write the buffer to flash (and wait for it to finish.)
+	     */
+	    __boot_page_write_short(address.word);
+    fc68:	55 e0       	ldi	r21, 0x05	; 5
+    fc6a:	e5 2e       	mov	r14, r21
+	    boot_spm_busy_wait();
 #if defined(RWWSRE)
-      // Reenable read access to flash
-      boot_rww_enable();
-    fc58:	a1 e1       	ldi	r26, 0x11	; 17
-    fc5a:	ba 2e       	mov	r11, r26
-
-      // If we are in NRWW section, page erase has to be delayed until now.
-      // Todo: Take RAMPZ into account (not doing so just means that we will
-      //  treat the top of both "pages" of flash as NRWW, for a slight speed
-      //  decrease, so fixing this is not urgent.)
-      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    fc5c:	f3 e0       	ldi	r31, 0x03	; 3
-    fc5e:	df 2e       	mov	r13, r31
+	    // Reenable read access to flash
+	    __boot_rww_enable_short();
+    fc6c:	61 e1       	ldi	r22, 0x11	; 17
 #endif
 
-  /* Forever loop */
+  /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    fc60:	98 d0       	rcall	.+304    	; 0xfd92 <getch>
+    fc6e:	d6 2e       	mov	r13, r22
 
     if(ch == STK_GET_PARAMETER) {
-    fc62:	81 34       	cpi	r24, 0x41	; 65
-    fc64:	61 f4       	brne	.+24     	; 0xfc7e <main+0x7e>
+    fc70:	ae d0       	rcall	.+348    	; 0xfdce <getch>
       unsigned char which = getch();
-    fc66:	95 d0       	rcall	.+298    	; 0xfd92 <getch>
-    fc68:	08 2f       	mov	r16, r24
+    fc72:	81 34       	cpi	r24, 0x41	; 65
+    fc74:	61 f4       	brne	.+24     	; 0xfc8e <main+0x8e>
+    fc76:	ab d0       	rcall	.+342    	; 0xfdce <getch>
       verifySpace();
-    fc6a:	a5 d0       	rcall	.+330    	; 0xfdb6 <verifySpace>
-      if (which == 0x82) {
-    fc6c:	02 38       	cpi	r16, 0x82	; 130
-    fc6e:	29 f1       	breq	.+74     	; 0xfcba <main+0xba>
-	/*
-	 * Send optiboot version as "minor SW version"
-	 */
-	putch(OPTIBOOT_MINVER);
-      } else if (which == 0x81) {
-    fc70:	01 38       	cpi	r16, 0x81	; 129
-    fc72:	11 f4       	brne	.+4      	; 0xfc78 <main+0x78>
-	  putch(OPTIBOOT_MAJVER);
-    fc74:	85 e0       	ldi	r24, 0x05	; 5
-    fc76:	01 c0       	rjmp	.+2      	; 0xfc7a <main+0x7a>
+    fc78:	c8 2f       	mov	r28, r24
+    fc7a:	bb d0       	rcall	.+374    	; 0xfdf2 <verifySpace>
+      /*
+       * Send optiboot version as "SW version"
+       * Note that the references to memory are optimized away.
+       */
+      if (which == STK_SW_MINOR) {
+    fc7c:	c2 38       	cpi	r28, 0x82	; 130
+    fc7e:	e9 f0       	breq	.+58     	; 0xfcba <main+0xba>
+	  putch(optiboot_version & 0xFF);
+      } else if (which == STK_SW_MAJOR) {
+    fc80:	c1 38       	cpi	r28, 0x81	; 129
+	  putch(optiboot_version >> 8);
+    fc82:	11 f4       	brne	.+4      	; 0xfc88 <main+0x88>
+    fc84:	87 e0       	ldi	r24, 0x07	; 7
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    fc78:	83 e0       	ldi	r24, 0x03	; 3
-    fc7a:	83 d0       	rcall	.+262    	; 0xfd82 <putch>
-    fc7c:	7f c0       	rjmp	.+254    	; 0xfd7c <main+0x17c>
+    fc86:	01 c0       	rjmp	.+2      	; 0xfc8a <main+0x8a>
+    fc88:	83 e0       	ldi	r24, 0x03	; 3
+    fc8a:	9a d0       	rcall	.+308    	; 0xfdc0 <putch>
+    fc8c:	96 c0       	rjmp	.+300    	; 0xfdba <main+0x1ba>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    fc7e:	82 34       	cpi	r24, 0x42	; 66
-    fc80:	11 f4       	brne	.+4      	; 0xfc86 <main+0x86>
+    fc8e:	82 34       	cpi	r24, 0x42	; 66
       // SET DEVICE is ignored
       getNch(20);
-    fc82:	84 e1       	ldi	r24, 0x14	; 20
-    fc84:	03 c0       	rjmp	.+6      	; 0xfc8c <main+0x8c>
+    fc90:	11 f4       	brne	.+4      	; 0xfc96 <main+0x96>
+    fc92:	84 e1       	ldi	r24, 0x14	; 20
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    fc86:	85 34       	cpi	r24, 0x45	; 69
-    fc88:	19 f4       	brne	.+6      	; 0xfc90 <main+0x90>
+    fc94:	03 c0       	rjmp	.+6      	; 0xfc9c <main+0x9c>
       // SET DEVICE EXT is ignored
       getNch(5);
-    fc8a:	85 e0       	ldi	r24, 0x05	; 5
-    fc8c:	9c d0       	rcall	.+312    	; 0xfdc6 <getNch>
-    fc8e:	76 c0       	rjmp	.+236    	; 0xfd7c <main+0x17c>
+    fc96:	85 34       	cpi	r24, 0x45	; 69
+    fc98:	19 f4       	brne	.+6      	; 0xfca0 <main+0xa0>
+    fc9a:	85 e0       	ldi	r24, 0x05	; 5
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    fc90:	85 35       	cpi	r24, 0x55	; 85
-    fc92:	79 f4       	brne	.+30     	; 0xfcb2 <main+0xb2>
+    fc9c:	b2 d0       	rcall	.+356    	; 0xfe02 <getNch>
+    fc9e:	8d c0       	rjmp	.+282    	; 0xfdba <main+0x1ba>
       // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    fc94:	7e d0       	rcall	.+252    	; 0xfd92 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    fc96:	e8 2e       	mov	r14, r24
-    fc98:	ff 24       	eor	r15, r15
-    fc9a:	7b d0       	rcall	.+246    	; 0xfd92 <getch>
-    fc9c:	08 2f       	mov	r16, r24
-    fc9e:	10 e0       	ldi	r17, 0x00	; 0
-    fca0:	10 2f       	mov	r17, r16
-    fca2:	00 27       	eor	r16, r16
-    fca4:	0e 29       	or	r16, r14
-    fca6:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
+      address.bytes[0] = getch();
+    fca0:	85 35       	cpi	r24, 0x55	; 85
+    fca2:	39 f4       	brne	.+14     	; 0xfcb2 <main+0xb2>
+    fca4:	94 d0       	rcall	.+296    	; 0xfdce <getch>
+      address.bytes[1] = getch();
+    fca6:	08 2f       	mov	r16, r24
+    fca8:	92 d0       	rcall	.+292    	; 0xfdce <getch>
+      }
+      else {
+        RAMPZ &= 0xFE;
+      }
 #endif
-      newAddress += newAddress; // Convert from word address to byte address
-    fca8:	00 0f       	add	r16, r16
-    fcaa:	11 1f       	adc	r17, r17
-      address = newAddress;
+      address.word *= 2; // Convert from word address to byte address
+    fcaa:	18 2f       	mov	r17, r24
+    fcac:	00 0f       	add	r16, r16
+    fcae:	11 1f       	adc	r17, r17
       verifySpace();
-    fcac:	84 d0       	rcall	.+264    	; 0xfdb6 <verifySpace>
-    fcae:	78 01       	movw	r14, r16
-    fcb0:	65 c0       	rjmp	.+202    	; 0xfd7c <main+0x17c>
     }
     else if(ch == STK_UNIVERSAL) {
-    fcb2:	86 35       	cpi	r24, 0x56	; 86
-    fcb4:	21 f4       	brne	.+8      	; 0xfcbe <main+0xbe>
+    fcb0:	83 c0       	rjmp	.+262    	; 0xfdb8 <main+0x1b8>
+        getNch(3);
+        putch(0x00);
+      }
+#else
       // UNIVERSAL command is ignored
       getNch(4);
+    fcb2:	86 35       	cpi	r24, 0x56	; 86
+    fcb4:	21 f4       	brne	.+8      	; 0xfcbe <main+0xbe>
     fcb6:	84 e0       	ldi	r24, 0x04	; 4
-    fcb8:	86 d0       	rcall	.+268    	; 0xfdc6 <getNch>
       putch(0x00);
-    fcba:	80 e0       	ldi	r24, 0x00	; 0
-    fcbc:	de cf       	rjmp	.-68     	; 0xfc7a <main+0x7a>
+    fcb8:	a4 d0       	rcall	.+328    	; 0xfe02 <getNch>
+#endif
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
+    fcba:	80 e0       	ldi	r24, 0x00	; 0
+    fcbc:	e6 cf       	rjmp	.-52     	; 0xfc8a <main+0x8a>
+      // PROGRAM PAGE - we support flash programming only, not EEPROM
+      uint8_t desttype;
+      uint8_t *bufPtr;
+      pagelen_t savelength;
+
+      GETLENGTH(length);
     fcbe:	84 36       	cpi	r24, 0x64	; 100
     fcc0:	09 f0       	breq	.+2      	; 0xfcc4 <main+0xc4>
-    fcc2:	40 c0       	rjmp	.+128    	; 0xfd44 <main+0x144>
+    fcc2:	48 c0       	rjmp	.+144    	; 0xfd54 <main+0x154>
+    fcc4:	84 d0       	rcall	.+264    	; 0xfdce <getch>
+    fcc6:	c8 2f       	mov	r28, r24
+    fcc8:	d0 e0       	ldi	r29, 0x00	; 0
+    fcca:	dc 2f       	mov	r29, r28
+    fccc:	cc 27       	eor	r28, r28
+      savelength = length;
+      desttype = getch();
+    fcce:	7f d0       	rcall	.+254    	; 0xfdce <getch>
+    fcd0:	c8 2b       	or	r28, r24
       // PROGRAM PAGE - we support flash programming only, not EEPROM
+      uint8_t desttype;
       uint8_t *bufPtr;
-      uint16_t addrPtr;
-
-      getch();			/* getlen() */
-    fcc4:	66 d0       	rcall	.+204    	; 0xfd92 <getch>
-      length = getch();
-    fcc6:	65 d0       	rcall	.+202    	; 0xfd92 <getch>
-    fcc8:	08 2f       	mov	r16, r24
-      getch();
-    fcca:	63 d0       	rcall	.+198    	; 0xfd92 <getch>
-
-      // If we are in RWW section, immediately start page erase
-      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    fccc:	80 e0       	ldi	r24, 0x00	; 0
-    fcce:	e8 16       	cp	r14, r24
-    fcd0:	80 ee       	ldi	r24, 0xE0	; 224
-    fcd2:	f8 06       	cpc	r15, r24
-    fcd4:	18 f4       	brcc	.+6      	; 0xfcdc <main+0xdc>
-    fcd6:	f7 01       	movw	r30, r14
-    fcd8:	d7 be       	out	0x37, r13	; 55
-    fcda:	e8 95       	spm
-    fcdc:	c0 e0       	ldi	r28, 0x00	; 0
-    fcde:	d1 e0       	ldi	r29, 0x01	; 1
-
-      // While that is going on, read in page contents
-      bufPtr = buff;
+      pagelen_t savelength;
+
+      GETLENGTH(length);
+    fcd2:	7d d0       	rcall	.+250    	; 0xfdce <getch>
+      savelength = length;
+      desttype = getch();
+    fcd4:	c8 2e       	mov	r12, r24
+    fcd6:	5e 01       	movw	r10, r28
+    fcd8:	81 2c       	mov	r8, r1
+
+      // read a page worth of contents
+      bufPtr = buff.bptr;
       do *bufPtr++ = getch();
-    fce0:	58 d0       	rcall	.+176    	; 0xfd92 <getch>
-    fce2:	89 93       	st	Y+, r24
+    fcda:	99 24       	eor	r9, r9
+    fcdc:	93 94       	inc	r9
+    fcde:	77 d0       	rcall	.+238    	; 0xfdce <getch>
+    fce0:	f4 01       	movw	r30, r8
+    fce2:	81 93       	st	Z+, r24
       while (--length);
-    fce4:	0c 17       	cp	r16, r28
-    fce6:	e1 f7       	brne	.-8      	; 0xfce0 <main+0xe0>
-
-      // If we are in NRWW section, page erase has to be delayed until now.
-      // Todo: Take RAMPZ into account (not doing so just means that we will
-      //  treat the top of both "pages" of flash as NRWW, for a slight speed
-      //  decrease, so fixing this is not urgent.)
-      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
-    fce8:	f0 e0       	ldi	r31, 0x00	; 0
-    fcea:	ef 16       	cp	r14, r31
-    fcec:	f0 ee       	ldi	r31, 0xE0	; 224
-    fcee:	ff 06       	cpc	r15, r31
-    fcf0:	18 f0       	brcs	.+6      	; 0xfcf8 <main+0xf8>
-    fcf2:	f7 01       	movw	r30, r14
-    fcf4:	d7 be       	out	0x37, r13	; 55
-    fcf6:	e8 95       	spm
+    fce4:	4f 01       	movw	r8, r30
+    fce6:	f1 e0       	ldi	r31, 0x01	; 1
+    fce8:	af 1a       	sub	r10, r31
+    fcea:	b1 08       	sbc	r11, r1
 
       // Read command terminator, start reply
       verifySpace();
-    fcf8:	5e d0       	rcall	.+188    	; 0xfdb6 <verifySpace>
-
-      // If only a partial page is to be programmed, the erase might not be complete.
-      // So check that here
-      boot_spm_busy_wait();
-    fcfa:	07 b6       	in	r0, 0x37	; 55
-    fcfc:	00 fc       	sbrc	r0, 0
-    fcfe:	fd cf       	rjmp	.-6      	; 0xfcfa <main+0xfa>
-    fd00:	a7 01       	movw	r20, r14
-    fd02:	a0 e0       	ldi	r26, 0x00	; 0
-    fd04:	b1 e0       	ldi	r27, 0x01	; 1
-      bufPtr = buff;
-      addrPtr = (uint16_t)(void*)address;
-      ch = SPM_PAGESIZE / 2;
-      do {
-        uint16_t a;
-        a = *bufPtr++;
-    fd06:	2c 91       	ld	r18, X
-    fd08:	30 e0       	ldi	r19, 0x00	; 0
-        a |= (*bufPtr++) << 8;
-    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 UART_SRL UBRR3L
-# define UART_UDR UDR3
-#endif
-
-/* main program starts here */
-int main(void) {
-    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);
-    fd1c:	fa 01       	movw	r30, r20
-    fd1e:	0c 01       	movw	r0, r24
-    fd20:	a7 be       	out	0x37, r10	; 55
-    fd22:	e8 95       	spm
-    fd24:	11 24       	eor	r1, r1
-        addrPtr += 2;
-    fd26:	4e 5f       	subi	r20, 0xFE	; 254
-    fd28:	5f 4f       	sbci	r21, 0xFF	; 255
-      } while (--ch);
-    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);
-    fd32:	f7 01       	movw	r30, r14
-    fd34:	c7 be       	out	0x37, r12	; 55
+    fcec:	c1 f7       	brne	.-16     	; 0xfcde <main+0xde>
+    fcee:	81 d0       	rcall	.+258    	; 0xfdf2 <verifySpace>
+ * void writebuffer(memtype, buffer, address, length)
+ */
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+			       addr16_t address, pagelen_t len)
+{
+    switch (memtype) {
+    fcf0:	85 e4       	ldi	r24, 0x45	; 69
+    fcf2:	c8 12       	cpse	r12, r24
+    fcf4:	12 c0       	rjmp	.+36     	; 0xfd1a <main+0x11a>
+    fcf6:	d3 95       	inc	r29
+    fcf8:	48 01       	movw	r8, r16
+    fcfa:	a1 2c       	mov	r10, r1
+    fcfc:	bb 24       	eor	r11, r11
+    case 'E': // EEPROM
+#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
+        while(len--) {
+    fcfe:	b3 94       	inc	r11
+    fd00:	ac 16       	cp	r10, r28
+    fd02:	bd 06       	cpc	r11, r29
+    fd04:	09 f4       	brne	.+2      	; 0xfd08 <main+0x108>
+	    eeprom_write_byte((address.bptr++), *(mybuff.bptr++));
+    fd06:	59 c0       	rjmp	.+178    	; 0xfdba <main+0x1ba>
+    fd08:	f5 01       	movw	r30, r10
+    fd0a:	61 91       	ld	r22, Z+
+    fd0c:	5f 01       	movw	r10, r30
+    fd0e:	c4 01       	movw	r24, r8
+    fd10:	8d d0       	rcall	.+282    	; 0xfe2c <eeprom_write_byte>
+    fd12:	ff ef       	ldi	r31, 0xFF	; 255
+    fd14:	8f 1a       	sub	r8, r31
+    fd16:	9f 0a       	sbc	r9, r31
+    fd18:	f3 cf       	rjmp	.-26     	; 0xfd00 <main+0x100>
+	     * Start the page erase and wait for it to finish.  There
+	     * used to be code to do this while receiving the data over
+	     * the serial link, but the performance improvement was slight,
+	     * and we needed the space back.
+	     */
+	    __boot_page_erase_short(address.word);
+    fd1a:	83 e0       	ldi	r24, 0x03	; 3
+    fd1c:	f8 01       	movw	r30, r16
+    fd1e:	87 bf       	out	0x37, r24	; 55
+    fd20:	e8 95       	spm
+	    boot_spm_busy_wait();
+    fd22:	07 b6       	in	r0, 0x37	; 55
+    fd24:	00 fc       	sbrc	r0, 0
+    fd26:	fd cf       	rjmp	.-6      	; 0xfd22 <main+0x122>
+    fd28:	a0 e0       	ldi	r26, 0x00	; 0
+    fd2a:	b1 e0       	ldi	r27, 0x01	; 1
+    fd2c:	f8 01       	movw	r30, r16
+
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
+	     */
+	    do {
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    fd2e:	8d 91       	ld	r24, X+
+    fd30:	9d 91       	ld	r25, X+
+    fd32:	0c 01       	movw	r0, r24
+    fd34:	f7 be       	out	0x37, r15	; 55
     fd36:	e8 95       	spm
-      boot_spm_busy_wait();
-    fd38:	07 b6       	in	r0, 0x37	; 55
-    fd3a:	00 fc       	sbrc	r0, 0
-    fd3c:	fd cf       	rjmp	.-6      	; 0xfd38 <main+0x138>
-
+		addrPtr += 2;
+	    } while (len -= 2);
+    fd38:	11 24       	eor	r1, r1
+    fd3a:	22 97       	sbiw	r28, 0x02	; 2
+    fd3c:	32 96       	adiw	r30, 0x02	; 2
+    fd3e:	20 97       	sbiw	r28, 0x00	; 0
+
+	    /*
+	     * Actually Write the buffer to flash (and wait for it to finish.)
+	     */
+	    __boot_page_write_short(address.word);
+    fd40:	b1 f7       	brne	.-20     	; 0xfd2e <main+0x12e>
+    fd42:	f8 01       	movw	r30, r16
+	    boot_spm_busy_wait();
+    fd44:	e7 be       	out	0x37, r14	; 55
+    fd46:	e8 95       	spm
 #if defined(RWWSRE)
-      // Reenable read access to flash
-      boot_rww_enable();
-    fd3e:	b7 be       	out	0x37, r11	; 55
-    fd40:	e8 95       	spm
-    fd42:	1c c0       	rjmp	.+56     	; 0xfd7c <main+0x17c>
-#endif
+	    // Reenable read access to flash
+	    __boot_rww_enable_short();
+    fd48:	07 b6       	in	r0, 0x37	; 55
+    fd4a:	00 fc       	sbrc	r0, 0
+    fd4c:	fd cf       	rjmp	.-6      	; 0xfd48 <main+0x148>
+      writebuffer(desttype, buff, address, savelength);
+
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    fd44:	84 37       	cpi	r24, 0x74	; 116
-    fd46:	61 f4       	brne	.+24     	; 0xfd60 <main+0x160>
-      // READ PAGE - we only read flash
-      getch();			/* getlen() */
-    fd48:	24 d0       	rcall	.+72     	; 0xfd92 <getch>
-      length = getch();
-    fd4a:	23 d0       	rcall	.+70     	; 0xfd92 <getch>
-    fd4c:	08 2f       	mov	r16, r24
-      getch();
-    fd4e:	21 d0       	rcall	.+66     	; 0xfd92 <getch>
+    fd4e:	d7 be       	out	0x37, r13	; 55
+    fd50:	e8 95       	spm
+      uint8_t desttype;
+      GETLENGTH(length);
+    fd52:	33 c0       	rjmp	.+102    	; 0xfdba <main+0x1ba>
+    fd54:	84 37       	cpi	r24, 0x74	; 116
+    fd56:	19 f5       	brne	.+70     	; 0xfd9e <main+0x19e>
+    fd58:	3a d0       	rcall	.+116    	; 0xfdce <getch>
+    fd5a:	c8 2f       	mov	r28, r24
+    fd5c:	d0 e0       	ldi	r29, 0x00	; 0
+    fd5e:	dc 2f       	mov	r29, r28
+    fd60:	cc 27       	eor	r28, r28
+
+      desttype = getch();
+    fd62:	35 d0       	rcall	.+106    	; 0xfdce <getch>
+    fd64:	5e 01       	movw	r10, r28
+    fd66:	a8 2a       	or	r10, r24
 
       verifySpace();
-    fd50:	32 d0       	rcall	.+100    	; 0xfdb6 <verifySpace>
-        __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+    fd68:	32 d0       	rcall	.+100    	; 0xfdce <getch>
+    fd6a:	98 2e       	mov	r9, r24
+
+static inline void read_mem(uint8_t memtype, addr16_t address, pagelen_t length)
+{
+    uint8_t ch;
+
+    switch (memtype) {
+    fd6c:	42 d0       	rcall	.+132    	; 0xfdf2 <verifySpace>
+    fd6e:	e8 01       	movw	r28, r16
+    fd70:	f5 e4       	ldi	r31, 0x45	; 69
+
+#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
+    case 'E': // EEPROM
+	do {
+	    putch(eeprom_read_byte((address.bptr++)));
+    fd72:	9f 12       	cpse	r9, r31
+    fd74:	0b c0       	rjmp	.+22     	; 0xfd8c <main+0x18c>
+    fd76:	ce 01       	movw	r24, r28
+    fd78:	51 d0       	rcall	.+162    	; 0xfe1c <eeprom_read_byte>
+	} while (--length);
+    fd7a:	22 d0       	rcall	.+68     	; 0xfdc0 <putch>
+    fd7c:	81 e0       	ldi	r24, 0x01	; 1
+    fd7e:	a8 1a       	sub	r10, r24
+    fd80:	b1 08       	sbc	r11, r1
+    fd82:	21 96       	adiw	r28, 0x01	; 1
+    fd84:	a1 14       	cp	r10, r1
+    fd86:	b1 04       	cpc	r11, r1
+	    //      while (--length);
+	    // read a Flash and increment the address (may increment RAMPZ)
+	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
 #else
-        // read a Flash byte and increment the address
-        __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    // read a Flash byte and increment the address
+	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+    fd88:	b1 f7       	brne	.-20     	; 0xfd76 <main+0x176>
+    fd8a:	17 c0       	rjmp	.+46     	; 0xfdba <main+0x1ba>
 #endif
-        putch(ch);
-    fd52:	f7 01       	movw	r30, r14
-    fd54:	85 91       	lpm	r24, Z+
-    fd56:	7f 01       	movw	r14, r30
-    fd58:	14 d0       	rcall	.+40     	; 0xfd82 <putch>
-      } while (--length);
-    fd5a:	01 50       	subi	r16, 0x01	; 1
-    fd5c:	d1 f7       	brne	.-12     	; 0xfd52 <main+0x152>
-    fd5e:	0e c0       	rjmp	.+28     	; 0xfd7c <main+0x17c>
+	    putch(ch);
+    fd8c:	fe 01       	movw	r30, r28
+    fd8e:	85 91       	lpm	r24, Z+
+	} while (--length);
+    fd90:	ef 01       	movw	r28, r30
+    fd92:	16 d0       	rcall	.+44     	; 0xfdc0 <putch>
+    fd94:	e1 e0       	ldi	r30, 0x01	; 1
+    fd96:	ae 1a       	sub	r10, r30
+    fd98:	b1 08       	sbc	r11, r1
+
+      read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    fd60:	85 37       	cpi	r24, 0x75	; 117
-    fd62:	39 f4       	brne	.+14     	; 0xfd72 <main+0x172>
+    fd9a:	c1 f7       	brne	.-16     	; 0xfd8c <main+0x18c>
+    fd9c:	0e c0       	rjmp	.+28     	; 0xfdba <main+0x1ba>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    fd64:	28 d0       	rcall	.+80     	; 0xfdb6 <verifySpace>
+    fd9e:	85 37       	cpi	r24, 0x75	; 117
+    fda0:	39 f4       	brne	.+14     	; 0xfdb0 <main+0x1b0>
       putch(SIGNATURE_0);
-    fd66:	8e e1       	ldi	r24, 0x1E	; 30
-    fd68:	0c d0       	rcall	.+24     	; 0xfd82 <putch>
+    fda2:	27 d0       	rcall	.+78     	; 0xfdf2 <verifySpace>
+    fda4:	8e e1       	ldi	r24, 0x1E	; 30
+    fda6:	0c d0       	rcall	.+24     	; 0xfdc0 <putch>
       putch(SIGNATURE_1);
-    fd6a:	86 e9       	ldi	r24, 0x96	; 150
-    fd6c:	0a d0       	rcall	.+20     	; 0xfd82 <putch>
+    fda8:	86 e9       	ldi	r24, 0x96	; 150
+    fdaa:	0a d0       	rcall	.+20     	; 0xfdc0 <putch>
+    fdac:	8a e0       	ldi	r24, 0x0A	; 10
       putch(SIGNATURE_2);
-    fd6e:	8a e0       	ldi	r24, 0x0A	; 10
-    fd70:	84 cf       	rjmp	.-248    	; 0xfc7a <main+0x7a>
+    fdae:	6d cf       	rjmp	.-294    	; 0xfc8a <main+0x8a>
+    fdb0:	81 35       	cpi	r24, 0x51	; 81
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    fd72:	81 35       	cpi	r24, 0x51	; 81
-    fd74:	11 f4       	brne	.+4      	; 0xfd7a <main+0x17a>
+    fdb2:	11 f4       	brne	.+4      	; 0xfdb8 <main+0x1b8>
+    fdb4:	88 e0       	ldi	r24, 0x08	; 8
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    fd76:	88 e0       	ldi	r24, 0x08	; 8
-    fd78:	18 d0       	rcall	.+48     	; 0xfdaa <watchdogConfig>
+    fdb6:	17 d0       	rcall	.+46     	; 0xfde6 <watchdogConfig>
+    fdb8:	1c d0       	rcall	.+56     	; 0xfdf2 <verifySpace>
+    fdba:	80 e1       	ldi	r24, 0x10	; 16
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    fd7a:	1d d0       	rcall	.+58     	; 0xfdb6 <verifySpace>
+    fdbc:	01 d0       	rcall	.+2      	; 0xfdc0 <putch>
+    fdbe:	58 cf       	rjmp	.-336    	; 0xfc70 <main+0x70>
+
+0000fdc0 <putch>:
     }
     putch(STK_OK);
-    fd7c:	80 e1       	ldi	r24, 0x10	; 16
-    fd7e:	01 d0       	rcall	.+2      	; 0xfd82 <putch>
-    fd80:	6f cf       	rjmp	.-290    	; 0xfc60 <main+0x60>
-
-0000fd82 <putch>:
+    fdc0:	90 91 c0 00 	lds	r25, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    fdc4:	95 ff       	sbrs	r25, 5
   }
+    fdc6:	fc cf       	rjmp	.-8      	; 0xfdc0 <putch>
 }
 
 void putch(char ch) {
-    fd82:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    fd84:	80 91 c0 00 	lds	r24, 0x00C0
-    fd88:	85 ff       	sbrs	r24, 5
-    fd8a:	fc cf       	rjmp	.-8      	; 0xfd84 <putch+0x2>
   UART_UDR = ch;
-    fd8c:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-    fd90:	08 95       	ret
+    fdc8:	80 93 c6 00 	sts	0x00C6, r24	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+    fdcc:	08 95       	ret
 
-0000fd92 <getch>:
+0000fdce <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    fd92:	80 91 c0 00 	lds	r24, 0x00C0
-    fd96:	87 ff       	sbrs	r24, 7
-    fd98:	fc cf       	rjmp	.-8      	; 0xfd92 <getch>
+    fdce:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    fdd2:	87 ff       	sbrs	r24, 7
+    fdd4:	fc cf       	rjmp	.-8      	; 0xfdce <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    fd9a:	80 91 c0 00 	lds	r24, 0x00C0
-    fd9e:	84 fd       	sbrc	r24, 4
-    fda0:	01 c0       	rjmp	.+2      	; 0xfda4 <getch+0x12>
+    fdd6:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    fdda:	84 fd       	sbrc	r24, 4
+    fddc:	01 c0       	rjmp	.+2      	; 0xfde0 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    fda2:	a8 95       	wdr
+    fdde:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
-  
+
   ch = UART_UDR;
-    fda4:	80 91 c6 00 	lds	r24, 0x00C6
+    fde0:	80 91 c6 00 	lds	r24, 0x00C6	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    fda8:	08 95       	ret
+    fde4:	08 95       	ret
 
-0000fdaa <watchdogConfig>:
+0000fde6 <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
+    fde6:	e0 e6       	ldi	r30, 0x60	; 96
+    fde8:	f0 e0       	ldi	r31, 0x00	; 0
+    fdea:	98 e1       	ldi	r25, 0x18	; 24
+    fdec:	90 83       	st	Z, r25
   WDTCSR = x;
-    fdb2:	80 83       	st	Z, r24
-}
-    fdb4:	08 95       	ret
+    fdee:	80 83       	st	Z, r24
+    fdf0:	08 95       	ret
 
-0000fdb6 <verifySpace>:
+0000fdf2 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    fdb6:	ed df       	rcall	.-38     	; 0xfd92 <getch>
-    fdb8:	80 32       	cpi	r24, 0x20	; 32
-    fdba:	19 f0       	breq	.+6      	; 0xfdc2 <verifySpace+0xc>
+    fdf2:	ed df       	rcall	.-38     	; 0xfdce <getch>
+    fdf4:	80 32       	cpi	r24, 0x20	; 32
+    fdf6:	19 f0       	breq	.+6      	; 0xfdfe <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    fdbc:	88 e0       	ldi	r24, 0x08	; 8
-    fdbe:	f5 df       	rcall	.-22     	; 0xfdaa <watchdogConfig>
-    fdc0:	ff cf       	rjmp	.-2      	; 0xfdc0 <verifySpace+0xa>
+    fdf8:	88 e0       	ldi	r24, 0x08	; 8
+    fdfa:	f5 df       	rcall	.-22     	; 0xfde6 <watchdogConfig>
+    fdfc:	ff cf       	rjmp	.-2      	; 0xfdfc <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    fdc2:	84 e1       	ldi	r24, 0x14	; 20
-}
-    fdc4:	de cf       	rjmp	.-68     	; 0xfd82 <putch>
+    fdfe:	84 e1       	ldi	r24, 0x14	; 20
+    fe00:	df cf       	rjmp	.-66     	; 0xfdc0 <putch>
 
-0000fdc6 <getNch>:
+0000fe02 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    fdc6:	1f 93       	push	r17
-    fdc8:	18 2f       	mov	r17, r24
+    fe02:	cf 93       	push	r28
+    fe04:	c8 2f       	mov	r28, r24
   do getch(); while (--count);
-    fdca:	e3 df       	rcall	.-58     	; 0xfd92 <getch>
-    fdcc:	11 50       	subi	r17, 0x01	; 1
-    fdce:	e9 f7       	brne	.-6      	; 0xfdca <getNch+0x4>
+    fe06:	e3 df       	rcall	.-58     	; 0xfdce <getch>
+    fe08:	c1 50       	subi	r28, 0x01	; 1
+    fe0a:	e9 f7       	brne	.-6      	; 0xfe06 <getNch+0x4>
   verifySpace();
-    fdd0:	f2 df       	rcall	.-28     	; 0xfdb6 <verifySpace>
-}
-    fdd2:	1f 91       	pop	r17
-    fdd4:	08 95       	ret
+    fe0c:	cf 91       	pop	r28
+    fe0e:	f1 cf       	rjmp	.-30     	; 0xfdf2 <verifySpace>
 
-0000fdd6 <appStart>:
+0000fe10 <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    fdd6:	28 2e       	mov	r2, r24
+    fe10:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    fdd8:	80 e0       	ldi	r24, 0x00	; 0
-    fdda:	e7 df       	rcall	.-50     	; 0xfdaa <watchdogConfig>
+    fe12:	80 e0       	ldi	r24, 0x00	; 0
+    fe14:	e8 df       	rcall	.-48     	; 0xfde6 <watchdogConfig>
+    fe16:	e0 e0       	ldi	r30, 0x00	; 0
+  // Note that appstart_vec is defined so that this works with either
+  // real or virtual boot partitions.
   __asm__ __volatile__ (
-    fddc:	ee 27       	eor	r30, r30
-    fdde:	ff 27       	eor	r31, r31
-    fde0:	09 94       	ijmp
+    fe18:	ff 27       	eor	r31, r31
+    fe1a:	09 94       	ijmp
+
+0000fe1c <eeprom_read_byte>:
+    fe1c:	f9 99       	sbic	0x1f, 1	; 31
+    fe1e:	fe cf       	rjmp	.-4      	; 0xfe1c <eeprom_read_byte>
+    fe20:	92 bd       	out	0x22, r25	; 34
+    fe22:	81 bd       	out	0x21, r24	; 33
+    fe24:	f8 9a       	sbi	0x1f, 0	; 31
+    fe26:	99 27       	eor	r25, r25
+    fe28:	80 b5       	in	r24, 0x20	; 32
+    fe2a:	08 95       	ret
+
+0000fe2c <eeprom_write_byte>:
+    fe2c:	26 2f       	mov	r18, r22
+
+0000fe2e <eeprom_write_r18>:
+    fe2e:	f9 99       	sbic	0x1f, 1	; 31
+    fe30:	fe cf       	rjmp	.-4      	; 0xfe2e <eeprom_write_r18>
+    fe32:	1f ba       	out	0x1f, r1	; 31
+    fe34:	92 bd       	out	0x22, r25	; 34
+    fe36:	81 bd       	out	0x21, r24	; 33
+    fe38:	20 bd       	out	0x20, r18	; 32
+    fe3a:	0f b6       	in	r0, 0x3f	; 63
+    fe3c:	f8 94       	cli
+    fe3e:	fa 9a       	sbi	0x1f, 2	; 31
+    fe40:	f9 9a       	sbi	0x1f, 1	; 31
+    fe42:	0f be       	out	0x3f, r0	; 63
+    fe44:	01 96       	adiw	r24, 0x01	; 1
+    fe46:	08 95       	ret

+ 310 - 312
optiboot/bootloaders/optiboot/optiboot_diecimila.lst

@@ -3,584 +3,582 @@ optiboot_atmega168.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001d6  00003e00  00003e00  00000074  2**1
+  0 .data         00000000  00800100  00003fbe  00000252  2**0
+                  CONTENTS, ALLOC, LOAD, DATA
+  1 .text         000001be  00003e00  00003e00  00000094  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
+  2 .version      00000002  00003ffe  00003ffe  00000252  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
+  3 .comment      0000002f  00000000  00000000  00000254  2**0
+                  CONTENTS, READONLY
+  4 .debug_aranges 00000028  00000000  00000000  00000283  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
+  5 .debug_info   000005c8  00000000  00000000  000002ab  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
+  6 .debug_abbrev 00000282  00000000  00000000  00000873  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
+  7 .debug_line   000002f9  00000000  00000000  00000af5  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
+  8 .debug_frame  0000008c  00000000  00000000  00000df0  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
+  9 .debug_str    000001fa  00000000  00000000  00000e7c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
+ 10 .debug_loc    00000331  00000000  00000000  00001076  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
+ 11 .debug_ranges 00000060  00000000  00000000  000013a7  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00003e00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
+  //  SP points to RAMEND
+  //  r1 contains zero
+  //
+  // If not, uncomment the following instructions:
+  // cli();
+  asm volatile ("clr __zero_reg__");
     3e00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
+   * 
+   * Code by MarkG55
+   * see discusion in https://github.com/Optiboot/optiboot/issues/97
    */
+#if !defined(__AVR_ATmega16__)
   ch = MCUSR;
-    3e02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-    3e04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-    3e06:	89 2f       	mov	r24, r25
-    3e08:	8d 70       	andi	r24, 0x0D	; 13
-    3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
-      appStart(ch);
-    3e0c:	89 2f       	mov	r24, r25
-    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
+    3e02:	84 b7       	in	r24, 0x34	; 52
+#else
+  ch = MCUCSR;
+#endif
+  // Skip all logic and run bootloader if MCUSR is cleared (application request)
+  if (ch != 0) {
+    3e04:	88 23       	and	r24, r24
+    3e06:	49 f0       	breq	.+18     	; 0x3e1a <main+0x1a>
+       *  2. we clear WDRF if it's set with EXTRF to avoid loops
+       * One problematic scenario: broken application code sets watchdog timer 
+       * without clearing MCUSR before and triggers it quickly. But it's
+       * recoverable by power-on with pushed reset button.
+       */
+      if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) { 
+    3e08:	98 2f       	mov	r25, r24
+    3e0a:	9a 70       	andi	r25, 0x0A	; 10
+    3e0c:	92 30       	cpi	r25, 0x02	; 2
+    3e0e:	29 f0       	breq	.+10     	; 0x3e1a <main+0x1a>
+	  if (ch & _BV(EXTRF)) {
+    3e10:	81 ff       	sbrs	r24, 1
+    3e12:	02 c0       	rjmp	.+4      	; 0x3e18 <main+0x18>
+	       * prevent entering bootloader.
+	       * '&' operation is skipped to spare few bytes as bits in MCUSR
+	       * can only be cleared.
+	       */
+#if !defined(__AVR_ATmega16__)
+	      MCUSR = ~(_BV(WDRF));  
+    3e14:	97 ef       	ldi	r25, 0xF7	; 247
+    3e16:	94 bf       	out	0x34, r25	; 52
+#else
+	      MCUCSR = ~(_BV(WDRF));  
+#endif
+	  }
+	  appStart(ch);
+    3e18:	cc d0       	rcall	.+408    	; 0x3fb2 <appStart>
+      }
+  }
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
   TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    3e10:	85 e0       	ldi	r24, 0x05	; 5
-    3e12:	80 93 81 00 	sts	0x0081, r24
+    3e1a:	85 e0       	ldi	r24, 0x05	; 5
+    3e1c:	80 93 81 00 	sts	0x0081, r24	; 0x800081 <__TEXT_REGION_LENGTH__+0x7e0081>
   UCSRA = _BV(U2X); //Double speed mode USART
   UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
   UART_SRA = _BV(U2X0); //Double speed mode USART0
-    3e16:	82 e0       	ldi	r24, 0x02	; 2
-    3e18:	80 93 c0 00 	sts	0x00C0, r24
+    3e20:	82 e0       	ldi	r24, 0x02	; 2
+    3e22:	80 93 c0 00 	sts	0x00C0, r24	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-    3e1c:	88 e1       	ldi	r24, 0x18	; 24
-    3e1e:	80 93 c1 00 	sts	0x00C1, r24
+    3e26:	88 e1       	ldi	r24, 0x18	; 24
+    3e28:	80 93 c1 00 	sts	0x00C1, r24	; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7e00c1>
   UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-    3e22:	86 e0       	ldi	r24, 0x06	; 6
-    3e24:	80 93 c2 00 	sts	0x00C2, r24
+    3e2c:	86 e0       	ldi	r24, 0x06	; 6
+    3e2e:	80 93 c2 00 	sts	0x00C2, r24	; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7e00c2>
   UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-    3e28:	80 e1       	ldi	r24, 0x10	; 16
-    3e2a:	80 93 c4 00 	sts	0x00C4, r24
+    3e32:	80 e1       	ldi	r24, 0x10	; 16
+    3e34:	80 93 c4 00 	sts	0x00C4, r24	; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7e00c4>
 #endif
 #endif
 
-  // Set up watchdog to trigger after 500ms
+  // Set up watchdog to trigger after 1s
   watchdogConfig(WATCHDOG_1S);
-    3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
+    3e38:	8e e0       	ldi	r24, 0x0E	; 14
+    3e3a:	a6 d0       	rcall	.+332    	; 0x3f88 <watchdogConfig>
 
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
-    3e32:	25 9a       	sbi	0x04, 5	; 4
-    3e34:	86 e0       	ldi	r24, 0x06	; 6
+    3e3c:	25 9a       	sbi	0x04, 5	; 4
+    3e3e:	86 e0       	ldi	r24, 0x06	; 6
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-    3e36:	20 e3       	ldi	r18, 0x30	; 48
-    3e38:	3c ef       	ldi	r19, 0xFC	; 252
+    3e40:	20 e3       	ldi	r18, 0x30	; 48
+    3e42:	3c ef       	ldi	r19, 0xFC	; 252
     TIFR1 = _BV(TOV1);
-    3e3a:	91 e0       	ldi	r25, 0x01	; 1
+    3e44:	91 e0       	ldi	r25, 0x01	; 1
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-    3e3c:	30 93 85 00 	sts	0x0085, r19
-    3e40:	20 93 84 00 	sts	0x0084, r18
+    3e46:	30 93 85 00 	sts	0x0085, r19	; 0x800085 <__TEXT_REGION_LENGTH__+0x7e0085>
+    3e4a:	20 93 84 00 	sts	0x0084, r18	; 0x800084 <__TEXT_REGION_LENGTH__+0x7e0084>
     TIFR1 = _BV(TOV1);
-    3e44:	96 bb       	out	0x16, r25	; 22
+    3e4e:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
-    3e46:	b0 9b       	sbis	0x16, 0	; 22
-    3e48:	fe cf       	rjmp	.-4      	; 0x3e46 <main+0x46>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
+    3e50:	b0 9b       	sbis	0x16, 0	; 22
+    3e52:	fe cf       	rjmp	.-4      	; 0x3e50 <main+0x50>
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
     LED_PORT ^= _BV(LED);
 #else
     LED_PIN |= _BV(LED);
-    3e4a:	1d 9a       	sbi	0x03, 5	; 3
+    3e54:	1d 9a       	sbi	0x03, 5	; 3
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3e4c:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
+    3e56:	a8 95       	wdr
+     * While in theory, the STK500 initial commands would be buffered
+     *  by the UART hardware, avrdude sends several attempts in rather
+     *  quick succession, some of which will be lost and cause us to
+     *  get out of sync.  So if we see any data; stop blinking.
+     */
+    if (UART_SRA & _BV(RXC0))
+    3e58:	40 91 c0 00 	lds	r20, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    3e5c:	47 fd       	sbrc	r20, 7
+    3e5e:	02 c0       	rjmp	.+4      	; 0x3e64 <main+0x64>
+    3e60:	81 50       	subi	r24, 0x01	; 1
 #else
-    LED_PIN |= _BV(LED);
+// This doesn't seem to work?
+//    if ((UART_PIN & (1<<UART_RX_BIT)) == 0)
+//	break;  // detect start bit on soft uart too.
 #endif
-    watchdogReset();
   } while (--count);
-    3e4e:	81 50       	subi	r24, 0x01	; 1
-    3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	ee 24       	eor	r14, r14
-    3e54:	ff 24       	eor	r15, r15
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	b3 e0       	ldi	r27, 0x03	; 3
-    3e58:	ab 2e       	mov	r10, r27
+    3e62:	89 f7       	brne	.-30     	; 0x3e46 <main+0x46>
+
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	bb 24       	eor	r11, r11
-    3e5c:	b3 94       	inc	r11
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    3e64:	ee 24       	eor	r14, r14
+    3e66:	e3 94       	inc	r14
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e60:	da 2e       	mov	r13, r26
+	    __boot_page_write_short(address.word);
+    3e68:	95 e0       	ldi	r25, 0x05	; 5
+    3e6a:	d9 2e       	mov	r13, r25
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
-	    boot_rww_enable();
-    3e62:	f1 e1       	ldi	r31, 0x11	; 17
-    3e64:	cf 2e       	mov	r12, r31
+	    __boot_rww_enable_short();
+    3e6c:	21 e1       	ldi	r18, 0x11	; 17
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
+    3e6e:	c2 2e       	mov	r12, r18
 
     if(ch == STK_GET_PARAMETER) {
-    3e68:	81 34       	cpi	r24, 0x41	; 65
-    3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
+    3e70:	7f d0       	rcall	.+254    	; 0x3f70 <getch>
       unsigned char which = getch();
-    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
-    3e6e:	08 2f       	mov	r16, r24
+    3e72:	81 34       	cpi	r24, 0x41	; 65
+    3e74:	61 f4       	brne	.+24     	; 0x3e8e <main+0x8e>
+    3e76:	7c d0       	rcall	.+248    	; 0x3f70 <getch>
       verifySpace();
-    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
+    3e78:	18 2f       	mov	r17, r24
+    3e7a:	8c d0       	rcall	.+280    	; 0x3f94 <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
-      if (which == 0x82) {
-    3e72:	02 38       	cpi	r16, 0x82	; 130
-    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
+      if (which == STK_SW_MINOR) {
+    3e7c:	12 38       	cpi	r17, 0x82	; 130
+    3e7e:	e9 f0       	breq	.+58     	; 0x3eba <main+0xba>
 	  putch(optiboot_version & 0xFF);
-    3e76:	82 e0       	ldi	r24, 0x02	; 2
-    3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
-      } else if (which == 0x81) {
-    3e7a:	01 38       	cpi	r16, 0x81	; 129
-    3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
+      } else if (which == STK_SW_MAJOR) {
+    3e80:	11 38       	cpi	r17, 0x81	; 129
+	  putch(optiboot_version >> 8);
+    3e82:	11 f4       	brne	.+4      	; 0x3e88 <main+0x88>
+    3e84:	87 e0       	ldi	r24, 0x07	; 7
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
-    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
+    3e86:	01 c0       	rjmp	.+2      	; 0x3e8a <main+0x8a>
+    3e88:	83 e0       	ldi	r24, 0x03	; 3
+    3e8a:	6b d0       	rcall	.+214    	; 0x3f62 <putch>
+    3e8c:	67 c0       	rjmp	.+206    	; 0x3f5c <main+0x15c>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    3e86:	82 34       	cpi	r24, 0x42	; 66
-    3e88:	11 f4       	brne	.+4      	; 0x3e8e <main+0x8e>
+    3e8e:	82 34       	cpi	r24, 0x42	; 66
       // SET DEVICE is ignored
       getNch(20);
-    3e8a:	84 e1       	ldi	r24, 0x14	; 20
-    3e8c:	03 c0       	rjmp	.+6      	; 0x3e94 <main+0x94>
+    3e90:	11 f4       	brne	.+4      	; 0x3e96 <main+0x96>
+    3e92:	84 e1       	ldi	r24, 0x14	; 20
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e8e:	85 34       	cpi	r24, 0x45	; 69
-    3e90:	19 f4       	brne	.+6      	; 0x3e98 <main+0x98>
+    3e94:	03 c0       	rjmp	.+6      	; 0x3e9c <main+0x9c>
       // SET DEVICE EXT is ignored
       getNch(5);
-    3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
-    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
+    3e96:	85 34       	cpi	r24, 0x45	; 69
+    3e98:	19 f4       	brne	.+6      	; 0x3ea0 <main+0xa0>
+    3e9a:	85 e0       	ldi	r24, 0x05	; 5
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    3e98:	85 35       	cpi	r24, 0x55	; 85
-    3e9a:	79 f4       	brne	.+30     	; 0x3eba <main+0xba>
+    3e9c:	83 d0       	rcall	.+262    	; 0x3fa4 <getNch>
+    3e9e:	5e c0       	rjmp	.+188    	; 0x3f5c <main+0x15c>
       // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e9e:	e8 2e       	mov	r14, r24
-    3ea0:	ff 24       	eor	r15, r15
-    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
-    3ea4:	08 2f       	mov	r16, r24
-    3ea6:	10 e0       	ldi	r17, 0x00	; 0
-    3ea8:	10 2f       	mov	r17, r16
-    3eaa:	00 27       	eor	r16, r16
-    3eac:	0e 29       	or	r16, r14
-    3eae:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
+      address.bytes[0] = getch();
+    3ea0:	85 35       	cpi	r24, 0x55	; 85
+    3ea2:	39 f4       	brne	.+14     	; 0x3eb2 <main+0xb2>
+    3ea4:	65 d0       	rcall	.+202    	; 0x3f70 <getch>
+      address.bytes[1] = getch();
+    3ea6:	c8 2f       	mov	r28, r24
+    3ea8:	63 d0       	rcall	.+198    	; 0x3f70 <getch>
+      }
+      else {
+        RAMPZ &= 0xFE;
+      }
 #endif
-      newAddress += newAddress; // Convert from word address to byte address
-    3eb0:	00 0f       	add	r16, r16
-    3eb2:	11 1f       	adc	r17, r17
-      address = newAddress;
+      address.word *= 2; // Convert from word address to byte address
+    3eaa:	d8 2f       	mov	r29, r24
+    3eac:	cc 0f       	add	r28, r28
+    3eae:	dd 1f       	adc	r29, r29
       verifySpace();
-    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
-    3eb6:	78 01       	movw	r14, r16
-    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_UNIVERSAL) {
-    3eba:	86 35       	cpi	r24, 0x56	; 86
-    3ebc:	21 f4       	brne	.+8      	; 0x3ec6 <main+0xc6>
+    3eb0:	54 c0       	rjmp	.+168    	; 0x3f5a <main+0x15a>
+        getNch(3);
+        putch(0x00);
+      }
+#else
       // UNIVERSAL command is ignored
       getNch(4);
-    3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
+    3eb2:	86 35       	cpi	r24, 0x56	; 86
+    3eb4:	21 f4       	brne	.+8      	; 0x3ebe <main+0xbe>
       putch(0x00);
-    3ec2:	80 e0       	ldi	r24, 0x00	; 0
-    3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
+    3eb6:	84 e0       	ldi	r24, 0x04	; 4
+    3eb8:	75 d0       	rcall	.+234    	; 0x3fa4 <getNch>
+#endif
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    3ec6:	84 36       	cpi	r24, 0x64	; 100
-    3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
+    3eba:	80 e0       	ldi	r24, 0x00	; 0
+    3ebc:	e6 cf       	rjmp	.-52     	; 0x3e8a <main+0x8a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
       pagelen_t savelength;
 
       GETLENGTH(length);
-    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
-    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
-    3ed0:	18 2f       	mov	r17, r24
+    3ebe:	84 36       	cpi	r24, 0x64	; 100
+    3ec0:	09 f0       	breq	.+2      	; 0x3ec4 <main+0xc4>
+    3ec2:	2e c0       	rjmp	.+92     	; 0x3f20 <main+0x120>
+    3ec4:	55 d0       	rcall	.+170    	; 0x3f70 <getch>
       savelength = length;
       desttype = getch();
-    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
-    3ed4:	08 2f       	mov	r16, r24
-    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
-    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
+    3ec6:	54 d0       	rcall	.+168    	; 0x3f70 <getch>
+    3ec8:	f8 2e       	mov	r15, r24
+    3eca:	52 d0       	rcall	.+164    	; 0x3f70 <getch>
+    3ecc:	b8 2e       	mov	r11, r24
+    3ece:	00 e0       	ldi	r16, 0x00	; 0
 
       // read a page worth of contents
-      bufPtr = buff;
+      bufPtr = buff.bptr;
       do *bufPtr++ = getch();
-    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
-    3edc:	89 93       	st	Y+, r24
+    3ed0:	11 e0       	ldi	r17, 0x01	; 1
+    3ed2:	4e d0       	rcall	.+156    	; 0x3f70 <getch>
+    3ed4:	f8 01       	movw	r30, r16
+    3ed6:	81 93       	st	Z+, r24
+    3ed8:	8f 01       	movw	r16, r30
       while (--length);
-    3ede:	1c 17       	cp	r17, r28
-    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
+    3eda:	fe 12       	cpse	r15, r30
+    3edc:	fa cf       	rjmp	.-12     	; 0x3ed2 <main+0xd2>
 
       // Read command terminator, start reply
       verifySpace();
-    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
+    3ede:	5a d0       	rcall	.+180    	; 0x3f94 <verifySpace>
+    3ee0:	f5 e4       	ldi	r31, 0x45	; 69
  * void writebuffer(memtype, buffer, address, length)
  */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+			       addr16_t address, pagelen_t len)
 {
     switch (memtype) {
-    3ee4:	05 34       	cpi	r16, 0x45	; 69
-    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
-    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
+    3ee2:	bf 12       	cpse	r11, r31
+    3ee4:	01 c0       	rjmp	.+2      	; 0x3ee8 <main+0xe8>
+    3ee6:	ff cf       	rjmp	.-2      	; 0x3ee6 <main+0xe6>
+    3ee8:	83 e0       	ldi	r24, 0x03	; 3
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	a7 be       	out	0x37, r10	; 55
+	    __boot_page_erase_short(address.word);
+    3eea:	fe 01       	movw	r30, r28
+    3eec:	87 bf       	out	0x37, r24	; 55
     3eee:	e8 95       	spm
-	    boot_spm_busy_wait();
     3ef0:	07 b6       	in	r0, 0x37	; 55
+	    boot_spm_busy_wait();
     3ef2:	00 fc       	sbrc	r0, 0
     3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
-    3ef6:	a7 01       	movw	r20, r14
-    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
-    3efa:	b1 e0       	ldi	r27, 0x01	; 1
+    3ef6:	a0 e0       	ldi	r26, 0x00	; 0
+    3ef8:	b1 e0       	ldi	r27, 0x01	; 1
+    3efa:	fe 01       	movw	r30, r28
+    3efc:	8d 91       	ld	r24, X+
+
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-    3efc:	2c 91       	ld	r18, X
-    3efe:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-    3f00:	11 96       	adiw	r26, 0x01	; 1
-    3f02:	8c 91       	ld	r24, X
-    3f04:	11 97       	sbiw	r26, 0x01	; 1
-    3f06:	90 e0       	ldi	r25, 0x00	; 0
-    3f08:	98 2f       	mov	r25, r24
-    3f0a:	88 27       	eor	r24, r24
-    3f0c:	82 2b       	or	r24, r18
-    3f0e:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    3f10:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f12:	fa 01       	movw	r30, r20
-    3f14:	0c 01       	movw	r0, r24
-    3f16:	b7 be       	out	0x37, r11	; 55
-    3f18:	e8 95       	spm
-    3f1a:	11 24       	eor	r1, r1
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    3efe:	9d 91       	ld	r25, X+
+    3f00:	0c 01       	movw	r0, r24
+    3f02:	e7 be       	out	0x37, r14	; 55
+    3f04:	e8 95       	spm
+    3f06:	11 24       	eor	r1, r1
+    3f08:	32 96       	adiw	r30, 0x02	; 2
 		addrPtr += 2;
-    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
-    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    3f20:	1a 17       	cp	r17, r26
-    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
+    3f0a:	fa 12       	cpse	r15, r26
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3f24:	f7 01       	movw	r30, r14
-    3f26:	d7 be       	out	0x37, r13	; 55
-    3f28:	e8 95       	spm
+	    __boot_page_write_short(address.word);
+    3f0c:	f7 cf       	rjmp	.-18     	; 0x3efc <main+0xfc>
+    3f0e:	fe 01       	movw	r30, r28
 	    boot_spm_busy_wait();
-    3f2a:	07 b6       	in	r0, 0x37	; 55
-    3f2c:	00 fc       	sbrc	r0, 0
-    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
+    3f10:	d7 be       	out	0x37, r13	; 55
+    3f12:	e8 95       	spm
 #if defined(RWWSRE)
 	    // Reenable read access to flash
-	    boot_rww_enable();
-    3f30:	c7 be       	out	0x37, r12	; 55
-    3f32:	e8 95       	spm
-    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
+	    __boot_rww_enable_short();
+    3f14:	07 b6       	in	r0, 0x37	; 55
+    3f16:	00 fc       	sbrc	r0, 0
+    3f18:	fd cf       	rjmp	.-6      	; 0x3f14 <main+0x114>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f36:	84 37       	cpi	r24, 0x74	; 116
-    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
+    3f1a:	c7 be       	out	0x37, r12	; 55
+    3f1c:	e8 95       	spm
       uint8_t desttype;
       GETLENGTH(length);
-    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
-    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
-    3f3e:	08 2f       	mov	r16, r24
+    3f1e:	1e c0       	rjmp	.+60     	; 0x3f5c <main+0x15c>
+    3f20:	84 37       	cpi	r24, 0x74	; 116
+    3f22:	71 f4       	brne	.+28     	; 0x3f40 <main+0x140>
 
       desttype = getch();
-    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
+    3f24:	25 d0       	rcall	.+74     	; 0x3f70 <getch>
 
       verifySpace();
-    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
-    3f44:	e7 01       	movw	r28, r14
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+    3f26:	24 d0       	rcall	.+72     	; 0x3f70 <getch>
+    3f28:	f8 2e       	mov	r15, r24
+    3f2a:	22 d0       	rcall	.+68     	; 0x3f70 <getch>
+	    //      while (--length);
+	    // read a Flash and increment the address (may increment RAMPZ)
+	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
 #else
 	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+    3f2c:	33 d0       	rcall	.+102    	; 0x3f94 <verifySpace>
+    3f2e:	8e 01       	movw	r16, r28
 #endif
 	    putch(ch);
-    3f46:	fe 01       	movw	r30, r28
-    3f48:	85 91       	lpm	r24, Z+
-    3f4a:	ef 01       	movw	r28, r30
-    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
+    3f30:	f8 01       	movw	r30, r16
 	} while (--length);
-    3f4e:	01 50       	subi	r16, 0x01	; 1
-    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
-    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
-	  
+    3f32:	85 91       	lpm	r24, Z+
+    3f34:	8f 01       	movw	r16, r30
+    3f36:	15 d0       	rcall	.+42     	; 0x3f62 <putch>
+    3f38:	fa 94       	dec	r15
+
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f54:	85 37       	cpi	r24, 0x75	; 117
-    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
+    3f3a:	f1 10       	cpse	r15, r1
+    3f3c:	f9 cf       	rjmp	.-14     	; 0x3f30 <main+0x130>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
+    3f3e:	0e c0       	rjmp	.+28     	; 0x3f5c <main+0x15c>
+    3f40:	85 37       	cpi	r24, 0x75	; 117
       putch(SIGNATURE_0);
-    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
+    3f42:	39 f4       	brne	.+14     	; 0x3f52 <main+0x152>
+    3f44:	27 d0       	rcall	.+78     	; 0x3f94 <verifySpace>
+    3f46:	8e e1       	ldi	r24, 0x1E	; 30
       putch(SIGNATURE_1);
-    3f5e:	84 e9       	ldi	r24, 0x94	; 148
-    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
+    3f48:	0c d0       	rcall	.+24     	; 0x3f62 <putch>
+    3f4a:	84 e9       	ldi	r24, 0x94	; 148
+    3f4c:	0a d0       	rcall	.+20     	; 0x3f62 <putch>
       putch(SIGNATURE_2);
-    3f62:	86 e0       	ldi	r24, 0x06	; 6
-    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
+    3f4e:	86 e0       	ldi	r24, 0x06	; 6
+    3f50:	9c cf       	rjmp	.-200    	; 0x3e8a <main+0x8a>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f66:	81 35       	cpi	r24, 0x51	; 81
-    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
+    3f52:	81 35       	cpi	r24, 0x51	; 81
+    3f54:	11 f4       	brne	.+4      	; 0x3f5a <main+0x15a>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f6a:	88 e0       	ldi	r24, 0x08	; 8
-    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
+    3f56:	88 e0       	ldi	r24, 0x08	; 8
+    3f58:	17 d0       	rcall	.+46     	; 0x3f88 <watchdogConfig>
+    3f5a:	1c d0       	rcall	.+56     	; 0x3f94 <verifySpace>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
+    3f5c:	80 e1       	ldi	r24, 0x10	; 16
+    3f5e:	01 d0       	rcall	.+2      	; 0x3f62 <putch>
     }
     putch(STK_OK);
-    3f70:	80 e1       	ldi	r24, 0x10	; 16
-    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
-    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
+    3f60:	87 cf       	rjmp	.-242    	; 0x3e70 <main+0x70>
 
-00003f76 <putch>:
+00003f62 <putch>:
+    3f62:	90 91 c0 00 	lds	r25, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   }
+    3f66:	95 ff       	sbrs	r25, 5
 }
 
 void putch(char ch) {
-    3f76:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    3f78:	80 91 c0 00 	lds	r24, 0x00C0
-    3f7c:	85 ff       	sbrs	r24, 5
-    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
+    3f68:	fc cf       	rjmp	.-8      	; 0x3f62 <putch>
   UART_UDR = ch;
-    3f80:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-    3f84:	08 95       	ret
+    3f6a:	80 93 c6 00 	sts	0x00C6, r24	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+    3f6e:	08 95       	ret
 
-00003f86 <getch>:
+00003f70 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    3f86:	80 91 c0 00 	lds	r24, 0x00C0
-    3f8a:	87 ff       	sbrs	r24, 7
-    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
+    3f70:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    3f74:	87 ff       	sbrs	r24, 7
+    3f76:	fc cf       	rjmp	.-8      	; 0x3f70 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
-    3f92:	84 fd       	sbrc	r24, 4
-    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
+    3f78:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    3f7c:	84 fd       	sbrc	r24, 4
+    3f7e:	01 c0       	rjmp	.+2      	; 0x3f82 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3f96:	a8 95       	wdr
+    3f80:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
-  
+
   ch = UART_UDR;
-    3f98:	80 91 c6 00 	lds	r24, 0x00C6
+    3f82:	80 91 c6 00 	lds	r24, 0x00C6	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3f9c:	08 95       	ret
+    3f86:	08 95       	ret
 
-00003f9e <watchdogConfig>:
+00003f88 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
-    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fa2:	98 e1       	ldi	r25, 0x18	; 24
-    3fa4:	90 83       	st	Z, r25
+    3f88:	e0 e6       	ldi	r30, 0x60	; 96
+    3f8a:	f0 e0       	ldi	r31, 0x00	; 0
+    3f8c:	98 e1       	ldi	r25, 0x18	; 24
+    3f8e:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fa6:	80 83       	st	Z, r24
-}
-    3fa8:	08 95       	ret
+    3f90:	80 83       	st	Z, r24
+    3f92:	08 95       	ret
 
-00003faa <verifySpace>:
+00003f94 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
-    3fac:	80 32       	cpi	r24, 0x20	; 32
-    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
+    3f94:	ed df       	rcall	.-38     	; 0x3f70 <getch>
+    3f96:	80 32       	cpi	r24, 0x20	; 32
+    3f98:	19 f0       	breq	.+6      	; 0x3fa0 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fb0:	88 e0       	ldi	r24, 0x08	; 8
-    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
-    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
+    3f9a:	88 e0       	ldi	r24, 0x08	; 8
+    3f9c:	f5 df       	rcall	.-22     	; 0x3f88 <watchdogConfig>
+    3f9e:	ff cf       	rjmp	.-2      	; 0x3f9e <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fb6:	84 e1       	ldi	r24, 0x14	; 20
-}
-    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
+    3fa0:	84 e1       	ldi	r24, 0x14	; 20
+    3fa2:	df cf       	rjmp	.-66     	; 0x3f62 <putch>
 
-00003fba <getNch>:
+00003fa4 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fba:	1f 93       	push	r17
-    3fbc:	18 2f       	mov	r17, r24
+    3fa4:	cf 93       	push	r28
+    3fa6:	c8 2f       	mov	r28, r24
   do getch(); while (--count);
-    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
-    3fc0:	11 50       	subi	r17, 0x01	; 1
-    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
+    3fa8:	e3 df       	rcall	.-58     	; 0x3f70 <getch>
+    3faa:	c1 50       	subi	r28, 0x01	; 1
+    3fac:	e9 f7       	brne	.-6      	; 0x3fa8 <getNch+0x4>
   verifySpace();
-    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
-}
-    3fc6:	1f 91       	pop	r17
-    3fc8:	08 95       	ret
+    3fae:	cf 91       	pop	r28
+    3fb0:	f1 cf       	rjmp	.-30     	; 0x3f94 <verifySpace>
 
-00003fca <appStart>:
+00003fb2 <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fca:	28 2e       	mov	r2, r24
+    3fb2:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    3fcc:	80 e0       	ldi	r24, 0x00	; 0
-    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
+    3fb4:	80 e0       	ldi	r24, 0x00	; 0
+    3fb6:	e8 df       	rcall	.-48     	; 0x3f88 <watchdogConfig>
+    3fb8:	e0 e0       	ldi	r30, 0x00	; 0
+  // Note that appstart_vec is defined so that this works with either
+  // real or virtual boot partitions.
   __asm__ __volatile__ (
-    3fd0:	ee 27       	eor	r30, r30
-    3fd2:	ff 27       	eor	r31, r31
-    3fd4:	09 94       	ijmp
+    3fba:	ff 27       	eor	r31, r31
+    3fbc:	09 94       	ijmp

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

@@ -1,33 +1,31 @@
-:103E0000112494B714BE892F8D7011F0892FDDD045
-:103E100085E08093810082E08093C00088E18093F8
-:103E2000C10086E08093C20088E08093C4008EE0E9
-:103E3000B6D0259A86E028E13EEF91E030938500E8
-:103E40002093840096BBB09BFECF1D9AA89581500D
-:103E5000A9F7EE24FF24B3E0AB2EBB24B394A5E076
-:103E6000DA2EF1E1CF2E8FD0813469F48CD0082F77
-:103E70009CD0023811F482E004C0013809F471C00A
-:103E800083E079D075C0823411F484E103C08534B5
-:103E900019F485E092D06CC0853579F474D0E82EA1
-:103EA000FF2471D0082F10E0102F00270E291F29A2
-:103EB000000F111F7AD078015BC0863521F484E0B1
-:103EC0007CD080E0DECF843609F035C05CD05BD09A
-:103ED000182F59D0082FC0E0D1E055D089931C1776
-:103EE000E1F763D0053409F4FFCFF701A7BEE895E9
-:103EF00007B600FCFDCFA701A0E0B1E02C9130E0B7
-:103F000011968C91119790E0982F8827822B932BF4
-:103F10001296FA010C01B7BEE89511244E5F5F4F6F
-:103F20001A1761F7F701D7BEE89507B600FCFDCF79
-:103F3000C7BEE8951DC0843769F425D024D0082F6A
-:103F400022D033D0E701FE018591EF0114D001505A
-:103F5000D1F70EC0853739F428D08EE10CD084E932
-:103F60000AD086E08ECF813511F488E018D01DD0BC
-:103F700080E101D078CF982F8091C00085FFFCCFE1
-:103F80009093C60008958091C00087FFFCCF809178
-:103F9000C00084FD01C0A8958091C6000895E0E6A8
-:103FA000F0E098E1908380830895EDDF803219F08E
-:103FB00088E0F5DFFFCF84E1DECF1F93182FE3DF2A
-:103FC0001150E9F7F2DF1F910895282E80E0E7DF16
-:063FD000EE27FF27099413
-:023FFE000206B9
+:103E0000112484B7882349F0982F9A70923029F0B2
+:103E100081FF02C097EF94BFCCD085E080938100F2
+:103E200082E08093C00088E18093C10086E08093A7
+:103E3000C20088E08093C4008EE0A6D0259A86E078
+:103E400028E13EEF91E0309385002093840096BBFB
+:103E5000B09BFECF1D9AA8954091C00047FD02C0BF
+:103E6000815089F7EE24E39495E0D92E21E1C22E0A
+:103E70007FD0813461F47CD0182F8CD01238E9F0D7
+:103E8000113811F487E001C083E06BD067C0823441
+:103E900011F484E103C0853419F485E083D05EC059
+:103EA000853539F465D0C82F63D0D82FCC0FDD1FEE
+:103EB00054C0863521F484E075D080E0E6CF8436A6
+:103EC00009F02EC055D054D0F82E52D0B82E00E0B4
+:103ED00011E04ED0F80181938F01FE12FACF5AD033
+:103EE000F5E4BF1201C0FFCF83E0FE0187BFE89574
+:103EF00007B600FCFDCFA0E0B1E0FE018D919D91E1
+:103F00000C01E7BEE89511243296FA12F7CFFE01B4
+:103F1000D7BEE89507B600FCFDCFC7BEE8951EC02A
+:103F2000843771F425D024D0F82E22D033D08E01DE
+:103F3000F80185918F0115D0FA94F110F9CF0EC0D8
+:103F4000853739F427D08EE10CD084E90AD086E099
+:103F50009CCF813511F488E017D01CD080E101D0CE
+:103F600087CF9091C00095FFFCCF8093C600089545
+:103F70008091C00087FFFCCF8091C00084FD01C00C
+:103F8000A8958091C6000895E0E6F0E098E190835E
+:103F900080830895EDDF803219F088E0F5DFFFCFF0
+:103FA00084E1DFCFCF93C82FE3DFC150E9F7CF9192
+:0E3FB000F1CF282E80E0E8DFE0E0FF27099443
+:023FFE000007BA
 :0400000300003E00BB
 :00000001FF

+ 310 - 312
optiboot/bootloaders/optiboot/optiboot_lilypad.lst

@@ -3,584 +3,582 @@ optiboot_atmega168.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001d6  00003e00  00003e00  00000074  2**1
+  0 .data         00000000  00800100  00003fbe  00000252  2**0
+                  CONTENTS, ALLOC, LOAD, DATA
+  1 .text         000001be  00003e00  00003e00  00000094  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
+  2 .version      00000002  00003ffe  00003ffe  00000252  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
+  3 .comment      0000002f  00000000  00000000  00000254  2**0
+                  CONTENTS, READONLY
+  4 .debug_aranges 00000028  00000000  00000000  00000283  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
+  5 .debug_info   000005c8  00000000  00000000  000002ab  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
+  6 .debug_abbrev 00000282  00000000  00000000  00000873  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
+  7 .debug_line   000002f9  00000000  00000000  00000af5  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
+  8 .debug_frame  0000008c  00000000  00000000  00000df0  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
+  9 .debug_str    000001fa  00000000  00000000  00000e7c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
+ 10 .debug_loc    00000331  00000000  00000000  00001076  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
+ 11 .debug_ranges 00000060  00000000  00000000  000013a7  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00003e00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
+  //  SP points to RAMEND
+  //  r1 contains zero
+  //
+  // If not, uncomment the following instructions:
+  // cli();
+  asm volatile ("clr __zero_reg__");
     3e00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
+   * 
+   * Code by MarkG55
+   * see discusion in https://github.com/Optiboot/optiboot/issues/97
    */
+#if !defined(__AVR_ATmega16__)
   ch = MCUSR;
-    3e02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-    3e04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-    3e06:	89 2f       	mov	r24, r25
-    3e08:	8d 70       	andi	r24, 0x0D	; 13
-    3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
-      appStart(ch);
-    3e0c:	89 2f       	mov	r24, r25
-    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
+    3e02:	84 b7       	in	r24, 0x34	; 52
+#else
+  ch = MCUCSR;
+#endif
+  // Skip all logic and run bootloader if MCUSR is cleared (application request)
+  if (ch != 0) {
+    3e04:	88 23       	and	r24, r24
+    3e06:	49 f0       	breq	.+18     	; 0x3e1a <main+0x1a>
+       *  2. we clear WDRF if it's set with EXTRF to avoid loops
+       * One problematic scenario: broken application code sets watchdog timer 
+       * without clearing MCUSR before and triggers it quickly. But it's
+       * recoverable by power-on with pushed reset button.
+       */
+      if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) { 
+    3e08:	98 2f       	mov	r25, r24
+    3e0a:	9a 70       	andi	r25, 0x0A	; 10
+    3e0c:	92 30       	cpi	r25, 0x02	; 2
+    3e0e:	29 f0       	breq	.+10     	; 0x3e1a <main+0x1a>
+	  if (ch & _BV(EXTRF)) {
+    3e10:	81 ff       	sbrs	r24, 1
+    3e12:	02 c0       	rjmp	.+4      	; 0x3e18 <main+0x18>
+	       * prevent entering bootloader.
+	       * '&' operation is skipped to spare few bytes as bits in MCUSR
+	       * can only be cleared.
+	       */
+#if !defined(__AVR_ATmega16__)
+	      MCUSR = ~(_BV(WDRF));  
+    3e14:	97 ef       	ldi	r25, 0xF7	; 247
+    3e16:	94 bf       	out	0x34, r25	; 52
+#else
+	      MCUCSR = ~(_BV(WDRF));  
+#endif
+	  }
+	  appStart(ch);
+    3e18:	cc d0       	rcall	.+408    	; 0x3fb2 <appStart>
+      }
+  }
 
 #if LED_START_FLASHES > 0
   // Set up Timer 1 for timeout counter
   TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    3e10:	85 e0       	ldi	r24, 0x05	; 5
-    3e12:	80 93 81 00 	sts	0x0081, r24
+    3e1a:	85 e0       	ldi	r24, 0x05	; 5
+    3e1c:	80 93 81 00 	sts	0x0081, r24	; 0x800081 <__TEXT_REGION_LENGTH__+0x7e0081>
   UCSRA = _BV(U2X); //Double speed mode USART
   UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
   UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
   UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #else
   UART_SRA = _BV(U2X0); //Double speed mode USART0
-    3e16:	82 e0       	ldi	r24, 0x02	; 2
-    3e18:	80 93 c0 00 	sts	0x00C0, r24
+    3e20:	82 e0       	ldi	r24, 0x02	; 2
+    3e22:	80 93 c0 00 	sts	0x00C0, r24	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-    3e1c:	88 e1       	ldi	r24, 0x18	; 24
-    3e1e:	80 93 c1 00 	sts	0x00C1, r24
+    3e26:	88 e1       	ldi	r24, 0x18	; 24
+    3e28:	80 93 c1 00 	sts	0x00C1, r24	; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7e00c1>
   UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-    3e22:	86 e0       	ldi	r24, 0x06	; 6
-    3e24:	80 93 c2 00 	sts	0x00C2, r24
+    3e2c:	86 e0       	ldi	r24, 0x06	; 6
+    3e2e:	80 93 c2 00 	sts	0x00C2, r24	; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7e00c2>
   UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-    3e28:	88 e0       	ldi	r24, 0x08	; 8
-    3e2a:	80 93 c4 00 	sts	0x00C4, r24
+    3e32:	88 e0       	ldi	r24, 0x08	; 8
+    3e34:	80 93 c4 00 	sts	0x00C4, r24	; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7e00c4>
 #endif
 #endif
 
-  // Set up watchdog to trigger after 500ms
+  // Set up watchdog to trigger after 1s
   watchdogConfig(WATCHDOG_1S);
-    3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
+    3e38:	8e e0       	ldi	r24, 0x0E	; 14
+    3e3a:	a6 d0       	rcall	.+332    	; 0x3f88 <watchdogConfig>
 
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
-    3e32:	25 9a       	sbi	0x04, 5	; 4
-    3e34:	86 e0       	ldi	r24, 0x06	; 6
+    3e3c:	25 9a       	sbi	0x04, 5	; 4
+    3e3e:	86 e0       	ldi	r24, 0x06	; 6
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-    3e36:	28 e1       	ldi	r18, 0x18	; 24
-    3e38:	3e ef       	ldi	r19, 0xFE	; 254
+    3e40:	28 e1       	ldi	r18, 0x18	; 24
+    3e42:	3e ef       	ldi	r19, 0xFE	; 254
     TIFR1 = _BV(TOV1);
-    3e3a:	91 e0       	ldi	r25, 0x01	; 1
+    3e44:	91 e0       	ldi	r25, 0x01	; 1
 }
 
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
   do {
     TCNT1 = -(F_CPU/(1024*16));
-    3e3c:	30 93 85 00 	sts	0x0085, r19
-    3e40:	20 93 84 00 	sts	0x0084, r18
+    3e46:	30 93 85 00 	sts	0x0085, r19	; 0x800085 <__TEXT_REGION_LENGTH__+0x7e0085>
+    3e4a:	20 93 84 00 	sts	0x0084, r18	; 0x800084 <__TEXT_REGION_LENGTH__+0x7e0084>
     TIFR1 = _BV(TOV1);
-    3e44:	96 bb       	out	0x16, r25	; 22
+    3e4e:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
-    3e46:	b0 9b       	sbis	0x16, 0	; 22
-    3e48:	fe cf       	rjmp	.-4      	; 0x3e46 <main+0x46>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
+    3e50:	b0 9b       	sbis	0x16, 0	; 22
+    3e52:	fe cf       	rjmp	.-4      	; 0x3e50 <main+0x50>
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
     LED_PORT ^= _BV(LED);
 #else
     LED_PIN |= _BV(LED);
-    3e4a:	1d 9a       	sbi	0x03, 5	; 3
+    3e54:	1d 9a       	sbi	0x03, 5	; 3
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3e4c:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
+    3e56:	a8 95       	wdr
+     * While in theory, the STK500 initial commands would be buffered
+     *  by the UART hardware, avrdude sends several attempts in rather
+     *  quick succession, some of which will be lost and cause us to
+     *  get out of sync.  So if we see any data; stop blinking.
+     */
+    if (UART_SRA & _BV(RXC0))
+    3e58:	40 91 c0 00 	lds	r20, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    3e5c:	47 fd       	sbrc	r20, 7
+    3e5e:	02 c0       	rjmp	.+4      	; 0x3e64 <main+0x64>
+    3e60:	81 50       	subi	r24, 0x01	; 1
 #else
-    LED_PIN |= _BV(LED);
+// This doesn't seem to work?
+//    if ((UART_PIN & (1<<UART_RX_BIT)) == 0)
+//	break;  // detect start bit on soft uart too.
 #endif
-    watchdogReset();
   } while (--count);
-    3e4e:	81 50       	subi	r24, 0x01	; 1
-    3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	ee 24       	eor	r14, r14
-    3e54:	ff 24       	eor	r15, r15
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	b3 e0       	ldi	r27, 0x03	; 3
-    3e58:	ab 2e       	mov	r10, r27
+    3e62:	89 f7       	brne	.-30     	; 0x3e46 <main+0x46>
+
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	bb 24       	eor	r11, r11
-    3e5c:	b3 94       	inc	r11
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    3e64:	ee 24       	eor	r14, r14
+    3e66:	e3 94       	inc	r14
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e60:	da 2e       	mov	r13, r26
+	    __boot_page_write_short(address.word);
+    3e68:	95 e0       	ldi	r25, 0x05	; 5
+    3e6a:	d9 2e       	mov	r13, r25
 	    boot_spm_busy_wait();
 #if defined(RWWSRE)
 	    // Reenable read access to flash
-	    boot_rww_enable();
-    3e62:	f1 e1       	ldi	r31, 0x11	; 17
-    3e64:	cf 2e       	mov	r12, r31
+	    __boot_rww_enable_short();
+    3e6c:	21 e1       	ldi	r18, 0x11	; 17
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
+    3e6e:	c2 2e       	mov	r12, r18
 
     if(ch == STK_GET_PARAMETER) {
-    3e68:	81 34       	cpi	r24, 0x41	; 65
-    3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
+    3e70:	7f d0       	rcall	.+254    	; 0x3f70 <getch>
       unsigned char which = getch();
-    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
-    3e6e:	08 2f       	mov	r16, r24
+    3e72:	81 34       	cpi	r24, 0x41	; 65
+    3e74:	61 f4       	brne	.+24     	; 0x3e8e <main+0x8e>
+    3e76:	7c d0       	rcall	.+248    	; 0x3f70 <getch>
       verifySpace();
-    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
+    3e78:	18 2f       	mov	r17, r24
+    3e7a:	8c d0       	rcall	.+280    	; 0x3f94 <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
-      if (which == 0x82) {
-    3e72:	02 38       	cpi	r16, 0x82	; 130
-    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
+      if (which == STK_SW_MINOR) {
+    3e7c:	12 38       	cpi	r17, 0x82	; 130
+    3e7e:	e9 f0       	breq	.+58     	; 0x3eba <main+0xba>
 	  putch(optiboot_version & 0xFF);
-    3e76:	82 e0       	ldi	r24, 0x02	; 2
-    3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
-      } else if (which == 0x81) {
-    3e7a:	01 38       	cpi	r16, 0x81	; 129
-    3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
+      } else if (which == STK_SW_MAJOR) {
+    3e80:	11 38       	cpi	r17, 0x81	; 129
+	  putch(optiboot_version >> 8);
+    3e82:	11 f4       	brne	.+4      	; 0x3e88 <main+0x88>
+    3e84:	87 e0       	ldi	r24, 0x07	; 7
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
-    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
+    3e86:	01 c0       	rjmp	.+2      	; 0x3e8a <main+0x8a>
+    3e88:	83 e0       	ldi	r24, 0x03	; 3
+    3e8a:	6b d0       	rcall	.+214    	; 0x3f62 <putch>
+    3e8c:	67 c0       	rjmp	.+206    	; 0x3f5c <main+0x15c>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    3e86:	82 34       	cpi	r24, 0x42	; 66
-    3e88:	11 f4       	brne	.+4      	; 0x3e8e <main+0x8e>
+    3e8e:	82 34       	cpi	r24, 0x42	; 66
       // SET DEVICE is ignored
       getNch(20);
-    3e8a:	84 e1       	ldi	r24, 0x14	; 20
-    3e8c:	03 c0       	rjmp	.+6      	; 0x3e94 <main+0x94>
+    3e90:	11 f4       	brne	.+4      	; 0x3e96 <main+0x96>
+    3e92:	84 e1       	ldi	r24, 0x14	; 20
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e8e:	85 34       	cpi	r24, 0x45	; 69
-    3e90:	19 f4       	brne	.+6      	; 0x3e98 <main+0x98>
+    3e94:	03 c0       	rjmp	.+6      	; 0x3e9c <main+0x9c>
       // SET DEVICE EXT is ignored
       getNch(5);
-    3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
-    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
+    3e96:	85 34       	cpi	r24, 0x45	; 69
+    3e98:	19 f4       	brne	.+6      	; 0x3ea0 <main+0xa0>
+    3e9a:	85 e0       	ldi	r24, 0x05	; 5
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    3e98:	85 35       	cpi	r24, 0x55	; 85
-    3e9a:	79 f4       	brne	.+30     	; 0x3eba <main+0xba>
+    3e9c:	83 d0       	rcall	.+262    	; 0x3fa4 <getNch>
+    3e9e:	5e c0       	rjmp	.+188    	; 0x3f5c <main+0x15c>
       // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e9e:	e8 2e       	mov	r14, r24
-    3ea0:	ff 24       	eor	r15, r15
-    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
-    3ea4:	08 2f       	mov	r16, r24
-    3ea6:	10 e0       	ldi	r17, 0x00	; 0
-    3ea8:	10 2f       	mov	r17, r16
-    3eaa:	00 27       	eor	r16, r16
-    3eac:	0e 29       	or	r16, r14
-    3eae:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
+      address.bytes[0] = getch();
+    3ea0:	85 35       	cpi	r24, 0x55	; 85
+    3ea2:	39 f4       	brne	.+14     	; 0x3eb2 <main+0xb2>
+    3ea4:	65 d0       	rcall	.+202    	; 0x3f70 <getch>
+      address.bytes[1] = getch();
+    3ea6:	c8 2f       	mov	r28, r24
+    3ea8:	63 d0       	rcall	.+198    	; 0x3f70 <getch>
+      }
+      else {
+        RAMPZ &= 0xFE;
+      }
 #endif
-      newAddress += newAddress; // Convert from word address to byte address
-    3eb0:	00 0f       	add	r16, r16
-    3eb2:	11 1f       	adc	r17, r17
-      address = newAddress;
+      address.word *= 2; // Convert from word address to byte address
+    3eaa:	d8 2f       	mov	r29, r24
+    3eac:	cc 0f       	add	r28, r28
+    3eae:	dd 1f       	adc	r29, r29
       verifySpace();
-    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
-    3eb6:	78 01       	movw	r14, r16
-    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
     }
     else if(ch == STK_UNIVERSAL) {
-    3eba:	86 35       	cpi	r24, 0x56	; 86
-    3ebc:	21 f4       	brne	.+8      	; 0x3ec6 <main+0xc6>
+    3eb0:	54 c0       	rjmp	.+168    	; 0x3f5a <main+0x15a>
+        getNch(3);
+        putch(0x00);
+      }
+#else
       // UNIVERSAL command is ignored
       getNch(4);
-    3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
+    3eb2:	86 35       	cpi	r24, 0x56	; 86
+    3eb4:	21 f4       	brne	.+8      	; 0x3ebe <main+0xbe>
       putch(0x00);
-    3ec2:	80 e0       	ldi	r24, 0x00	; 0
-    3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
+    3eb6:	84 e0       	ldi	r24, 0x04	; 4
+    3eb8:	75 d0       	rcall	.+234    	; 0x3fa4 <getNch>
+#endif
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    3ec6:	84 36       	cpi	r24, 0x64	; 100
-    3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
+    3eba:	80 e0       	ldi	r24, 0x00	; 0
+    3ebc:	e6 cf       	rjmp	.-52     	; 0x3e8a <main+0x8a>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
       pagelen_t savelength;
 
       GETLENGTH(length);
-    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
-    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
-    3ed0:	18 2f       	mov	r17, r24
+    3ebe:	84 36       	cpi	r24, 0x64	; 100
+    3ec0:	09 f0       	breq	.+2      	; 0x3ec4 <main+0xc4>
+    3ec2:	2e c0       	rjmp	.+92     	; 0x3f20 <main+0x120>
+    3ec4:	55 d0       	rcall	.+170    	; 0x3f70 <getch>
       savelength = length;
       desttype = getch();
-    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
-    3ed4:	08 2f       	mov	r16, r24
-    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
-    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
+    3ec6:	54 d0       	rcall	.+168    	; 0x3f70 <getch>
+    3ec8:	f8 2e       	mov	r15, r24
+    3eca:	52 d0       	rcall	.+164    	; 0x3f70 <getch>
+    3ecc:	b8 2e       	mov	r11, r24
+    3ece:	00 e0       	ldi	r16, 0x00	; 0
 
       // read a page worth of contents
-      bufPtr = buff;
+      bufPtr = buff.bptr;
       do *bufPtr++ = getch();
-    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
-    3edc:	89 93       	st	Y+, r24
+    3ed0:	11 e0       	ldi	r17, 0x01	; 1
+    3ed2:	4e d0       	rcall	.+156    	; 0x3f70 <getch>
+    3ed4:	f8 01       	movw	r30, r16
+    3ed6:	81 93       	st	Z+, r24
+    3ed8:	8f 01       	movw	r16, r30
       while (--length);
-    3ede:	1c 17       	cp	r17, r28
-    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
+    3eda:	fe 12       	cpse	r15, r30
+    3edc:	fa cf       	rjmp	.-12     	; 0x3ed2 <main+0xd2>
 
       // Read command terminator, start reply
       verifySpace();
-    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
+    3ede:	5a d0       	rcall	.+180    	; 0x3f94 <verifySpace>
+    3ee0:	f5 e4       	ldi	r31, 0x45	; 69
  * void writebuffer(memtype, buffer, address, length)
  */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+			       addr16_t address, pagelen_t len)
 {
     switch (memtype) {
-    3ee4:	05 34       	cpi	r16, 0x45	; 69
-    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
-    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
+    3ee2:	bf 12       	cpse	r11, r31
+    3ee4:	01 c0       	rjmp	.+2      	; 0x3ee8 <main+0xe8>
+    3ee6:	ff cf       	rjmp	.-2      	; 0x3ee6 <main+0xe6>
+    3ee8:	83 e0       	ldi	r24, 0x03	; 3
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	a7 be       	out	0x37, r10	; 55
+	    __boot_page_erase_short(address.word);
+    3eea:	fe 01       	movw	r30, r28
+    3eec:	87 bf       	out	0x37, r24	; 55
     3eee:	e8 95       	spm
-	    boot_spm_busy_wait();
     3ef0:	07 b6       	in	r0, 0x37	; 55
+	    boot_spm_busy_wait();
     3ef2:	00 fc       	sbrc	r0, 0
     3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
-    3ef6:	a7 01       	movw	r20, r14
-    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
-    3efa:	b1 e0       	ldi	r27, 0x01	; 1
+    3ef6:	a0 e0       	ldi	r26, 0x00	; 0
+    3ef8:	b1 e0       	ldi	r27, 0x01	; 1
+    3efa:	fe 01       	movw	r30, r28
+    3efc:	8d 91       	ld	r24, X+
+
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-    3efc:	2c 91       	ld	r18, X
-    3efe:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-    3f00:	11 96       	adiw	r26, 0x01	; 1
-    3f02:	8c 91       	ld	r24, X
-    3f04:	11 97       	sbiw	r26, 0x01	; 1
-    3f06:	90 e0       	ldi	r25, 0x00	; 0
-    3f08:	98 2f       	mov	r25, r24
-    3f0a:	88 27       	eor	r24, r24
-    3f0c:	82 2b       	or	r24, r18
-    3f0e:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    3f10:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f12:	fa 01       	movw	r30, r20
-    3f14:	0c 01       	movw	r0, r24
-    3f16:	b7 be       	out	0x37, r11	; 55
-    3f18:	e8 95       	spm
-    3f1a:	11 24       	eor	r1, r1
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    3efe:	9d 91       	ld	r25, X+
+    3f00:	0c 01       	movw	r0, r24
+    3f02:	e7 be       	out	0x37, r14	; 55
+    3f04:	e8 95       	spm
+    3f06:	11 24       	eor	r1, r1
+    3f08:	32 96       	adiw	r30, 0x02	; 2
 		addrPtr += 2;
-    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
-    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    3f20:	1a 17       	cp	r17, r26
-    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
+    3f0a:	fa 12       	cpse	r15, r26
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3f24:	f7 01       	movw	r30, r14
-    3f26:	d7 be       	out	0x37, r13	; 55
-    3f28:	e8 95       	spm
+	    __boot_page_write_short(address.word);
+    3f0c:	f7 cf       	rjmp	.-18     	; 0x3efc <main+0xfc>
+    3f0e:	fe 01       	movw	r30, r28
 	    boot_spm_busy_wait();
-    3f2a:	07 b6       	in	r0, 0x37	; 55
-    3f2c:	00 fc       	sbrc	r0, 0
-    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
+    3f10:	d7 be       	out	0x37, r13	; 55
+    3f12:	e8 95       	spm
 #if defined(RWWSRE)
 	    // Reenable read access to flash
-	    boot_rww_enable();
-    3f30:	c7 be       	out	0x37, r12	; 55
-    3f32:	e8 95       	spm
-    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
+	    __boot_rww_enable_short();
+    3f14:	07 b6       	in	r0, 0x37	; 55
+    3f16:	00 fc       	sbrc	r0, 0
+    3f18:	fd cf       	rjmp	.-6      	; 0x3f14 <main+0x114>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    3f36:	84 37       	cpi	r24, 0x74	; 116
-    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
+    3f1a:	c7 be       	out	0x37, r12	; 55
+    3f1c:	e8 95       	spm
       uint8_t desttype;
       GETLENGTH(length);
-    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
-    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
-    3f3e:	08 2f       	mov	r16, r24
+    3f1e:	1e c0       	rjmp	.+60     	; 0x3f5c <main+0x15c>
+    3f20:	84 37       	cpi	r24, 0x74	; 116
+    3f22:	71 f4       	brne	.+28     	; 0x3f40 <main+0x140>
 
       desttype = getch();
-    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
+    3f24:	25 d0       	rcall	.+74     	; 0x3f70 <getch>
 
       verifySpace();
-    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
-    3f44:	e7 01       	movw	r28, r14
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+    3f26:	24 d0       	rcall	.+72     	; 0x3f70 <getch>
+    3f28:	f8 2e       	mov	r15, r24
+    3f2a:	22 d0       	rcall	.+68     	; 0x3f70 <getch>
+	    //      while (--length);
+	    // read a Flash and increment the address (may increment RAMPZ)
+	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
 #else
 	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+    3f2c:	33 d0       	rcall	.+102    	; 0x3f94 <verifySpace>
+    3f2e:	8e 01       	movw	r16, r28
 #endif
 	    putch(ch);
-    3f46:	fe 01       	movw	r30, r28
-    3f48:	85 91       	lpm	r24, Z+
-    3f4a:	ef 01       	movw	r28, r30
-    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
+    3f30:	f8 01       	movw	r30, r16
 	} while (--length);
-    3f4e:	01 50       	subi	r16, 0x01	; 1
-    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
-    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
-	  
+    3f32:	85 91       	lpm	r24, Z+
+    3f34:	8f 01       	movw	r16, r30
+    3f36:	15 d0       	rcall	.+42     	; 0x3f62 <putch>
+    3f38:	fa 94       	dec	r15
+
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    3f54:	85 37       	cpi	r24, 0x75	; 117
-    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
+    3f3a:	f1 10       	cpse	r15, r1
+    3f3c:	f9 cf       	rjmp	.-14     	; 0x3f30 <main+0x130>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
+    3f3e:	0e c0       	rjmp	.+28     	; 0x3f5c <main+0x15c>
+    3f40:	85 37       	cpi	r24, 0x75	; 117
       putch(SIGNATURE_0);
-    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
+    3f42:	39 f4       	brne	.+14     	; 0x3f52 <main+0x152>
+    3f44:	27 d0       	rcall	.+78     	; 0x3f94 <verifySpace>
+    3f46:	8e e1       	ldi	r24, 0x1E	; 30
       putch(SIGNATURE_1);
-    3f5e:	84 e9       	ldi	r24, 0x94	; 148
-    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
+    3f48:	0c d0       	rcall	.+24     	; 0x3f62 <putch>
+    3f4a:	84 e9       	ldi	r24, 0x94	; 148
+    3f4c:	0a d0       	rcall	.+20     	; 0x3f62 <putch>
       putch(SIGNATURE_2);
-    3f62:	86 e0       	ldi	r24, 0x06	; 6
-    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
+    3f4e:	86 e0       	ldi	r24, 0x06	; 6
+    3f50:	9c cf       	rjmp	.-200    	; 0x3e8a <main+0x8a>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f66:	81 35       	cpi	r24, 0x51	; 81
-    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
+    3f52:	81 35       	cpi	r24, 0x51	; 81
+    3f54:	11 f4       	brne	.+4      	; 0x3f5a <main+0x15a>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    3f6a:	88 e0       	ldi	r24, 0x08	; 8
-    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
+    3f56:	88 e0       	ldi	r24, 0x08	; 8
+    3f58:	17 d0       	rcall	.+46     	; 0x3f88 <watchdogConfig>
+    3f5a:	1c d0       	rcall	.+56     	; 0x3f94 <verifySpace>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
+    3f5c:	80 e1       	ldi	r24, 0x10	; 16
+    3f5e:	01 d0       	rcall	.+2      	; 0x3f62 <putch>
     }
     putch(STK_OK);
-    3f70:	80 e1       	ldi	r24, 0x10	; 16
-    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
-    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
+    3f60:	87 cf       	rjmp	.-242    	; 0x3e70 <main+0x70>
 
-00003f76 <putch>:
+00003f62 <putch>:
+    3f62:	90 91 c0 00 	lds	r25, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
   }
+    3f66:	95 ff       	sbrs	r25, 5
 }
 
 void putch(char ch) {
-    3f76:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
-    3f78:	80 91 c0 00 	lds	r24, 0x00C0
-    3f7c:	85 ff       	sbrs	r24, 5
-    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
+    3f68:	fc cf       	rjmp	.-8      	; 0x3f62 <putch>
   UART_UDR = ch;
-    3f80:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-    3f84:	08 95       	ret
+    3f6a:	80 93 c6 00 	sts	0x00C6, r24	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+    3f6e:	08 95       	ret
 
-00003f86 <getch>:
+00003f70 <getch>:
       [uartBit] "I" (UART_RX_BIT)
     :
       "r25"
 );
 #else
   while(!(UART_SRA & _BV(RXC0)))
-    3f86:	80 91 c0 00 	lds	r24, 0x00C0
-    3f8a:	87 ff       	sbrs	r24, 7
-    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
+    3f70:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    3f74:	87 ff       	sbrs	r24, 7
+    3f76:	fc cf       	rjmp	.-8      	; 0x3f70 <getch>
     ;
   if (!(UART_SRA & _BV(FE0))) {
-    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
-    3f92:	84 fd       	sbrc	r24, 4
-    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
+    3f78:	80 91 c0 00 	lds	r24, 0x00C0	; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+    3f7c:	84 fd       	sbrc	r24, 4
+    3f7e:	01 c0       	rjmp	.+2      	; 0x3f82 <getch+0x12>
 }
 #endif
 
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
   __asm__ __volatile__ (
-    3f96:	a8 95       	wdr
+    3f80:	a8 95       	wdr
        * don't care that an invalid char is returned...)
        */
     watchdogReset();
   }
-  
+
   ch = UART_UDR;
-    3f98:	80 91 c6 00 	lds	r24, 0x00C6
+    3f82:	80 91 c6 00 	lds	r24, 0x00C6	; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    3f9c:	08 95       	ret
+    3f86:	08 95       	ret
 
-00003f9e <watchdogConfig>:
+00003f88 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
-    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fa2:	98 e1       	ldi	r25, 0x18	; 24
-    3fa4:	90 83       	st	Z, r25
+    3f88:	e0 e6       	ldi	r30, 0x60	; 96
+    3f8a:	f0 e0       	ldi	r31, 0x00	; 0
+    3f8c:	98 e1       	ldi	r25, 0x18	; 24
+    3f8e:	90 83       	st	Z, r25
   WDTCSR = x;
-    3fa6:	80 83       	st	Z, r24
-}
-    3fa8:	08 95       	ret
+    3f90:	80 83       	st	Z, r24
+    3f92:	08 95       	ret
 
-00003faa <verifySpace>:
+00003f94 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
-    3fac:	80 32       	cpi	r24, 0x20	; 32
-    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
+    3f94:	ed df       	rcall	.-38     	; 0x3f70 <getch>
+    3f96:	80 32       	cpi	r24, 0x20	; 32
+    3f98:	19 f0       	breq	.+6      	; 0x3fa0 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fb0:	88 e0       	ldi	r24, 0x08	; 8
-    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
-    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
+    3f9a:	88 e0       	ldi	r24, 0x08	; 8
+    3f9c:	f5 df       	rcall	.-22     	; 0x3f88 <watchdogConfig>
+    3f9e:	ff cf       	rjmp	.-2      	; 0x3f9e <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    3fb6:	84 e1       	ldi	r24, 0x14	; 20
-}
-    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
+    3fa0:	84 e1       	ldi	r24, 0x14	; 20
+    3fa2:	df cf       	rjmp	.-66     	; 0x3f62 <putch>
 
-00003fba <getNch>:
+00003fa4 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    3fba:	1f 93       	push	r17
-    3fbc:	18 2f       	mov	r17, r24
+    3fa4:	cf 93       	push	r28
+    3fa6:	c8 2f       	mov	r28, r24
   do getch(); while (--count);
-    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
-    3fc0:	11 50       	subi	r17, 0x01	; 1
-    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
+    3fa8:	e3 df       	rcall	.-58     	; 0x3f70 <getch>
+    3faa:	c1 50       	subi	r28, 0x01	; 1
+    3fac:	e9 f7       	brne	.-6      	; 0x3fa8 <getNch+0x4>
   verifySpace();
-    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
-}
-    3fc6:	1f 91       	pop	r17
-    3fc8:	08 95       	ret
+    3fae:	cf 91       	pop	r28
+    3fb0:	f1 cf       	rjmp	.-30     	; 0x3f94 <verifySpace>
 
-00003fca <appStart>:
+00003fb2 <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fca:	28 2e       	mov	r2, r24
+    3fb2:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    3fcc:	80 e0       	ldi	r24, 0x00	; 0
-    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
+    3fb4:	80 e0       	ldi	r24, 0x00	; 0
+    3fb6:	e8 df       	rcall	.-48     	; 0x3f88 <watchdogConfig>
+    3fb8:	e0 e0       	ldi	r30, 0x00	; 0
+  // Note that appstart_vec is defined so that this works with either
+  // real or virtual boot partitions.
   __asm__ __volatile__ (
-    3fd0:	ee 27       	eor	r30, r30
-    3fd2:	ff 27       	eor	r31, r31
-    3fd4:	09 94       	ijmp
+    3fba:	ff 27       	eor	r31, r31
+    3fbc:	09 94       	ijmp

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

@@ -1,39 +1,38 @@
-:101D0000112494B714BE892F8D7011F0892F0ED134
-:101D10008EE0F8D0D29AEE24FF2493E0B92EAA24C4
-:101D2000A39485E0982E0FE7D02E1EECC12ED7D0BD
-:101D3000813471F4D4D0082FE9D0023811F482E054
-:101D400005C0013811F486E001C083E0B9D0B5C008
-:101D5000823411F484E103C0853419F485E0DED0C7
-:101D6000ACC0853579F4BBD0E82EFF24B8D0082F5D
-:101D700010E0102F00270E291F29000F111FC6D0B9
-:101D800078019BC0863521F484E0C8D080E0DECFA6
-:101D9000843609F05EC0A3D0A2D0182FA0D0082F9F
-:101DA000C0E0D1E09CD089931C17E1F7AFD0E114DB
-:101DB000F10441F5809100012091010130E0322FC2
-:101DC000222790E0282B392B309385012093840122
-:101DD000409108018091090190E0982F882750E0F8
-:101DE000842B952B9093870180938601245030405B
-:101DF00020930801232F332720930901D09200015B
-:101E0000C0920101053409F4FFCFF701B7BEE89590
-:101E100007B600FCFDCFA701A0E0B1E02C9130E0B7
-:101E200011968C91119790E0982F8827822B932BF5
-:101E30001296FA010C01A7BEE89511244E5F5F4F80
-:101E40001A1761F7F70197BEE89507B600FCFDCFBA
-:101E500034C0843721F543D042D0082F40D056D02B
-:101E6000E701209719F48091840114C0C130D10595
-:101E700019F4809185010EC0C830D10519F4809104
-:101E8000860108C0C930D10519F48091870102C0CC
-:101E9000FE01849115D0015081F02196E2CF853763
-:101EA00039F434D08EE10CD083E90AD08CE04ECFE7
-:101EB000813511F488E026D029D080E101D037CFD8
-:101EC0002AE030E08095089410F4DA9802C0DA9A9B
-:101ED000000014D013D086952A95B1F7089529E013
-:101EE00030E0CB99FECF0AD009D008D08894CB99A6
-:101EF00008942A9511F08795F7CF08959EE09A955A
-:101F0000F1F7089598E191BD81BD0895E8DF803231
-:101F100019F088E0F7DFFFCF84E1D2CF1F93182FAD
-:101F2000DEDF1150E9F7F2DF1F910895282E80E0DF
-:081F3000E9DFE4E0FF2709945A
-:021FFE000206D9
+:101D0000112484B7882349F0982F9A70923029F0D3
+:101D100081FF02C097EF94BFFED08EE0E9D0D29A47
+:101D200023E0C22EBB24B39435E0A32ECDD0813462
+:101D300071F4CAD0F82EE0D082E8F816F1F0E1E8AC
+:101D4000FE1202C087E001C083E0AFD0ABC0823496
+:101D500011F484E103C0853419F485E0D5D0A2C024
+:101D6000853539F4B1D0C82FAFD0D82FCC0FDD1FB7
+:101D700098C0863521F484E0C7D080E0E6CF843671
+:101D800009F055C0A1D0A0D0F82E9ED0D82EEF2CAF
+:101D900080E6882E912C98D0F40181934F01EA942B
+:101DA000E110F9CFA9D0209719F590916000909398
+:101DB000E400809161008093E50020916800209309
+:101DC000E600209169002093E700092F182F0450A6
+:101DD000110900936800812F8F70806C80936900D7
+:101DE00000E81EE000936000812F806C809361000A
+:101DF000F5E4DF1201C0FFCFFE01C7BEE89507B6CC
+:101E000000FCFDCFA0E6B0E0FE018D919D910C019C
+:101E1000B7BEE8951124FA94FA943296F110F5CFF2
+:101E2000FE01A7BEE89507B600FCFDCF3BC0843796
+:101E300059F54AD049D0D82E47D05ED07E01E11462
+:101E4000F10419F48091E40017C0F1E0EF16F104F9
+:101E500019F48091E50010C088E0E816F10419F447
+:101E60008091E60009C0E9E0EE16F10419F48091D2
+:101E7000E70002C0F701849118D0DA94FFEFEF1A5F
+:101E8000FF0AD110DCCF0EC0853739F435D08EE192
+:101E90000CD083E90AD08CE058CF813511F488E06A
+:101EA00027D02AD080E101D041CF2AE030E08095D0
+:101EB000089410F4DA9802C0DA9A000015D014D011
+:101EC00086952A95B1F70895A89529E030E0CB9939
+:101ED000FECF0AD009D008D08894CB9908942A95CF
+:101EE00011F08795F7CF08959EE09A95F1F7089540
+:101EF00098E191BD81BD0895E7DF803219F088E057
+:101F0000F7DFFFCF84E1D1CFCF93C82FDDDFC15002
+:101F1000E9F7CF91F1CF282E80E0EADFE4E0FF2758
+:021F2000099422
+:021FFE000007DA
 :0400000300001D00DC
 :00000001FF

+ 404 - 381
optiboot/bootloaders/optiboot/optiboot_luminet.lst

@@ -3,609 +3,632 @@ optiboot_attiny84.elf:     file format elf32-avr
 
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         00000238  00001d00  00001d00  00000074  2**1
+  0 .text         00000222  00001d00  00001d00  00000074  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00001ffe  00001ffe  000002ac  2**0
+  1 .version      00000002  00001ffe  00001ffe  00000296  2**0
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  000002ae  2**0
+  2 .data         00000000  00800060  00800060  00000298  2**0
+                  CONTENTS, ALLOC, LOAD, DATA
+  3 .comment      0000002f  00000000  00000000  00000298  2**0
+                  CONTENTS, READONLY
+  4 .debug_aranges 00000028  00000000  00000000  000002c7  2**0
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000082  00000000  00000000  000002d6  2**0
+  5 .debug_info   000005e9  00000000  00000000  000002ef  2**0
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003e1  00000000  00000000  00000358  2**0
+  6 .debug_abbrev 0000029f  00000000  00000000  000008d8  2**0
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001a5  00000000  00000000  00000739  2**0
+  7 .debug_line   00000307  00000000  00000000  00000b77  2**0
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   0000042a  00000000  00000000  000008de  2**0
+  8 .debug_frame  0000009c  00000000  00000000  00000e80  2**2
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000090  00000000  00000000  00000d08  2**2
+  9 .debug_str    00000212  00000000  00000000  00000f1c  2**0
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    00000185  00000000  00000000  00000d98  2**0
+ 10 .debug_loc    00000367  00000000  00000000  0000112e  2**0
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000324  00000000  00000000  00000f1d  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000d0  00000000  00000000  00001241  2**0
+ 11 .debug_ranges 00000060  00000000  00000000  00001495  2**0
                   CONTENTS, READONLY, DEBUGGING
 
 Disassembly of section .text:
 
 00001d00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
+  //  SP points to RAMEND
+  //  r1 contains zero
+  //
+  // If not, uncomment the following instructions:
+  // cli();
+  asm volatile ("clr __zero_reg__");
     1d00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
+   * 
+   * Code by MarkG55
+   * see discusion in https://github.com/Optiboot/optiboot/issues/97
    */
+#if !defined(__AVR_ATmega16__)
   ch = MCUSR;
-    1d02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-    1d04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-    1d06:	89 2f       	mov	r24, r25
-    1d08:	8d 70       	andi	r24, 0x0D	; 13
-    1d0a:	11 f0       	breq	.+4      	; 0x1d10 <main+0x10>
-      appStart(ch);
-    1d0c:	89 2f       	mov	r24, r25
-    1d0e:	0e d1       	rcall	.+540    	; 0x1f2c <appStart>
+    1d02:	84 b7       	in	r24, 0x34	; 52
+#else
+  ch = MCUCSR;
+#endif
+  // Skip all logic and run bootloader if MCUSR is cleared (application request)
+  if (ch != 0) {
+    1d04:	88 23       	and	r24, r24
+    1d06:	49 f0       	breq	.+18     	; 0x1d1a <main+0x1a>
+       *  2. we clear WDRF if it's set with EXTRF to avoid loops
+       * One problematic scenario: broken application code sets watchdog timer 
+       * without clearing MCUSR before and triggers it quickly. But it's
+       * recoverable by power-on with pushed reset button.
+       */
+      if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) { 
+    1d08:	98 2f       	mov	r25, r24
+    1d0a:	9a 70       	andi	r25, 0x0A	; 10
+    1d0c:	92 30       	cpi	r25, 0x02	; 2
+    1d0e:	29 f0       	breq	.+10     	; 0x1d1a <main+0x1a>
+	  if (ch & _BV(EXTRF)) {
+    1d10:	81 ff       	sbrs	r24, 1
+    1d12:	02 c0       	rjmp	.+4      	; 0x1d18 <main+0x18>
+	       * prevent entering bootloader.
+	       * '&' operation is skipped to spare few bytes as bits in MCUSR
+	       * can only be cleared.
+	       */
+#if !defined(__AVR_ATmega16__)
+	      MCUSR = ~(_BV(WDRF));  
+    1d14:	97 ef       	ldi	r25, 0xF7	; 247
+    1d16:	94 bf       	out	0x34, r25	; 52
+#else
+	      MCUCSR = ~(_BV(WDRF));  
+#endif
+	  }
+	  appStart(ch);
+    1d18:	fe d0       	rcall	.+508    	; 0x1f16 <appStart>
   UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
 #endif
 #endif
 
-  // Set up watchdog to trigger after 500ms
+  // Set up watchdog to trigger after 1s
   watchdogConfig(WATCHDOG_1S);
-    1d10:	8e e0       	ldi	r24, 0x0E	; 14
-    1d12:	f8 d0       	rcall	.+496    	; 0x1f04 <watchdogConfig>
+    1d1a:	8e e0       	ldi	r24, 0x0E	; 14
+    1d1c:	e9 d0       	rcall	.+466    	; 0x1ef0 <watchdogConfig>
   LED_DDR |= _BV(LED);
 #endif
 
 #ifdef SOFT_UART
   /* Set TX pin as output */
   UART_DDR |= _BV(UART_TX_BIT);
-    1d14:	d2 9a       	sbi	0x1a, 2	; 26
-    1d16:	ee 24       	eor	r14, r14
-    1d18:	ff 24       	eor	r15, r15
+    1d1e:	d2 9a       	sbi	0x1a, 2	; 26
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    1d1a:	93 e0       	ldi	r25, 0x03	; 3
-    1d1c:	b9 2e       	mov	r11, r25
+	    __boot_page_erase_short(address.word);
+    1d20:	23 e0       	ldi	r18, 0x03	; 3
+    1d22:	c2 2e       	mov	r12, r18
+
+	    /*
+	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    1d1e:	aa 24       	eor	r10, r10
-    1d20:	a3 94       	inc	r10
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    1d24:	bb 24       	eor	r11, r11
+    1d26:	b3 94       	inc	r11
 	    } while (len -= 2);
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    1d22:	85 e0       	ldi	r24, 0x05	; 5
-    1d24:	98 2e       	mov	r9, r24
-        vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
-        buff[8] = vect & 0xff;
-        buff[9] = vect >> 8;
-
-        // Add jump to bootloader at RESET vector
-        buff[0] = 0x7f;
-    1d26:	0f e7       	ldi	r16, 0x7F	; 127
-    1d28:	d0 2e       	mov	r13, r16
-        buff[1] = 0xce; // rjmp 0x1d00 instruction
-    1d2a:	1e ec       	ldi	r17, 0xCE	; 206
-    1d2c:	c1 2e       	mov	r12, r17
+	    __boot_page_write_short(address.word);
+    1d28:	35 e0       	ldi	r19, 0x05	; 5
+    1d2a:	a3 2e       	mov	r10, r19
 #endif
 
   /* Forever loop: exits by causing WDT reset */
   for (;;) {
     /* get character from UART */
     ch = getch();
-    1d2e:	d7 d0       	rcall	.+430    	; 0x1ede <getch>
+    1d2c:	cd d0       	rcall	.+410    	; 0x1ec8 <getch>
 
     if(ch == STK_GET_PARAMETER) {
-    1d30:	81 34       	cpi	r24, 0x41	; 65
-    1d32:	71 f4       	brne	.+28     	; 0x1d50 <main+0x50>
+    1d2e:	81 34       	cpi	r24, 0x41	; 65
+    1d30:	71 f4       	brne	.+28     	; 0x1d4e <main+0x4e>
       unsigned char which = getch();
-    1d34:	d4 d0       	rcall	.+424    	; 0x1ede <getch>
-    1d36:	08 2f       	mov	r16, r24
+    1d32:	ca d0       	rcall	.+404    	; 0x1ec8 <getch>
+    1d34:	f8 2e       	mov	r15, r24
       verifySpace();
-    1d38:	e9 d0       	rcall	.+466    	; 0x1f0c <verifySpace>
+    1d36:	e0 d0       	rcall	.+448    	; 0x1ef8 <verifySpace>
       /*
        * Send optiboot version as "SW version"
        * Note that the references to memory are optimized away.
        */
-      if (which == 0x82) {
-    1d3a:	02 38       	cpi	r16, 0x82	; 130
-    1d3c:	11 f4       	brne	.+4      	; 0x1d42 <main+0x42>
+      if (which == STK_SW_MINOR) {
+    1d38:	82 e8       	ldi	r24, 0x82	; 130
+    1d3a:	f8 16       	cp	r15, r24
+    1d3c:	f1 f0       	breq	.+60     	; 0x1d7a <main+0x7a>
 	  putch(optiboot_version & 0xFF);
-    1d3e:	82 e0       	ldi	r24, 0x02	; 2
-    1d40:	05 c0       	rjmp	.+10     	; 0x1d4c <main+0x4c>
-      } else if (which == 0x81) {
-    1d42:	01 38       	cpi	r16, 0x81	; 129
-    1d44:	11 f4       	brne	.+4      	; 0x1d4a <main+0x4a>
+      } else if (which == STK_SW_MAJOR) {
+    1d3e:	e1 e8       	ldi	r30, 0x81	; 129
+    1d40:	fe 12       	cpse	r15, r30
+    1d42:	02 c0       	rjmp	.+4      	; 0x1d48 <main+0x48>
 	  putch(optiboot_version >> 8);
-    1d46:	86 e0       	ldi	r24, 0x06	; 6
-    1d48:	01 c0       	rjmp	.+2      	; 0x1d4c <main+0x4c>
+    1d44:	87 e0       	ldi	r24, 0x07	; 7
+    1d46:	01 c0       	rjmp	.+2      	; 0x1d4a <main+0x4a>
       } else {
 	/*
 	 * GET PARAMETER returns a generic 0x03 reply for
          * other parameters - enough to keep Avrdude happy
 	 */
 	putch(0x03);
-    1d4a:	83 e0       	ldi	r24, 0x03	; 3
-    1d4c:	b9 d0       	rcall	.+370    	; 0x1ec0 <putch>
-    1d4e:	b5 c0       	rjmp	.+362    	; 0x1eba <main+0x1ba>
+    1d48:	83 e0       	ldi	r24, 0x03	; 3
+    1d4a:	af d0       	rcall	.+350    	; 0x1eaa <putch>
+    1d4c:	ab c0       	rjmp	.+342    	; 0x1ea4 <main+0x1a4>
       }
     }
     else if(ch == STK_SET_DEVICE) {
-    1d50:	82 34       	cpi	r24, 0x42	; 66
-    1d52:	11 f4       	brne	.+4      	; 0x1d58 <main+0x58>
+    1d4e:	82 34       	cpi	r24, 0x42	; 66
+    1d50:	11 f4       	brne	.+4      	; 0x1d56 <main+0x56>
       // SET DEVICE is ignored
       getNch(20);
-    1d54:	84 e1       	ldi	r24, 0x14	; 20
-    1d56:	03 c0       	rjmp	.+6      	; 0x1d5e <main+0x5e>
+    1d52:	84 e1       	ldi	r24, 0x14	; 20
+    1d54:	03 c0       	rjmp	.+6      	; 0x1d5c <main+0x5c>
     }
     else if(ch == STK_SET_DEVICE_EXT) {
-    1d58:	85 34       	cpi	r24, 0x45	; 69
-    1d5a:	19 f4       	brne	.+6      	; 0x1d62 <main+0x62>
+    1d56:	85 34       	cpi	r24, 0x45	; 69
+    1d58:	19 f4       	brne	.+6      	; 0x1d60 <main+0x60>
       // SET DEVICE EXT is ignored
       getNch(5);
-    1d5c:	85 e0       	ldi	r24, 0x05	; 5
-    1d5e:	de d0       	rcall	.+444    	; 0x1f1c <verifySpace+0x10>
-    1d60:	ac c0       	rjmp	.+344    	; 0x1eba <main+0x1ba>
+    1d5a:	85 e0       	ldi	r24, 0x05	; 5
+    1d5c:	d5 d0       	rcall	.+426    	; 0x1f08 <getNch>
+    1d5e:	a2 c0       	rjmp	.+324    	; 0x1ea4 <main+0x1a4>
     }
     else if(ch == STK_LOAD_ADDRESS) {
-    1d62:	85 35       	cpi	r24, 0x55	; 85
-    1d64:	79 f4       	brne	.+30     	; 0x1d84 <main+0x84>
+    1d60:	85 35       	cpi	r24, 0x55	; 85
+    1d62:	39 f4       	brne	.+14     	; 0x1d72 <main+0x72>
       // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    1d66:	bb d0       	rcall	.+374    	; 0x1ede <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    1d68:	e8 2e       	mov	r14, r24
-    1d6a:	ff 24       	eor	r15, r15
-    1d6c:	b8 d0       	rcall	.+368    	; 0x1ede <getch>
-    1d6e:	08 2f       	mov	r16, r24
-    1d70:	10 e0       	ldi	r17, 0x00	; 0
-    1d72:	10 2f       	mov	r17, r16
-    1d74:	00 27       	eor	r16, r16
-    1d76:	0e 29       	or	r16, r14
-    1d78:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
+      address.bytes[0] = getch();
+    1d64:	b1 d0       	rcall	.+354    	; 0x1ec8 <getch>
+    1d66:	c8 2f       	mov	r28, r24
+      address.bytes[1] = getch();
+    1d68:	af d0       	rcall	.+350    	; 0x1ec8 <getch>
+    1d6a:	d8 2f       	mov	r29, r24
+      }
+      else {
+        RAMPZ &= 0xFE;
+      }
 #endif
-      newAddress += newAddress; // Convert from word address to byte address
-    1d7a:	00 0f       	add	r16, r16
-    1d7c:	11 1f       	adc	r17, r17
-      address = newAddress;
+      address.word *= 2; // Convert from word address to byte address
+    1d6c:	cc 0f       	add	r28, r28
+    1d6e:	dd 1f       	adc	r29, r29
+    1d70:	98 c0       	rjmp	.+304    	; 0x1ea2 <main+0x1a2>
       verifySpace();
-    1d7e:	c6 d0       	rcall	.+396    	; 0x1f0c <verifySpace>
-    1d80:	78 01       	movw	r14, r16
-    1d82:	9b c0       	rjmp	.+310    	; 0x1eba <main+0x1ba>
     }
     else if(ch == STK_UNIVERSAL) {
-    1d84:	86 35       	cpi	r24, 0x56	; 86
-    1d86:	21 f4       	brne	.+8      	; 0x1d90 <main+0x90>
+    1d72:	86 35       	cpi	r24, 0x56	; 86
+    1d74:	21 f4       	brne	.+8      	; 0x1d7e <main+0x7e>
+        getNch(3);
+        putch(0x00);
+      }
+#else
       // UNIVERSAL command is ignored
       getNch(4);
-    1d88:	84 e0       	ldi	r24, 0x04	; 4
-    1d8a:	c8 d0       	rcall	.+400    	; 0x1f1c <verifySpace+0x10>
+    1d76:	84 e0       	ldi	r24, 0x04	; 4
+    1d78:	c7 d0       	rcall	.+398    	; 0x1f08 <getNch>
       putch(0x00);
-    1d8c:	80 e0       	ldi	r24, 0x00	; 0
-    1d8e:	de cf       	rjmp	.-68     	; 0x1d4c <main+0x4c>
+    1d7a:	80 e0       	ldi	r24, 0x00	; 0
+    1d7c:	e6 cf       	rjmp	.-52     	; 0x1d4a <main+0x4a>
+#endif
     }
     /* Write memory, length is big endian and is in bytes */
     else if(ch == STK_PROG_PAGE) {
-    1d90:	84 36       	cpi	r24, 0x64	; 100
-    1d92:	09 f0       	breq	.+2      	; 0x1d96 <main+0x96>
-    1d94:	5e c0       	rjmp	.+188    	; 0x1e52 <main+0x152>
+    1d7e:	84 36       	cpi	r24, 0x64	; 100
+    1d80:	09 f0       	breq	.+2      	; 0x1d84 <main+0x84>
+    1d82:	55 c0       	rjmp	.+170    	; 0x1e2e <main+0x12e>
+      // PROGRAM PAGE - we support flash programming only, not EEPROM
+      uint8_t desttype;
+      uint8_t *bufPtr;
+      pagelen_t savelength;
+
+      GETLENGTH(length);
+    1d84:	a1 d0       	rcall	.+322    	; 0x1ec8 <getch>
+    1d86:	a0 d0       	rcall	.+320    	; 0x1ec8 <getch>
+    1d88:	f8 2e       	mov	r15, r24
+      savelength = length;
+      desttype = getch();
+    1d8a:	9e d0       	rcall	.+316    	; 0x1ec8 <getch>
+    1d8c:	d8 2e       	mov	r13, r24
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t desttype;
       uint8_t *bufPtr;
       pagelen_t savelength;
 
       GETLENGTH(length);
-    1d96:	a3 d0       	rcall	.+326    	; 0x1ede <getch>
-    1d98:	a2 d0       	rcall	.+324    	; 0x1ede <getch>
-    1d9a:	18 2f       	mov	r17, r24
+    1d8e:	ef 2c       	mov	r14, r15
       savelength = length;
       desttype = getch();
-    1d9c:	a0 d0       	rcall	.+320    	; 0x1ede <getch>
-    1d9e:	08 2f       	mov	r16, r24
-    1da0:	c0 e0       	ldi	r28, 0x00	; 0
-    1da2:	d1 e0       	ldi	r29, 0x01	; 1
+    1d90:	80 e6       	ldi	r24, 0x60	; 96
+    1d92:	88 2e       	mov	r8, r24
+    1d94:	91 2c       	mov	r9, r1
 
       // read a page worth of contents
-      bufPtr = buff;
+      bufPtr = buff.bptr;
       do *bufPtr++ = getch();
-    1da4:	9c d0       	rcall	.+312    	; 0x1ede <getch>
-    1da6:	89 93       	st	Y+, r24
+    1d96:	98 d0       	rcall	.+304    	; 0x1ec8 <getch>
+    1d98:	f4 01       	movw	r30, r8
+    1d9a:	81 93       	st	Z+, r24
+    1d9c:	4f 01       	movw	r8, r30
       while (--length);
-    1da8:	1c 17       	cp	r17, r28
-    1daa:	e1 f7       	brne	.-8      	; 0x1da4 <main+0xa4>
+    1d9e:	ea 94       	dec	r14
+    1da0:	e1 10       	cpse	r14, r1
+    1da2:	f9 cf       	rjmp	.-14     	; 0x1d96 <main+0x96>
 
       // Read command terminator, start reply
       verifySpace();
-    1dac:	af d0       	rcall	.+350    	; 0x1f0c <verifySpace>
+    1da4:	a9 d0       	rcall	.+338    	; 0x1ef8 <verifySpace>
 
-#ifdef VIRTUAL_BOOT_PARTITION
-      if ((uint16_t)(void*)address == 0) {
-    1dae:	e1 14       	cp	r14, r1
-    1db0:	f1 04       	cpc	r15, r1
-    1db2:	41 f5       	brne	.+80     	; 0x1e04 <main+0x104>
-        // This is the reset vector page. We need to live-patch the code so the
-        // bootloader runs.
+#else
+/*
+ * AVR with 2-byte ISR Vectors and rjmp
+ */
+      if (address.word == rstVect0) {
+    1da6:	20 97       	sbiw	r28, 0x00	; 0
+    1da8:	19 f5       	brne	.+70     	; 0x1df0 <main+0xf0>
+        // This is the reset vector page. We need to live-patch
+        // the code so the bootloader runs first.
         //
-        // Move RESET vector to WDT vector
-        uint16_t vect = buff[0] | (buff[1]<<8);
-    1db4:	80 91 00 01 	lds	r24, 0x0100
-    1db8:	20 91 01 01 	lds	r18, 0x0101
-    1dbc:	30 e0       	ldi	r19, 0x00	; 0
-    1dbe:	32 2f       	mov	r19, r18
-    1dc0:	22 27       	eor	r18, r18
-    1dc2:	90 e0       	ldi	r25, 0x00	; 0
-    1dc4:	28 2b       	or	r18, r24
-    1dc6:	39 2b       	or	r19, r25
-        rstVect = vect;
-    1dc8:	30 93 85 01 	sts	0x0185, r19
-    1dcc:	20 93 84 01 	sts	0x0184, r18
-        wdtVect = buff[8] | (buff[9]<<8);
-    1dd0:	40 91 08 01 	lds	r20, 0x0108
-    1dd4:	80 91 09 01 	lds	r24, 0x0109
-    1dd8:	90 e0       	ldi	r25, 0x00	; 0
-    1dda:	98 2f       	mov	r25, r24
-    1ddc:	88 27       	eor	r24, r24
-    1dde:	50 e0       	ldi	r21, 0x00	; 0
-    1de0:	84 2b       	or	r24, r20
-    1de2:	95 2b       	or	r25, r21
-    1de4:	90 93 87 01 	sts	0x0187, r25
-    1de8:	80 93 86 01 	sts	0x0186, r24
-        vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
-    1dec:	24 50       	subi	r18, 0x04	; 4
-    1dee:	30 40       	sbci	r19, 0x00	; 0
-        buff[8] = vect & 0xff;
-    1df0:	20 93 08 01 	sts	0x0108, r18
-        buff[9] = vect >> 8;
-    1df4:	23 2f       	mov	r18, r19
-    1df6:	33 27       	eor	r19, r19
-    1df8:	20 93 09 01 	sts	0x0109, r18
-
-        // Add jump to bootloader at RESET vector
-        buff[0] = 0x7f;
-    1dfc:	d0 92 00 01 	sts	0x0100, r13
-        buff[1] = 0xce; // rjmp 0x1d00 instruction
-    1e00:	c0 92 01 01 	sts	0x0101, r12
+        // Move RESET vector to 'save' vector
+	// Save jmp targets (for "Verify")
+	rstVect0_sav = buff.bptr[rstVect0];
+    1daa:	90 91 60 00 	lds	r25, 0x0060	; 0x800060 <_edata>
+    1dae:	90 93 e4 00 	sts	0x00E4, r25	; 0x8000e4 <_edata+0x84>
+	rstVect1_sav = buff.bptr[rstVect1];
+    1db2:	80 91 61 00 	lds	r24, 0x0061	; 0x800061 <_edata+0x1>
+    1db6:	80 93 e5 00 	sts	0x00E5, r24	; 0x8000e5 <_edata+0x85>
+	saveVect0_sav = buff.bptr[saveVect0];
+    1dba:	20 91 68 00 	lds	r18, 0x0068	; 0x800068 <_edata+0x8>
+    1dbe:	20 93 e6 00 	sts	0x00E6, r18	; 0x8000e6 <_edata+0x86>
+	saveVect1_sav = buff.bptr[saveVect1];
+    1dc2:	20 91 69 00 	lds	r18, 0x0069	; 0x800069 <_edata+0x9>
+    1dc6:	20 93 e7 00 	sts	0x00E7, r18	; 0x8000e7 <_edata+0x87>
+
+	// Instruction is a relative jump (rjmp), so recalculate.
+	// an RJMP instruction is 0b1100xxxx xxxxxxxx, so we should be able to
+	// do math on the offsets without masking it off first.
+	addr16_t vect;
+	vect.bytes[0] = rstVect0_sav;
+    1dca:	09 2f       	mov	r16, r25
+	vect.bytes[1] = rstVect1_sav;
+    1dcc:	18 2f       	mov	r17, r24
+	vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
+    1dce:	04 50       	subi	r16, 0x04	; 4
+    1dd0:	11 09       	sbc	r17, r1
+        // Move RESET jmp target to 'save' vector
+        buff.bptr[saveVect0] = vect.bytes[0];
+    1dd2:	00 93 68 00 	sts	0x0068, r16	; 0x800068 <_edata+0x8>
+        buff.bptr[saveVect1] = (vect.bytes[1] & 0x0F)| 0xC0;  // make an "rjmp"
+    1dd6:	81 2f       	mov	r24, r17
+    1dd8:	8f 70       	andi	r24, 0x0F	; 15
+    1dda:	80 6c       	ori	r24, 0xC0	; 192
+    1ddc:	80 93 69 00 	sts	0x0069, r24	; 0x800069 <_edata+0x9>
+        // Add rjump to bootloader at RESET vector
+        vect.word = ((uint16_t)main); // (main) is always <= 0x0FFF; no masking needed.
+    1de0:	00 e8       	ldi	r16, 0x80	; 128
+    1de2:	1e e0       	ldi	r17, 0x0E	; 14
+        buff.bptr[0] = vect.bytes[0]; // rjmp 0x1c00 instruction
+    1de4:	00 93 60 00 	sts	0x0060, r16	; 0x800060 <_edata>
+	buff.bptr[1] = vect.bytes[1] | 0xC0;  // make an "rjmp"
+    1de8:	81 2f       	mov	r24, r17
+    1dea:	80 6c       	ori	r24, 0xC0	; 192
+    1dec:	80 93 61 00 	sts	0x0061, r24	; 0x800061 <_edata+0x1>
  * void writebuffer(memtype, buffer, address, length)
  */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+			       addr16_t address, pagelen_t len)
 {
     switch (memtype) {
-    1e04:	05 34       	cpi	r16, 0x45	; 69
-    1e06:	09 f4       	brne	.+2      	; 0x1e0a <main+0x10a>
-    1e08:	ff cf       	rjmp	.-2      	; 0x1e08 <main+0x108>
+    1df0:	f5 e4       	ldi	r31, 0x45	; 69
+    1df2:	df 12       	cpse	r13, r31
+    1df4:	01 c0       	rjmp	.+2      	; 0x1df8 <main+0xf8>
+    1df6:	ff cf       	rjmp	.-2      	; 0x1df6 <main+0xf6>
 	     * Start the page erase and wait for it to finish.  There
 	     * used to be code to do this while receiving the data over
 	     * the serial link, but the performance improvement was slight,
 	     * and we needed the space back.
 	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    1e0a:	f7 01       	movw	r30, r14
-    1e0c:	b7 be       	out	0x37, r11	; 55
-    1e0e:	e8 95       	spm
+	    __boot_page_erase_short(address.word);
+    1df8:	fe 01       	movw	r30, r28
+    1dfa:	c7 be       	out	0x37, r12	; 55
+    1dfc:	e8 95       	spm
 	    boot_spm_busy_wait();
-    1e10:	07 b6       	in	r0, 0x37	; 55
-    1e12:	00 fc       	sbrc	r0, 0
-    1e14:	fd cf       	rjmp	.-6      	; 0x1e10 <main+0x110>
-    1e16:	a7 01       	movw	r20, r14
-    1e18:	a0 e0       	ldi	r26, 0x00	; 0
-    1e1a:	b1 e0       	ldi	r27, 0x01	; 1
+    1dfe:	07 b6       	in	r0, 0x37	; 55
+    1e00:	00 fc       	sbrc	r0, 0
+    1e02:	fd cf       	rjmp	.-6      	; 0x1dfe <main+0xfe>
+    1e04:	a0 e6       	ldi	r26, 0x60	; 96
+    1e06:	b0 e0       	ldi	r27, 0x00	; 0
+    1e08:	fe 01       	movw	r30, r28
+
 	    /*
 	     * Copy data from the buffer into the flash write buffer.
 	     */
 	    do {
-		uint16_t a;
-		a = *bufPtr++;
-    1e1c:	2c 91       	ld	r18, X
-    1e1e:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-    1e20:	11 96       	adiw	r26, 0x01	; 1
-    1e22:	8c 91       	ld	r24, X
-    1e24:	11 97       	sbiw	r26, 0x01	; 1
-    1e26:	90 e0       	ldi	r25, 0x00	; 0
-    1e28:	98 2f       	mov	r25, r24
-    1e2a:	88 27       	eor	r24, r24
-    1e2c:	82 2b       	or	r24, r18
-    1e2e:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    1e30:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    1e32:	fa 01       	movw	r30, r20
-    1e34:	0c 01       	movw	r0, r24
-    1e36:	a7 be       	out	0x37, r10	; 55
-    1e38:	e8 95       	spm
-    1e3a:	11 24       	eor	r1, r1
+		__boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+    1e0a:	8d 91       	ld	r24, X+
+    1e0c:	9d 91       	ld	r25, X+
+    1e0e:	0c 01       	movw	r0, r24
+    1e10:	b7 be       	out	0x37, r11	; 55
+    1e12:	e8 95       	spm
+    1e14:	11 24       	eor	r1, r1
 		addrPtr += 2;
-    1e3c:	4e 5f       	subi	r20, 0xFE	; 254
-    1e3e:	5f 4f       	sbci	r21, 0xFF	; 255
 	    } while (len -= 2);
-    1e40:	1a 17       	cp	r17, r26
-    1e42:	61 f7       	brne	.-40     	; 0x1e1c <main+0x11c>
+    1e16:	fa 94       	dec	r15
+    1e18:	fa 94       	dec	r15
+    1e1a:	32 96       	adiw	r30, 0x02	; 2
+    1e1c:	f1 10       	cpse	r15, r1
+    1e1e:	f5 cf       	rjmp	.-22     	; 0x1e0a <main+0x10a>
 
 	    /*
 	     * Actually Write the buffer to flash (and wait for it to finish.)
 	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    1e44:	f7 01       	movw	r30, r14
-    1e46:	97 be       	out	0x37, r9	; 55
-    1e48:	e8 95       	spm
+	    __boot_page_write_short(address.word);
+    1e20:	fe 01       	movw	r30, r28
+    1e22:	a7 be       	out	0x37, r10	; 55
+    1e24:	e8 95       	spm
 	    boot_spm_busy_wait();
-    1e4a:	07 b6       	in	r0, 0x37	; 55
-    1e4c:	00 fc       	sbrc	r0, 0
-    1e4e:	fd cf       	rjmp	.-6      	; 0x1e4a <main+0x14a>
-    1e50:	34 c0       	rjmp	.+104    	; 0x1eba <main+0x1ba>
+    1e26:	07 b6       	in	r0, 0x37	; 55
+    1e28:	00 fc       	sbrc	r0, 0
+    1e2a:	fd cf       	rjmp	.-6      	; 0x1e26 <main+0x126>
+    1e2c:	3b c0       	rjmp	.+118    	; 0x1ea4 <main+0x1a4>
       writebuffer(desttype, buff, address, savelength);
 
 
     }
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
-    1e52:	84 37       	cpi	r24, 0x74	; 116
-    1e54:	21 f5       	brne	.+72     	; 0x1e9e <main+0x19e>
+    1e2e:	84 37       	cpi	r24, 0x74	; 116
+    1e30:	59 f5       	brne	.+86     	; 0x1e88 <main+0x188>
       uint8_t desttype;
       GETLENGTH(length);
-    1e56:	43 d0       	rcall	.+134    	; 0x1ede <getch>
-    1e58:	42 d0       	rcall	.+132    	; 0x1ede <getch>
-    1e5a:	08 2f       	mov	r16, r24
+    1e32:	4a d0       	rcall	.+148    	; 0x1ec8 <getch>
+    1e34:	49 d0       	rcall	.+146    	; 0x1ec8 <getch>
+    1e36:	d8 2e       	mov	r13, r24
 
       desttype = getch();
-    1e5c:	40 d0       	rcall	.+128    	; 0x1ede <getch>
+    1e38:	47 d0       	rcall	.+142    	; 0x1ec8 <getch>
 
       verifySpace();
-    1e5e:	56 d0       	rcall	.+172    	; 0x1f0c <verifySpace>
-    1e60:	e7 01       	movw	r28, r14
+    1e3a:	5e d0       	rcall	.+188    	; 0x1ef8 <verifySpace>
+    1e3c:	7e 01       	movw	r14, r28
 #endif
     default:
 	do {
 #ifdef VIRTUAL_BOOT_PARTITION
         // Undo vector patch in bottom page so verify passes
-	    if (address == 0)       ch=rstVect & 0xff;
-    1e62:	20 97       	sbiw	r28, 0x00	; 0
-    1e64:	19 f4       	brne	.+6      	; 0x1e6c <main+0x16c>
-    1e66:	80 91 84 01 	lds	r24, 0x0184
-    1e6a:	14 c0       	rjmp	.+40     	; 0x1e94 <main+0x194>
-	    else if (address == 1)  ch=rstVect >> 8;
-    1e6c:	c1 30       	cpi	r28, 0x01	; 1
-    1e6e:	d1 05       	cpc	r29, r1
-    1e70:	19 f4       	brne	.+6      	; 0x1e78 <main+0x178>
-    1e72:	80 91 85 01 	lds	r24, 0x0185
-    1e76:	0e c0       	rjmp	.+28     	; 0x1e94 <main+0x194>
-	    else if (address == 8)  ch=wdtVect & 0xff;
-    1e78:	c8 30       	cpi	r28, 0x08	; 8
-    1e7a:	d1 05       	cpc	r29, r1
-    1e7c:	19 f4       	brne	.+6      	; 0x1e84 <main+0x184>
-    1e7e:	80 91 86 01 	lds	r24, 0x0186
-    1e82:	08 c0       	rjmp	.+16     	; 0x1e94 <main+0x194>
-	    else if (address == 9) ch=wdtVect >> 8;
-    1e84:	c9 30       	cpi	r28, 0x09	; 9
-    1e86:	d1 05       	cpc	r29, r1
-    1e88:	19 f4       	brne	.+6      	; 0x1e90 <main+0x190>
-    1e8a:	80 91 87 01 	lds	r24, 0x0187
-    1e8e:	02 c0       	rjmp	.+4      	; 0x1e94 <main+0x194>
-	    else ch = pgm_read_byte_near(address);
-    1e90:	fe 01       	movw	r30, r28
-    1e92:	84 91       	lpm	r24, Z+
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    if (address.word == rstVect0) ch = rstVect0_sav;
+    1e3e:	e1 14       	cp	r14, r1
+    1e40:	f1 04       	cpc	r15, r1
+    1e42:	19 f4       	brne	.+6      	; 0x1e4a <main+0x14a>
+    1e44:	80 91 e4 00 	lds	r24, 0x00E4	; 0x8000e4 <_edata+0x84>
+    1e48:	17 c0       	rjmp	.+46     	; 0x1e78 <main+0x178>
+	    else if (address.word == rstVect1) ch = rstVect1_sav;
+    1e4a:	f1 e0       	ldi	r31, 0x01	; 1
+    1e4c:	ef 16       	cp	r14, r31
+    1e4e:	f1 04       	cpc	r15, r1
+    1e50:	19 f4       	brne	.+6      	; 0x1e58 <main+0x158>
+    1e52:	80 91 e5 00 	lds	r24, 0x00E5	; 0x8000e5 <_edata+0x85>
+    1e56:	10 c0       	rjmp	.+32     	; 0x1e78 <main+0x178>
+	    else if (address.word == saveVect0) ch = saveVect0_sav;
+    1e58:	88 e0       	ldi	r24, 0x08	; 8
+    1e5a:	e8 16       	cp	r14, r24
+    1e5c:	f1 04       	cpc	r15, r1
+    1e5e:	19 f4       	brne	.+6      	; 0x1e66 <main+0x166>
+    1e60:	80 91 e6 00 	lds	r24, 0x00E6	; 0x8000e6 <_edata+0x86>
+    1e64:	09 c0       	rjmp	.+18     	; 0x1e78 <main+0x178>
+	    else if (address.word == saveVect1) ch = saveVect1_sav;
+    1e66:	e9 e0       	ldi	r30, 0x09	; 9
+    1e68:	ee 16       	cp	r14, r30
+    1e6a:	f1 04       	cpc	r15, r1
+    1e6c:	19 f4       	brne	.+6      	; 0x1e74 <main+0x174>
+    1e6e:	80 91 e7 00 	lds	r24, 0x00E7	; 0x8000e7 <_edata+0x87>
+    1e72:	02 c0       	rjmp	.+4      	; 0x1e78 <main+0x178>
+	    else ch = pgm_read_byte_near(address.bptr);
+    1e74:	f7 01       	movw	r30, r14
+    1e76:	84 91       	lpm	r24, Z
+	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
 #else
 	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
+	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
 #endif
 	    putch(ch);
-    1e94:	15 d0       	rcall	.+42     	; 0x1ec0 <putch>
+    1e78:	18 d0       	rcall	.+48     	; 0x1eaa <putch>
 	} while (--length);
-    1e96:	01 50       	subi	r16, 0x01	; 1
-    1e98:	81 f0       	breq	.+32     	; 0x1eba <main+0x1ba>
-	    if (address == 0)       ch=rstVect & 0xff;
-	    else if (address == 1)  ch=rstVect >> 8;
-	    else if (address == 8)  ch=wdtVect & 0xff;
-	    else if (address == 9) ch=wdtVect >> 8;
-	    else ch = pgm_read_byte_near(address);
-	    address++;
-    1e9a:	21 96       	adiw	r28, 0x01	; 1
-    1e9c:	e2 cf       	rjmp	.-60     	; 0x1e62 <main+0x162>
-	  
+    1e7a:	da 94       	dec	r13
+    1e7c:	ff ef       	ldi	r31, 0xFF	; 255
+    1e7e:	ef 1a       	sub	r14, r31
+    1e80:	ff 0a       	sbc	r15, r31
+    1e82:	d1 10       	cpse	r13, r1
+    1e84:	dc cf       	rjmp	.-72     	; 0x1e3e <main+0x13e>
+    1e86:	0e c0       	rjmp	.+28     	; 0x1ea4 <main+0x1a4>
+
       read_mem(desttype, address, length);
     }
 
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
-    1e9e:	85 37       	cpi	r24, 0x75	; 117
-    1ea0:	39 f4       	brne	.+14     	; 0x1eb0 <main+0x1b0>
+    1e88:	85 37       	cpi	r24, 0x75	; 117
+    1e8a:	39 f4       	brne	.+14     	; 0x1e9a <main+0x19a>
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
-    1ea2:	34 d0       	rcall	.+104    	; 0x1f0c <verifySpace>
+    1e8c:	35 d0       	rcall	.+106    	; 0x1ef8 <verifySpace>
       putch(SIGNATURE_0);
-    1ea4:	8e e1       	ldi	r24, 0x1E	; 30
-    1ea6:	0c d0       	rcall	.+24     	; 0x1ec0 <putch>
+    1e8e:	8e e1       	ldi	r24, 0x1E	; 30
+    1e90:	0c d0       	rcall	.+24     	; 0x1eaa <putch>
       putch(SIGNATURE_1);
-    1ea8:	83 e9       	ldi	r24, 0x93	; 147
-    1eaa:	0a d0       	rcall	.+20     	; 0x1ec0 <putch>
+    1e92:	83 e9       	ldi	r24, 0x93	; 147
+    1e94:	0a d0       	rcall	.+20     	; 0x1eaa <putch>
       putch(SIGNATURE_2);
-    1eac:	8c e0       	ldi	r24, 0x0C	; 12
-    1eae:	4e cf       	rjmp	.-356    	; 0x1d4c <main+0x4c>
+    1e96:	8c e0       	ldi	r24, 0x0C	; 12
+    1e98:	58 cf       	rjmp	.-336    	; 0x1d4a <main+0x4a>
     }
     else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    1eb0:	81 35       	cpi	r24, 0x51	; 81
-    1eb2:	11 f4       	brne	.+4      	; 0x1eb8 <main+0x1b8>
+    1e9a:	81 35       	cpi	r24, 0x51	; 81
+    1e9c:	11 f4       	brne	.+4      	; 0x1ea2 <main+0x1a2>
       // Adaboot no-wait mod
       watchdogConfig(WATCHDOG_16MS);
-    1eb4:	88 e0       	ldi	r24, 0x08	; 8
-    1eb6:	26 d0       	rcall	.+76     	; 0x1f04 <watchdogConfig>
+    1e9e:	88 e0       	ldi	r24, 0x08	; 8
+    1ea0:	27 d0       	rcall	.+78     	; 0x1ef0 <watchdogConfig>
       verifySpace();
     }
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
-    1eb8:	29 d0       	rcall	.+82     	; 0x1f0c <verifySpace>
+    1ea2:	2a d0       	rcall	.+84     	; 0x1ef8 <verifySpace>
     }
     putch(STK_OK);
-    1eba:	80 e1       	ldi	r24, 0x10	; 16
-    1ebc:	01 d0       	rcall	.+2      	; 0x1ec0 <putch>
-    1ebe:	37 cf       	rjmp	.-402    	; 0x1d2e <main+0x2e>
+    1ea4:	80 e1       	ldi	r24, 0x10	; 16
+    1ea6:	01 d0       	rcall	.+2      	; 0x1eaa <putch>
+  }
+    1ea8:	41 cf       	rjmp	.-382    	; 0x1d2c <main+0x2c>
 
-00001ec0 <putch>:
+00001eaa <putch>:
 void putch(char ch) {
 #ifndef SOFT_UART
   while (!(UART_SRA & _BV(UDRE0)));
   UART_UDR = ch;
 #else
   __asm__ __volatile__ (
-    1ec0:	2a e0       	ldi	r18, 0x0A	; 10
-    1ec2:	30 e0       	ldi	r19, 0x00	; 0
-    1ec4:	80 95       	com	r24
-    1ec6:	08 94       	sec
-    1ec8:	10 f4       	brcc	.+4      	; 0x1ece <putch+0xe>
-    1eca:	da 98       	cbi	0x1b, 2	; 27
-    1ecc:	02 c0       	rjmp	.+4      	; 0x1ed2 <putch+0x12>
-    1ece:	da 9a       	sbi	0x1b, 2	; 27
-    1ed0:	00 00       	nop
-    1ed2:	14 d0       	rcall	.+40     	; 0x1efc <uartDelay>
-    1ed4:	13 d0       	rcall	.+38     	; 0x1efc <uartDelay>
-    1ed6:	86 95       	lsr	r24
-    1ed8:	2a 95       	dec	r18
-    1eda:	b1 f7       	brne	.-20     	; 0x1ec8 <putch+0x8>
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
+    1eaa:	2a e0       	ldi	r18, 0x0A	; 10
+    1eac:	30 e0       	ldi	r19, 0x00	; 0
+    1eae:	80 95       	com	r24
+    1eb0:	08 94       	sec
+    1eb2:	10 f4       	brcc	.+4      	; 0x1eb8 <putch+0xe>
+    1eb4:	da 98       	cbi	0x1b, 2	; 27
+    1eb6:	02 c0       	rjmp	.+4      	; 0x1ebc <putch+0x12>
+    1eb8:	da 9a       	sbi	0x1b, 2	; 27
+    1eba:	00 00       	nop
+    1ebc:	15 d0       	rcall	.+42     	; 0x1ee8 <uartDelay>
+    1ebe:	14 d0       	rcall	.+40     	; 0x1ee8 <uartDelay>
+    1ec0:	86 95       	lsr	r24
+    1ec2:	2a 95       	dec	r18
+    1ec4:	b1 f7       	brne	.-20     	; 0x1eb2 <putch+0x8>
+    1ec6:	08 95       	ret
+
+00001ec8 <getch>:
 }
-    1edc:	08 95       	ret
+#endif
+
+// Watchdog functions. These are only safe with interrupts turned off.
+void watchdogReset() {
+  __asm__ __volatile__ (
+    1ec8:	a8 95       	wdr
+#endif
+#endif
 
-00001ede <getch>:
+#ifdef SOFT_UART
+    watchdogReset();
+  __asm__ __volatile__ (
+    1eca:	29 e0       	ldi	r18, 0x09	; 9
+    1ecc:	30 e0       	ldi	r19, 0x00	; 0
+    1ece:	cb 99       	sbic	0x19, 3	; 25
+    1ed0:	fe cf       	rjmp	.-4      	; 0x1ece <getch+0x6>
+    1ed2:	0a d0       	rcall	.+20     	; 0x1ee8 <uartDelay>
+    1ed4:	09 d0       	rcall	.+18     	; 0x1ee8 <uartDelay>
+    1ed6:	08 d0       	rcall	.+16     	; 0x1ee8 <uartDelay>
+    1ed8:	88 94       	clc
+    1eda:	cb 99       	sbic	0x19, 3	; 25
+    1edc:	08 94       	sec
+    1ede:	2a 95       	dec	r18
+    1ee0:	11 f0       	breq	.+4      	; 0x1ee6 <getch+0x1e>
+    1ee2:	87 95       	ror	r24
+    1ee4:	f7 cf       	rjmp	.-18     	; 0x1ed4 <getch+0xc>
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
   return ch;
 }
-    1ede:	29 e0       	ldi	r18, 0x09	; 9
-    1ee0:	30 e0       	ldi	r19, 0x00	; 0
-    1ee2:	cb 99       	sbic	0x19, 3	; 25
-    1ee4:	fe cf       	rjmp	.-4      	; 0x1ee2 <getch+0x4>
-    1ee6:	0a d0       	rcall	.+20     	; 0x1efc <uartDelay>
-    1ee8:	09 d0       	rcall	.+18     	; 0x1efc <uartDelay>
-    1eea:	08 d0       	rcall	.+16     	; 0x1efc <uartDelay>
-    1eec:	88 94       	clc
-    1eee:	cb 99       	sbic	0x19, 3	; 25
-    1ef0:	08 94       	sec
-    1ef2:	2a 95       	dec	r18
-    1ef4:	11 f0       	breq	.+4      	; 0x1efa <getch+0x1c>
-    1ef6:	87 95       	ror	r24
-    1ef8:	f7 cf       	rjmp	.-18     	; 0x1ee8 <getch+0xa>
-    1efa:	08 95       	ret
-
-00001efc <uartDelay>:
+    1ee6:	08 95       	ret
+
+00001ee8 <uartDelay>:
 #if UART_B_VALUE > 255
 #error Baud rate too slow for soft UART
 #endif
 
 void uartDelay() {
   __asm__ __volatile__ (
-    1efc:	9e e0       	ldi	r25, 0x0E	; 14
-    1efe:	9a 95       	dec	r25
-    1f00:	f1 f7       	brne	.-4      	; 0x1efe <uartDelay+0x2>
-    1f02:	08 95       	ret
+    1ee8:	9e e0       	ldi	r25, 0x0E	; 14
+    1eea:	9a 95       	dec	r25
+    1eec:	f1 f7       	brne	.-4      	; 0x1eea <uartDelay+0x2>
+    1eee:	08 95       	ret
 
-00001f04 <watchdogConfig>:
+00001ef0 <watchdogConfig>:
     "wdr\n"
   );
 }
 
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    1f04:	98 e1       	ldi	r25, 0x18	; 24
-    1f06:	91 bd       	out	0x21, r25	; 33
+    1ef0:	98 e1       	ldi	r25, 0x18	; 24
+    1ef2:	91 bd       	out	0x21, r25	; 33
   WDTCSR = x;
-    1f08:	81 bd       	out	0x21, r24	; 33
-}
-    1f0a:	08 95       	ret
+    1ef4:	81 bd       	out	0x21, r24	; 33
+    1ef6:	08 95       	ret
 
-00001f0c <verifySpace>:
+00001ef8 <verifySpace>:
   do getch(); while (--count);
   verifySpace();
 }
 
 void verifySpace() {
   if (getch() != CRC_EOP) {
-    1f0c:	e8 df       	rcall	.-48     	; 0x1ede <getch>
-    1f0e:	80 32       	cpi	r24, 0x20	; 32
-    1f10:	19 f0       	breq	.+6      	; 0x1f18 <verifySpace+0xc>
+    1ef8:	e7 df       	rcall	.-50     	; 0x1ec8 <getch>
+    1efa:	80 32       	cpi	r24, 0x20	; 32
+    1efc:	19 f0       	breq	.+6      	; 0x1f04 <verifySpace+0xc>
     watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    1f12:	88 e0       	ldi	r24, 0x08	; 8
-    1f14:	f7 df       	rcall	.-18     	; 0x1f04 <watchdogConfig>
-    1f16:	ff cf       	rjmp	.-2      	; 0x1f16 <verifySpace+0xa>
+    1efe:	88 e0       	ldi	r24, 0x08	; 8
+    1f00:	f7 df       	rcall	.-18     	; 0x1ef0 <watchdogConfig>
+    1f02:	ff cf       	rjmp	.-2      	; 0x1f02 <verifySpace+0xa>
     while (1)			      // and busy-loop so that WD causes
       ;				      //  a reset and app start.
   }
   putch(STK_INSYNC);
-    1f18:	84 e1       	ldi	r24, 0x14	; 20
-}
-    1f1a:	d2 cf       	rjmp	.-92     	; 0x1ec0 <putch>
+    1f04:	84 e1       	ldi	r24, 0x14	; 20
+    1f06:	d1 cf       	rjmp	.-94     	; 0x1eaa <putch>
+
+00001f08 <getNch>:
     ::[count] "M" (UART_B_VALUE)
   );
 }
 #endif
 
 void getNch(uint8_t count) {
-    1f1c:	1f 93       	push	r17
-
-00001f1e <getNch>:
-    1f1e:	18 2f       	mov	r17, r24
+    1f08:	cf 93       	push	r28
+    1f0a:	c8 2f       	mov	r28, r24
   do getch(); while (--count);
-    1f20:	de df       	rcall	.-68     	; 0x1ede <getch>
-    1f22:	11 50       	subi	r17, 0x01	; 1
-    1f24:	e9 f7       	brne	.-6      	; 0x1f20 <getNch+0x2>
+    1f0c:	dd df       	rcall	.-70     	; 0x1ec8 <getch>
+    1f0e:	c1 50       	subi	r28, 0x01	; 1
+    1f10:	e9 f7       	brne	.-6      	; 0x1f0c <getNch+0x4>
   verifySpace();
-    1f26:	f2 df       	rcall	.-28     	; 0x1f0c <verifySpace>
 }
-    1f28:	1f 91       	pop	r17
-    1f2a:	08 95       	ret
+    1f12:	cf 91       	pop	r28
+}
+#endif
+
+void getNch(uint8_t count) {
+  do getch(); while (--count);
+  verifySpace();
+    1f14:	f1 cf       	rjmp	.-30     	; 0x1ef8 <verifySpace>
 
-00001f2c <appStart>:
+00001f16 <appStart>:
 
 void appStart(uint8_t rstFlags) {
   // save the reset flags in the designated register
   //  This can be saved in a main program by putting code in .init0 (which
   //  executes before normal c init code) to save R2 to a global variable.
   __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    1f2c:	28 2e       	mov	r2, r24
+    1f16:	28 2e       	mov	r2, r24
 
   watchdogConfig(WATCHDOG_OFF);
-    1f2e:	80 e0       	ldi	r24, 0x00	; 0
-    1f30:	e9 df       	rcall	.-46     	; 0x1f04 <watchdogConfig>
+    1f18:	80 e0       	ldi	r24, 0x00	; 0
+    1f1a:	ea df       	rcall	.-44     	; 0x1ef0 <watchdogConfig>
+  // Note that appstart_vec is defined so that this works with either
+  // real or virtual boot partitions.
   __asm__ __volatile__ (
-    1f32:	e4 e0       	ldi	r30, 0x04	; 4
-    1f34:	ff 27       	eor	r31, r31
-    1f36:	09 94       	ijmp
+    1f1c:	e4 e0       	ldi	r30, 0x04	; 4
+    1f1e:	ff 27       	eor	r31, r31
+    1f20:	09 94       	ijmp

+ 0 - 33
optiboot/bootloaders/optiboot/optiboot_pro_16MHz.hex

@@ -1,33 +0,0 @@
-:103E0000112494B714BE892F8D7011F0892FDDD045
-:103E100085E08093810082E08093C00088E18093F8
-:103E2000C10086E08093C20080E18093C4008EE0F0
-:103E3000B6D0259A86E020E33CEF91E030938500F0
-:103E40002093840096BBB09BFECF1D9AA89581500D
-:103E5000A9F7EE24FF24B3E0AB2EBB24B394A5E076
-:103E6000DA2EF1E1CF2E8FD0813469F48CD0082F77
-:103E70009CD0023811F482E004C0013809F471C00A
-:103E800083E079D075C0823411F484E103C08534B5
-:103E900019F485E092D06CC0853579F474D0E82EA1
-:103EA000FF2471D0082F10E0102F00270E291F29A2
-:103EB000000F111F7AD078015BC0863521F484E0B1
-:103EC0007CD080E0DECF843609F035C05CD05BD09A
-:103ED000182F59D0082FC0E0D1E055D089931C1776
-:103EE000E1F763D0053409F4FFCFF701A7BEE895E9
-:103EF00007B600FCFDCFA701A0E0B1E02C9130E0B7
-:103F000011968C91119790E0982F8827822B932BF4
-:103F10001296FA010C01B7BEE89511244E5F5F4F6F
-:103F20001A1761F7F701D7BEE89507B600FCFDCF79
-:103F3000C7BEE8951DC0843769F425D024D0082F6A
-:103F400022D033D0E701FE018591EF0114D001505A
-:103F5000D1F70EC0853739F428D08EE10CD084E932
-:103F60000AD086E08ECF813511F488E018D01DD0BC
-:103F700080E101D078CF982F8091C00085FFFCCFE1
-:103F80009093C60008958091C00087FFFCCF809178
-:103F9000C00084FD01C0A8958091C6000895E0E6A8
-:103FA000F0E098E1908380830895EDDF803219F08E
-:103FB00088E0F5DFFFCF84E1DECF1F93182FE3DF2A
-:103FC0001150E9F7F2DF1F910895282E80E0E7DF16
-:063FD000EE27FF27099413
-:023FFE000206B9
-:0400000300003E00BB
-:00000001FF

+ 0 - 586
optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst

@@ -1,586 +0,0 @@
-
-optiboot_atmega168.elf:     file format elf32-avr
-
-Sections:
-Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001d6  00003e00  00003e00  00000074  2**1
-                  CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
-                  CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
-                  CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
-                  CONTENTS, READONLY, DEBUGGING
-
-Disassembly of section .text:
-
-00003e00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    3e00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
-   */
-  ch = MCUSR;
-    3e02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-    3e04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-    3e06:	89 2f       	mov	r24, r25
-    3e08:	8d 70       	andi	r24, 0x0D	; 13
-    3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
-      appStart(ch);
-    3e0c:	89 2f       	mov	r24, r25
-    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
-
-#if LED_START_FLASHES > 0
-  // Set up Timer 1 for timeout counter
-  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    3e10:	85 e0       	ldi	r24, 0x05	; 5
-    3e12:	80 93 81 00 	sts	0x0081, r24
-  UCSRA = _BV(U2X); //Double speed mode USART
-  UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
-  UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
-  UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-#else
-  UART_SRA = _BV(U2X0); //Double speed mode USART0
-    3e16:	82 e0       	ldi	r24, 0x02	; 2
-    3e18:	80 93 c0 00 	sts	0x00C0, r24
-  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-    3e1c:	88 e1       	ldi	r24, 0x18	; 24
-    3e1e:	80 93 c1 00 	sts	0x00C1, r24
-  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-    3e22:	86 e0       	ldi	r24, 0x06	; 6
-    3e24:	80 93 c2 00 	sts	0x00C2, r24
-  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-    3e28:	80 e1       	ldi	r24, 0x10	; 16
-    3e2a:	80 93 c4 00 	sts	0x00C4, r24
-#endif
-#endif
-
-  // Set up watchdog to trigger after 500ms
-  watchdogConfig(WATCHDOG_1S);
-    3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
-
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
-  /* Set LED pin as output */
-  LED_DDR |= _BV(LED);
-    3e32:	25 9a       	sbi	0x04, 5	; 4
-    3e34:	86 e0       	ldi	r24, 0x06	; 6
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    3e36:	20 e3       	ldi	r18, 0x30	; 48
-    3e38:	3c ef       	ldi	r19, 0xFC	; 252
-    TIFR1 = _BV(TOV1);
-    3e3a:	91 e0       	ldi	r25, 0x01	; 1
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    3e3c:	30 93 85 00 	sts	0x0085, r19
-    3e40:	20 93 84 00 	sts	0x0084, r18
-    TIFR1 = _BV(TOV1);
-    3e44:	96 bb       	out	0x16, r25	; 22
-    while(!(TIFR1 & _BV(TOV1)));
-    3e46:	b0 9b       	sbis	0x16, 0	; 22
-    3e48:	fe cf       	rjmp	.-4      	; 0x3e46 <main+0x46>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-    3e4a:	1d 9a       	sbi	0x03, 5	; 3
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    3e4c:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-#endif
-    watchdogReset();
-  } while (--count);
-    3e4e:	81 50       	subi	r24, 0x01	; 1
-    3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	ee 24       	eor	r14, r14
-    3e54:	ff 24       	eor	r15, r15
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	b3 e0       	ldi	r27, 0x03	; 3
-    3e58:	ab 2e       	mov	r10, r27
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	bb 24       	eor	r11, r11
-    3e5c:	b3 94       	inc	r11
-	    } while (len -= 2);
-
-	    /*
-	     * Actually Write the buffer to flash (and wait for it to finish.)
-	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e60:	da 2e       	mov	r13, r26
-	    boot_spm_busy_wait();
-#if defined(RWWSRE)
-	    // Reenable read access to flash
-	    boot_rww_enable();
-    3e62:	f1 e1       	ldi	r31, 0x11	; 17
-    3e64:	cf 2e       	mov	r12, r31
-#endif
-
-  /* Forever loop: exits by causing WDT reset */
-  for (;;) {
-    /* get character from UART */
-    ch = getch();
-    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
-
-    if(ch == STK_GET_PARAMETER) {
-    3e68:	81 34       	cpi	r24, 0x41	; 65
-    3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
-      unsigned char which = getch();
-    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
-    3e6e:	08 2f       	mov	r16, r24
-      verifySpace();
-    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
-      /*
-       * Send optiboot version as "SW version"
-       * Note that the references to memory are optimized away.
-       */
-      if (which == 0x82) {
-    3e72:	02 38       	cpi	r16, 0x82	; 130
-    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
-	  putch(optiboot_version & 0xFF);
-    3e76:	82 e0       	ldi	r24, 0x02	; 2
-    3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
-      } else if (which == 0x81) {
-    3e7a:	01 38       	cpi	r16, 0x81	; 129
-    3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
-      } else {
-	/*
-	 * GET PARAMETER returns a generic 0x03 reply for
-         * other parameters - enough to keep Avrdude happy
-	 */
-	putch(0x03);
-    3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
-    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
-      }
-    }
-    else if(ch == STK_SET_DEVICE) {
-    3e86:	82 34       	cpi	r24, 0x42	; 66
-    3e88:	11 f4       	brne	.+4      	; 0x3e8e <main+0x8e>
-      // SET DEVICE is ignored
-      getNch(20);
-    3e8a:	84 e1       	ldi	r24, 0x14	; 20
-    3e8c:	03 c0       	rjmp	.+6      	; 0x3e94 <main+0x94>
-    }
-    else if(ch == STK_SET_DEVICE_EXT) {
-    3e8e:	85 34       	cpi	r24, 0x45	; 69
-    3e90:	19 f4       	brne	.+6      	; 0x3e98 <main+0x98>
-      // SET DEVICE EXT is ignored
-      getNch(5);
-    3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
-    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
-    }
-    else if(ch == STK_LOAD_ADDRESS) {
-    3e98:	85 35       	cpi	r24, 0x55	; 85
-    3e9a:	79 f4       	brne	.+30     	; 0x3eba <main+0xba>
-      // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e9e:	e8 2e       	mov	r14, r24
-    3ea0:	ff 24       	eor	r15, r15
-    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
-    3ea4:	08 2f       	mov	r16, r24
-    3ea6:	10 e0       	ldi	r17, 0x00	; 0
-    3ea8:	10 2f       	mov	r17, r16
-    3eaa:	00 27       	eor	r16, r16
-    3eac:	0e 29       	or	r16, r14
-    3eae:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
-#endif
-      newAddress += newAddress; // Convert from word address to byte address
-    3eb0:	00 0f       	add	r16, r16
-    3eb2:	11 1f       	adc	r17, r17
-      address = newAddress;
-      verifySpace();
-    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
-    3eb6:	78 01       	movw	r14, r16
-    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
-    }
-    else if(ch == STK_UNIVERSAL) {
-    3eba:	86 35       	cpi	r24, 0x56	; 86
-    3ebc:	21 f4       	brne	.+8      	; 0x3ec6 <main+0xc6>
-      // UNIVERSAL command is ignored
-      getNch(4);
-    3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
-      putch(0x00);
-    3ec2:	80 e0       	ldi	r24, 0x00	; 0
-    3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
-    }
-    /* Write memory, length is big endian and is in bytes */
-    else if(ch == STK_PROG_PAGE) {
-    3ec6:	84 36       	cpi	r24, 0x64	; 100
-    3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
-      // PROGRAM PAGE - we support flash programming only, not EEPROM
-      uint8_t desttype;
-      uint8_t *bufPtr;
-      pagelen_t savelength;
-
-      GETLENGTH(length);
-    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
-    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
-    3ed0:	18 2f       	mov	r17, r24
-      savelength = length;
-      desttype = getch();
-    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
-    3ed4:	08 2f       	mov	r16, r24
-    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
-    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
-
-      // read a page worth of contents
-      bufPtr = buff;
-      do *bufPtr++ = getch();
-    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
-    3edc:	89 93       	st	Y+, r24
-      while (--length);
-    3ede:	1c 17       	cp	r17, r28
-    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
-
-      // Read command terminator, start reply
-      verifySpace();
-    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
- * void writebuffer(memtype, buffer, address, length)
- */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
-{
-    switch (memtype) {
-    3ee4:	05 34       	cpi	r16, 0x45	; 69
-    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
-    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	a7 be       	out	0x37, r10	; 55
-    3eee:	e8 95       	spm
-	    boot_spm_busy_wait();
-    3ef0:	07 b6       	in	r0, 0x37	; 55
-    3ef2:	00 fc       	sbrc	r0, 0
-    3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
-    3ef6:	a7 01       	movw	r20, r14
-    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
-    3efa:	b1 e0       	ldi	r27, 0x01	; 1
-	    /*
-	     * Copy data from the buffer into the flash write buffer.
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-    3efc:	2c 91       	ld	r18, X
-    3efe:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-    3f00:	11 96       	adiw	r26, 0x01	; 1
-    3f02:	8c 91       	ld	r24, X
-    3f04:	11 97       	sbiw	r26, 0x01	; 1
-    3f06:	90 e0       	ldi	r25, 0x00	; 0
-    3f08:	98 2f       	mov	r25, r24
-    3f0a:	88 27       	eor	r24, r24
-    3f0c:	82 2b       	or	r24, r18
-    3f0e:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    3f10:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f12:	fa 01       	movw	r30, r20
-    3f14:	0c 01       	movw	r0, r24
-    3f16:	b7 be       	out	0x37, r11	; 55
-    3f18:	e8 95       	spm
-    3f1a:	11 24       	eor	r1, r1
-		addrPtr += 2;
-    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
-    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
-	    } while (len -= 2);
-    3f20:	1a 17       	cp	r17, r26
-    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
-
-	    /*
-	     * Actually Write the buffer to flash (and wait for it to finish.)
-	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3f24:	f7 01       	movw	r30, r14
-    3f26:	d7 be       	out	0x37, r13	; 55
-    3f28:	e8 95       	spm
-	    boot_spm_busy_wait();
-    3f2a:	07 b6       	in	r0, 0x37	; 55
-    3f2c:	00 fc       	sbrc	r0, 0
-    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
-#if defined(RWWSRE)
-	    // Reenable read access to flash
-	    boot_rww_enable();
-    3f30:	c7 be       	out	0x37, r12	; 55
-    3f32:	e8 95       	spm
-    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
-      writebuffer(desttype, buff, address, savelength);
-
-
-    }
-    /* Read memory block mode, length is big endian.  */
-    else if(ch == STK_READ_PAGE) {
-    3f36:	84 37       	cpi	r24, 0x74	; 116
-    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
-      uint8_t desttype;
-      GETLENGTH(length);
-    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
-    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
-    3f3e:	08 2f       	mov	r16, r24
-
-      desttype = getch();
-    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
-
-      verifySpace();
-    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
-    3f44:	e7 01       	movw	r28, r14
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#else
-	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#endif
-	    putch(ch);
-    3f46:	fe 01       	movw	r30, r28
-    3f48:	85 91       	lpm	r24, Z+
-    3f4a:	ef 01       	movw	r28, r30
-    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
-	} while (--length);
-    3f4e:	01 50       	subi	r16, 0x01	; 1
-    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
-    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
-	  
-      read_mem(desttype, address, length);
-    }
-
-    /* Get device signature bytes  */
-    else if(ch == STK_READ_SIGN) {
-    3f54:	85 37       	cpi	r24, 0x75	; 117
-    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
-      // READ SIGN - return what Avrdude wants to hear
-      verifySpace();
-    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
-      putch(SIGNATURE_0);
-    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
-      putch(SIGNATURE_1);
-    3f5e:	84 e9       	ldi	r24, 0x94	; 148
-    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
-      putch(SIGNATURE_2);
-    3f62:	86 e0       	ldi	r24, 0x06	; 6
-    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
-    }
-    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f66:	81 35       	cpi	r24, 0x51	; 81
-    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
-      // Adaboot no-wait mod
-      watchdogConfig(WATCHDOG_16MS);
-    3f6a:	88 e0       	ldi	r24, 0x08	; 8
-    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
-      verifySpace();
-    }
-    else {
-      // This covers the response to commands like STK_ENTER_PROGMODE
-      verifySpace();
-    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
-    }
-    putch(STK_OK);
-    3f70:	80 e1       	ldi	r24, 0x10	; 16
-    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
-    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
-
-00003f76 <putch>:
-  }
-}
-
-void putch(char ch) {
-    3f76:	98 2f       	mov	r25, r24
-#ifndef SOFT_UART
-  while (!(UART_SRA & _BV(UDRE0)));
-    3f78:	80 91 c0 00 	lds	r24, 0x00C0
-    3f7c:	85 ff       	sbrs	r24, 5
-    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
-  UART_UDR = ch;
-    3f80:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-    3f84:	08 95       	ret
-
-00003f86 <getch>:
-      [uartBit] "I" (UART_RX_BIT)
-    :
-      "r25"
-);
-#else
-  while(!(UART_SRA & _BV(RXC0)))
-    3f86:	80 91 c0 00 	lds	r24, 0x00C0
-    3f8a:	87 ff       	sbrs	r24, 7
-    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
-    ;
-  if (!(UART_SRA & _BV(FE0))) {
-    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
-    3f92:	84 fd       	sbrc	r24, 4
-    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    3f96:	a8 95       	wdr
-       * don't care that an invalid char is returned...)
-       */
-    watchdogReset();
-  }
-  
-  ch = UART_UDR;
-    3f98:	80 91 c6 00 	lds	r24, 0x00C6
-  LED_PIN |= _BV(LED);
-#endif
-#endif
-
-  return ch;
-}
-    3f9c:	08 95       	ret
-
-00003f9e <watchdogConfig>:
-    "wdr\n"
-  );
-}
-
-void watchdogConfig(uint8_t x) {
-  WDTCSR = _BV(WDCE) | _BV(WDE);
-    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
-    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fa2:	98 e1       	ldi	r25, 0x18	; 24
-    3fa4:	90 83       	st	Z, r25
-  WDTCSR = x;
-    3fa6:	80 83       	st	Z, r24
-}
-    3fa8:	08 95       	ret
-
-00003faa <verifySpace>:
-  do getch(); while (--count);
-  verifySpace();
-}
-
-void verifySpace() {
-  if (getch() != CRC_EOP) {
-    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
-    3fac:	80 32       	cpi	r24, 0x20	; 32
-    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
-    watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fb0:	88 e0       	ldi	r24, 0x08	; 8
-    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
-    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
-    while (1)			      // and busy-loop so that WD causes
-      ;				      //  a reset and app start.
-  }
-  putch(STK_INSYNC);
-    3fb6:	84 e1       	ldi	r24, 0x14	; 20
-}
-    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
-
-00003fba <getNch>:
-    ::[count] "M" (UART_B_VALUE)
-  );
-}
-#endif
-
-void getNch(uint8_t count) {
-    3fba:	1f 93       	push	r17
-    3fbc:	18 2f       	mov	r17, r24
-  do getch(); while (--count);
-    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
-    3fc0:	11 50       	subi	r17, 0x01	; 1
-    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
-  verifySpace();
-    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
-}
-    3fc6:	1f 91       	pop	r17
-    3fc8:	08 95       	ret
-
-00003fca <appStart>:
-
-void appStart(uint8_t rstFlags) {
-  // save the reset flags in the designated register
-  //  This can be saved in a main program by putting code in .init0 (which
-  //  executes before normal c init code) to save R2 to a global variable.
-  __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fca:	28 2e       	mov	r2, r24
-
-  watchdogConfig(WATCHDOG_OFF);
-    3fcc:	80 e0       	ldi	r24, 0x00	; 0
-    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
-  __asm__ __volatile__ (
-    3fd0:	ee 27       	eor	r30, r30
-    3fd2:	ff 27       	eor	r31, r31
-    3fd4:	09 94       	ijmp

+ 0 - 33
optiboot/bootloaders/optiboot/optiboot_pro_20mhz.hex

@@ -1,33 +0,0 @@
-:103E0000112494B714BE892F8D7011F0892FDDD045
-:103E100085E08093810082E08093C00088E18093F8
-:103E2000C10086E08093C20085E18093C4008EE0EB
-:103E3000B6D0259A86E02CE33BEF91E030938500E5
-:103E40002093840096BBB09BFECF1D9AA89581500D
-:103E5000A9F7EE24FF24B3E0AB2EBB24B394A5E076
-:103E6000DA2EF1E1CF2E8FD0813469F48CD0082F77
-:103E70009CD0023811F482E004C0013809F471C00A
-:103E800083E079D075C0823411F484E103C08534B5
-:103E900019F485E092D06CC0853579F474D0E82EA1
-:103EA000FF2471D0082F10E0102F00270E291F29A2
-:103EB000000F111F7AD078015BC0863521F484E0B1
-:103EC0007CD080E0DECF843609F035C05CD05BD09A
-:103ED000182F59D0082FC0E0D1E055D089931C1776
-:103EE000E1F763D0053409F4FFCFF701A7BEE895E9
-:103EF00007B600FCFDCFA701A0E0B1E02C9130E0B7
-:103F000011968C91119790E0982F8827822B932BF4
-:103F10001296FA010C01B7BEE89511244E5F5F4F6F
-:103F20001A1761F7F701D7BEE89507B600FCFDCF79
-:103F3000C7BEE8951DC0843769F425D024D0082F6A
-:103F400022D033D0E701FE018591EF0114D001505A
-:103F5000D1F70EC0853739F428D08EE10CD084E932
-:103F60000AD086E08ECF813511F488E018D01DD0BC
-:103F700080E101D078CF982F8091C00085FFFCCFE1
-:103F80009093C60008958091C00087FFFCCF809178
-:103F9000C00084FD01C0A8958091C6000895E0E6A8
-:103FA000F0E098E1908380830895EDDF803219F08E
-:103FB00088E0F5DFFFCF84E1DECF1F93182FE3DF2A
-:103FC0001150E9F7F2DF1F910895282E80E0E7DF16
-:063FD000EE27FF27099413
-:023FFE000206B9
-:0400000300003E00BB
-:00000001FF

+ 0 - 586
optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst

@@ -1,586 +0,0 @@
-
-optiboot_atmega168.elf:     file format elf32-avr
-
-Sections:
-Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001d6  00003e00  00003e00  00000074  2**1
-                  CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
-                  CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
-                  CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
-                  CONTENTS, READONLY, DEBUGGING
-
-Disassembly of section .text:
-
-00003e00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    3e00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
-   */
-  ch = MCUSR;
-    3e02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-    3e04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-    3e06:	89 2f       	mov	r24, r25
-    3e08:	8d 70       	andi	r24, 0x0D	; 13
-    3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
-      appStart(ch);
-    3e0c:	89 2f       	mov	r24, r25
-    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
-
-#if LED_START_FLASHES > 0
-  // Set up Timer 1 for timeout counter
-  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    3e10:	85 e0       	ldi	r24, 0x05	; 5
-    3e12:	80 93 81 00 	sts	0x0081, r24
-  UCSRA = _BV(U2X); //Double speed mode USART
-  UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
-  UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
-  UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-#else
-  UART_SRA = _BV(U2X0); //Double speed mode USART0
-    3e16:	82 e0       	ldi	r24, 0x02	; 2
-    3e18:	80 93 c0 00 	sts	0x00C0, r24
-  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-    3e1c:	88 e1       	ldi	r24, 0x18	; 24
-    3e1e:	80 93 c1 00 	sts	0x00C1, r24
-  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-    3e22:	86 e0       	ldi	r24, 0x06	; 6
-    3e24:	80 93 c2 00 	sts	0x00C2, r24
-  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-    3e28:	85 e1       	ldi	r24, 0x15	; 21
-    3e2a:	80 93 c4 00 	sts	0x00C4, r24
-#endif
-#endif
-
-  // Set up watchdog to trigger after 500ms
-  watchdogConfig(WATCHDOG_1S);
-    3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
-
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
-  /* Set LED pin as output */
-  LED_DDR |= _BV(LED);
-    3e32:	25 9a       	sbi	0x04, 5	; 4
-    3e34:	86 e0       	ldi	r24, 0x06	; 6
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    3e36:	2c e3       	ldi	r18, 0x3C	; 60
-    3e38:	3b ef       	ldi	r19, 0xFB	; 251
-    TIFR1 = _BV(TOV1);
-    3e3a:	91 e0       	ldi	r25, 0x01	; 1
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    3e3c:	30 93 85 00 	sts	0x0085, r19
-    3e40:	20 93 84 00 	sts	0x0084, r18
-    TIFR1 = _BV(TOV1);
-    3e44:	96 bb       	out	0x16, r25	; 22
-    while(!(TIFR1 & _BV(TOV1)));
-    3e46:	b0 9b       	sbis	0x16, 0	; 22
-    3e48:	fe cf       	rjmp	.-4      	; 0x3e46 <main+0x46>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-    3e4a:	1d 9a       	sbi	0x03, 5	; 3
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    3e4c:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-#endif
-    watchdogReset();
-  } while (--count);
-    3e4e:	81 50       	subi	r24, 0x01	; 1
-    3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	ee 24       	eor	r14, r14
-    3e54:	ff 24       	eor	r15, r15
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	b3 e0       	ldi	r27, 0x03	; 3
-    3e58:	ab 2e       	mov	r10, r27
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	bb 24       	eor	r11, r11
-    3e5c:	b3 94       	inc	r11
-	    } while (len -= 2);
-
-	    /*
-	     * Actually Write the buffer to flash (and wait for it to finish.)
-	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e60:	da 2e       	mov	r13, r26
-	    boot_spm_busy_wait();
-#if defined(RWWSRE)
-	    // Reenable read access to flash
-	    boot_rww_enable();
-    3e62:	f1 e1       	ldi	r31, 0x11	; 17
-    3e64:	cf 2e       	mov	r12, r31
-#endif
-
-  /* Forever loop: exits by causing WDT reset */
-  for (;;) {
-    /* get character from UART */
-    ch = getch();
-    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
-
-    if(ch == STK_GET_PARAMETER) {
-    3e68:	81 34       	cpi	r24, 0x41	; 65
-    3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
-      unsigned char which = getch();
-    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
-    3e6e:	08 2f       	mov	r16, r24
-      verifySpace();
-    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
-      /*
-       * Send optiboot version as "SW version"
-       * Note that the references to memory are optimized away.
-       */
-      if (which == 0x82) {
-    3e72:	02 38       	cpi	r16, 0x82	; 130
-    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
-	  putch(optiboot_version & 0xFF);
-    3e76:	82 e0       	ldi	r24, 0x02	; 2
-    3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
-      } else if (which == 0x81) {
-    3e7a:	01 38       	cpi	r16, 0x81	; 129
-    3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
-      } else {
-	/*
-	 * GET PARAMETER returns a generic 0x03 reply for
-         * other parameters - enough to keep Avrdude happy
-	 */
-	putch(0x03);
-    3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
-    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
-      }
-    }
-    else if(ch == STK_SET_DEVICE) {
-    3e86:	82 34       	cpi	r24, 0x42	; 66
-    3e88:	11 f4       	brne	.+4      	; 0x3e8e <main+0x8e>
-      // SET DEVICE is ignored
-      getNch(20);
-    3e8a:	84 e1       	ldi	r24, 0x14	; 20
-    3e8c:	03 c0       	rjmp	.+6      	; 0x3e94 <main+0x94>
-    }
-    else if(ch == STK_SET_DEVICE_EXT) {
-    3e8e:	85 34       	cpi	r24, 0x45	; 69
-    3e90:	19 f4       	brne	.+6      	; 0x3e98 <main+0x98>
-      // SET DEVICE EXT is ignored
-      getNch(5);
-    3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
-    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
-    }
-    else if(ch == STK_LOAD_ADDRESS) {
-    3e98:	85 35       	cpi	r24, 0x55	; 85
-    3e9a:	79 f4       	brne	.+30     	; 0x3eba <main+0xba>
-      // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e9e:	e8 2e       	mov	r14, r24
-    3ea0:	ff 24       	eor	r15, r15
-    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
-    3ea4:	08 2f       	mov	r16, r24
-    3ea6:	10 e0       	ldi	r17, 0x00	; 0
-    3ea8:	10 2f       	mov	r17, r16
-    3eaa:	00 27       	eor	r16, r16
-    3eac:	0e 29       	or	r16, r14
-    3eae:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
-#endif
-      newAddress += newAddress; // Convert from word address to byte address
-    3eb0:	00 0f       	add	r16, r16
-    3eb2:	11 1f       	adc	r17, r17
-      address = newAddress;
-      verifySpace();
-    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
-    3eb6:	78 01       	movw	r14, r16
-    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
-    }
-    else if(ch == STK_UNIVERSAL) {
-    3eba:	86 35       	cpi	r24, 0x56	; 86
-    3ebc:	21 f4       	brne	.+8      	; 0x3ec6 <main+0xc6>
-      // UNIVERSAL command is ignored
-      getNch(4);
-    3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
-      putch(0x00);
-    3ec2:	80 e0       	ldi	r24, 0x00	; 0
-    3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
-    }
-    /* Write memory, length is big endian and is in bytes */
-    else if(ch == STK_PROG_PAGE) {
-    3ec6:	84 36       	cpi	r24, 0x64	; 100
-    3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
-      // PROGRAM PAGE - we support flash programming only, not EEPROM
-      uint8_t desttype;
-      uint8_t *bufPtr;
-      pagelen_t savelength;
-
-      GETLENGTH(length);
-    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
-    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
-    3ed0:	18 2f       	mov	r17, r24
-      savelength = length;
-      desttype = getch();
-    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
-    3ed4:	08 2f       	mov	r16, r24
-    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
-    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
-
-      // read a page worth of contents
-      bufPtr = buff;
-      do *bufPtr++ = getch();
-    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
-    3edc:	89 93       	st	Y+, r24
-      while (--length);
-    3ede:	1c 17       	cp	r17, r28
-    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
-
-      // Read command terminator, start reply
-      verifySpace();
-    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
- * void writebuffer(memtype, buffer, address, length)
- */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
-{
-    switch (memtype) {
-    3ee4:	05 34       	cpi	r16, 0x45	; 69
-    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
-    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	a7 be       	out	0x37, r10	; 55
-    3eee:	e8 95       	spm
-	    boot_spm_busy_wait();
-    3ef0:	07 b6       	in	r0, 0x37	; 55
-    3ef2:	00 fc       	sbrc	r0, 0
-    3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
-    3ef6:	a7 01       	movw	r20, r14
-    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
-    3efa:	b1 e0       	ldi	r27, 0x01	; 1
-	    /*
-	     * Copy data from the buffer into the flash write buffer.
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-    3efc:	2c 91       	ld	r18, X
-    3efe:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-    3f00:	11 96       	adiw	r26, 0x01	; 1
-    3f02:	8c 91       	ld	r24, X
-    3f04:	11 97       	sbiw	r26, 0x01	; 1
-    3f06:	90 e0       	ldi	r25, 0x00	; 0
-    3f08:	98 2f       	mov	r25, r24
-    3f0a:	88 27       	eor	r24, r24
-    3f0c:	82 2b       	or	r24, r18
-    3f0e:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    3f10:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f12:	fa 01       	movw	r30, r20
-    3f14:	0c 01       	movw	r0, r24
-    3f16:	b7 be       	out	0x37, r11	; 55
-    3f18:	e8 95       	spm
-    3f1a:	11 24       	eor	r1, r1
-		addrPtr += 2;
-    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
-    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
-	    } while (len -= 2);
-    3f20:	1a 17       	cp	r17, r26
-    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
-
-	    /*
-	     * Actually Write the buffer to flash (and wait for it to finish.)
-	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3f24:	f7 01       	movw	r30, r14
-    3f26:	d7 be       	out	0x37, r13	; 55
-    3f28:	e8 95       	spm
-	    boot_spm_busy_wait();
-    3f2a:	07 b6       	in	r0, 0x37	; 55
-    3f2c:	00 fc       	sbrc	r0, 0
-    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
-#if defined(RWWSRE)
-	    // Reenable read access to flash
-	    boot_rww_enable();
-    3f30:	c7 be       	out	0x37, r12	; 55
-    3f32:	e8 95       	spm
-    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
-      writebuffer(desttype, buff, address, savelength);
-
-
-    }
-    /* Read memory block mode, length is big endian.  */
-    else if(ch == STK_READ_PAGE) {
-    3f36:	84 37       	cpi	r24, 0x74	; 116
-    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
-      uint8_t desttype;
-      GETLENGTH(length);
-    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
-    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
-    3f3e:	08 2f       	mov	r16, r24
-
-      desttype = getch();
-    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
-
-      verifySpace();
-    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
-    3f44:	e7 01       	movw	r28, r14
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#else
-	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#endif
-	    putch(ch);
-    3f46:	fe 01       	movw	r30, r28
-    3f48:	85 91       	lpm	r24, Z+
-    3f4a:	ef 01       	movw	r28, r30
-    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
-	} while (--length);
-    3f4e:	01 50       	subi	r16, 0x01	; 1
-    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
-    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
-	  
-      read_mem(desttype, address, length);
-    }
-
-    /* Get device signature bytes  */
-    else if(ch == STK_READ_SIGN) {
-    3f54:	85 37       	cpi	r24, 0x75	; 117
-    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
-      // READ SIGN - return what Avrdude wants to hear
-      verifySpace();
-    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
-      putch(SIGNATURE_0);
-    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
-      putch(SIGNATURE_1);
-    3f5e:	84 e9       	ldi	r24, 0x94	; 148
-    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
-      putch(SIGNATURE_2);
-    3f62:	86 e0       	ldi	r24, 0x06	; 6
-    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
-    }
-    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f66:	81 35       	cpi	r24, 0x51	; 81
-    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
-      // Adaboot no-wait mod
-      watchdogConfig(WATCHDOG_16MS);
-    3f6a:	88 e0       	ldi	r24, 0x08	; 8
-    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
-      verifySpace();
-    }
-    else {
-      // This covers the response to commands like STK_ENTER_PROGMODE
-      verifySpace();
-    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
-    }
-    putch(STK_OK);
-    3f70:	80 e1       	ldi	r24, 0x10	; 16
-    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
-    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
-
-00003f76 <putch>:
-  }
-}
-
-void putch(char ch) {
-    3f76:	98 2f       	mov	r25, r24
-#ifndef SOFT_UART
-  while (!(UART_SRA & _BV(UDRE0)));
-    3f78:	80 91 c0 00 	lds	r24, 0x00C0
-    3f7c:	85 ff       	sbrs	r24, 5
-    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
-  UART_UDR = ch;
-    3f80:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-    3f84:	08 95       	ret
-
-00003f86 <getch>:
-      [uartBit] "I" (UART_RX_BIT)
-    :
-      "r25"
-);
-#else
-  while(!(UART_SRA & _BV(RXC0)))
-    3f86:	80 91 c0 00 	lds	r24, 0x00C0
-    3f8a:	87 ff       	sbrs	r24, 7
-    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
-    ;
-  if (!(UART_SRA & _BV(FE0))) {
-    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
-    3f92:	84 fd       	sbrc	r24, 4
-    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    3f96:	a8 95       	wdr
-       * don't care that an invalid char is returned...)
-       */
-    watchdogReset();
-  }
-  
-  ch = UART_UDR;
-    3f98:	80 91 c6 00 	lds	r24, 0x00C6
-  LED_PIN |= _BV(LED);
-#endif
-#endif
-
-  return ch;
-}
-    3f9c:	08 95       	ret
-
-00003f9e <watchdogConfig>:
-    "wdr\n"
-  );
-}
-
-void watchdogConfig(uint8_t x) {
-  WDTCSR = _BV(WDCE) | _BV(WDE);
-    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
-    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fa2:	98 e1       	ldi	r25, 0x18	; 24
-    3fa4:	90 83       	st	Z, r25
-  WDTCSR = x;
-    3fa6:	80 83       	st	Z, r24
-}
-    3fa8:	08 95       	ret
-
-00003faa <verifySpace>:
-  do getch(); while (--count);
-  verifySpace();
-}
-
-void verifySpace() {
-  if (getch() != CRC_EOP) {
-    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
-    3fac:	80 32       	cpi	r24, 0x20	; 32
-    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
-    watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fb0:	88 e0       	ldi	r24, 0x08	; 8
-    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
-    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
-    while (1)			      // and busy-loop so that WD causes
-      ;				      //  a reset and app start.
-  }
-  putch(STK_INSYNC);
-    3fb6:	84 e1       	ldi	r24, 0x14	; 20
-}
-    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
-
-00003fba <getNch>:
-    ::[count] "M" (UART_B_VALUE)
-  );
-}
-#endif
-
-void getNch(uint8_t count) {
-    3fba:	1f 93       	push	r17
-    3fbc:	18 2f       	mov	r17, r24
-  do getch(); while (--count);
-    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
-    3fc0:	11 50       	subi	r17, 0x01	; 1
-    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
-  verifySpace();
-    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
-}
-    3fc6:	1f 91       	pop	r17
-    3fc8:	08 95       	ret
-
-00003fca <appStart>:
-
-void appStart(uint8_t rstFlags) {
-  // save the reset flags in the designated register
-  //  This can be saved in a main program by putting code in .init0 (which
-  //  executes before normal c init code) to save R2 to a global variable.
-  __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fca:	28 2e       	mov	r2, r24
-
-  watchdogConfig(WATCHDOG_OFF);
-    3fcc:	80 e0       	ldi	r24, 0x00	; 0
-    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
-  __asm__ __volatile__ (
-    3fd0:	ee 27       	eor	r30, r30
-    3fd2:	ff 27       	eor	r31, r31
-    3fd4:	09 94       	ijmp

+ 0 - 33
optiboot/bootloaders/optiboot/optiboot_pro_8MHz.hex

@@ -1,33 +0,0 @@
-:103E0000112494B714BE892F8D7011F0892FDDD045
-:103E100085E08093810082E08093C00088E18093F8
-:103E2000C10086E08093C20088E08093C4008EE0E9
-:103E3000B6D0259A86E028E13EEF91E030938500E8
-:103E40002093840096BBB09BFECF1D9AA89581500D
-:103E5000A9F7EE24FF24B3E0AB2EBB24B394A5E076
-:103E6000DA2EF1E1CF2E8FD0813469F48CD0082F77
-:103E70009CD0023811F482E004C0013809F471C00A
-:103E800083E079D075C0823411F484E103C08534B5
-:103E900019F485E092D06CC0853579F474D0E82EA1
-:103EA000FF2471D0082F10E0102F00270E291F29A2
-:103EB000000F111F7AD078015BC0863521F484E0B1
-:103EC0007CD080E0DECF843609F035C05CD05BD09A
-:103ED000182F59D0082FC0E0D1E055D089931C1776
-:103EE000E1F763D0053409F4FFCFF701A7BEE895E9
-:103EF00007B600FCFDCFA701A0E0B1E02C9130E0B7
-:103F000011968C91119790E0982F8827822B932BF4
-:103F10001296FA010C01B7BEE89511244E5F5F4F6F
-:103F20001A1761F7F701D7BEE89507B600FCFDCF79
-:103F3000C7BEE8951DC0843769F425D024D0082F6A
-:103F400022D033D0E701FE018591EF0114D001505A
-:103F5000D1F70EC0853739F428D08EE10CD084E932
-:103F60000AD086E08ECF813511F488E018D01DD0BC
-:103F700080E101D078CF982F8091C00085FFFCCFE1
-:103F80009093C60008958091C00087FFFCCF809178
-:103F9000C00084FD01C0A8958091C6000895E0E6A8
-:103FA000F0E098E1908380830895EDDF803219F08E
-:103FB00088E0F5DFFFCF84E1DECF1F93182FE3DF2A
-:103FC0001150E9F7F2DF1F910895282E80E0E7DF16
-:063FD000EE27FF27099413
-:023FFE000206B9
-:0400000300003E00BB
-:00000001FF

+ 0 - 586
optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst

@@ -1,586 +0,0 @@
-
-optiboot_atmega168.elf:     file format elf32-avr
-
-Sections:
-Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001d6  00003e00  00003e00  00000074  2**1
-                  CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .version      00000002  00003ffe  00003ffe  0000024a  2**0
-                  CONTENTS, ALLOC, LOAD, READONLY, DATA
-  2 .debug_aranges 00000028  00000000  00000000  0000024c  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  3 .debug_pubnames 00000074  00000000  00000000  00000274  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  4 .debug_info   000003ea  00000000  00000000  000002e8  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  5 .debug_abbrev 000001ef  00000000  00000000  000006d2  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  6 .debug_line   00000423  00000000  00000000  000008c1  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  7 .debug_frame  00000080  00000000  00000000  00000ce4  2**2
-                  CONTENTS, READONLY, DEBUGGING
-  8 .debug_str    0000017c  00000000  00000000  00000d64  2**0
-                  CONTENTS, READONLY, DEBUGGING
-  9 .debug_loc    00000300  00000000  00000000  00000ee0  2**0
-                  CONTENTS, READONLY, DEBUGGING
- 10 .debug_ranges 000000b8  00000000  00000000  000011e0  2**0
-                  CONTENTS, READONLY, DEBUGGING
-
-Disassembly of section .text:
-
-00003e00 <main>:
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    3e00:	11 24       	eor	r1, r1
-   * modified Adaboot no-wait mod.
-   * Pass the reset reason to app.  Also, it appears that an Uno poweron
-   * can leave multiple reset flags set; we only want the bootloader to
-   * run on an 'external reset only' status
-   */
-  ch = MCUSR;
-    3e02:	94 b7       	in	r25, 0x34	; 52
-  MCUSR = 0;
-    3e04:	14 be       	out	0x34, r1	; 52
-  if (ch & (_BV(WDRF) | _BV(BORF) | _BV(PORF)))
-    3e06:	89 2f       	mov	r24, r25
-    3e08:	8d 70       	andi	r24, 0x0D	; 13
-    3e0a:	11 f0       	breq	.+4      	; 0x3e10 <main+0x10>
-      appStart(ch);
-    3e0c:	89 2f       	mov	r24, r25
-    3e0e:	dd d0       	rcall	.+442    	; 0x3fca <appStart>
-
-#if LED_START_FLASHES > 0
-  // Set up Timer 1 for timeout counter
-  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
-    3e10:	85 e0       	ldi	r24, 0x05	; 5
-    3e12:	80 93 81 00 	sts	0x0081, r24
-  UCSRA = _BV(U2X); //Double speed mode USART
-  UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
-  UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
-  UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-#else
-  UART_SRA = _BV(U2X0); //Double speed mode USART0
-    3e16:	82 e0       	ldi	r24, 0x02	; 2
-    3e18:	80 93 c0 00 	sts	0x00C0, r24
-  UART_SRB = _BV(RXEN0) | _BV(TXEN0);
-    3e1c:	88 e1       	ldi	r24, 0x18	; 24
-    3e1e:	80 93 c1 00 	sts	0x00C1, r24
-  UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
-    3e22:	86 e0       	ldi	r24, 0x06	; 6
-    3e24:	80 93 c2 00 	sts	0x00C2, r24
-  UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
-    3e28:	88 e0       	ldi	r24, 0x08	; 8
-    3e2a:	80 93 c4 00 	sts	0x00C4, r24
-#endif
-#endif
-
-  // Set up watchdog to trigger after 500ms
-  watchdogConfig(WATCHDOG_1S);
-    3e2e:	8e e0       	ldi	r24, 0x0E	; 14
-    3e30:	b6 d0       	rcall	.+364    	; 0x3f9e <watchdogConfig>
-
-#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH)
-  /* Set LED pin as output */
-  LED_DDR |= _BV(LED);
-    3e32:	25 9a       	sbi	0x04, 5	; 4
-    3e34:	86 e0       	ldi	r24, 0x06	; 6
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    3e36:	28 e1       	ldi	r18, 0x18	; 24
-    3e38:	3e ef       	ldi	r19, 0xFE	; 254
-    TIFR1 = _BV(TOV1);
-    3e3a:	91 e0       	ldi	r25, 0x01	; 1
-}
-
-#if LED_START_FLASHES > 0
-void flash_led(uint8_t count) {
-  do {
-    TCNT1 = -(F_CPU/(1024*16));
-    3e3c:	30 93 85 00 	sts	0x0085, r19
-    3e40:	20 93 84 00 	sts	0x0084, r18
-    TIFR1 = _BV(TOV1);
-    3e44:	96 bb       	out	0x16, r25	; 22
-    while(!(TIFR1 & _BV(TOV1)));
-    3e46:	b0 9b       	sbis	0x16, 0	; 22
-    3e48:	fe cf       	rjmp	.-4      	; 0x3e46 <main+0x46>
-#if defined(__AVR_ATmega8__)  || defined (__AVR_ATmega32__)
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-    3e4a:	1d 9a       	sbi	0x03, 5	; 3
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    3e4c:	a8 95       	wdr
-    LED_PORT ^= _BV(LED);
-#else
-    LED_PIN |= _BV(LED);
-#endif
-    watchdogReset();
-  } while (--count);
-    3e4e:	81 50       	subi	r24, 0x01	; 1
-    3e50:	a9 f7       	brne	.-22     	; 0x3e3c <main+0x3c>
-    3e52:	ee 24       	eor	r14, r14
-    3e54:	ff 24       	eor	r15, r15
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3e56:	b3 e0       	ldi	r27, 0x03	; 3
-    3e58:	ab 2e       	mov	r10, r27
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3e5a:	bb 24       	eor	r11, r11
-    3e5c:	b3 94       	inc	r11
-	    } while (len -= 2);
-
-	    /*
-	     * Actually Write the buffer to flash (and wait for it to finish.)
-	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3e5e:	a5 e0       	ldi	r26, 0x05	; 5
-    3e60:	da 2e       	mov	r13, r26
-	    boot_spm_busy_wait();
-#if defined(RWWSRE)
-	    // Reenable read access to flash
-	    boot_rww_enable();
-    3e62:	f1 e1       	ldi	r31, 0x11	; 17
-    3e64:	cf 2e       	mov	r12, r31
-#endif
-
-  /* Forever loop: exits by causing WDT reset */
-  for (;;) {
-    /* get character from UART */
-    ch = getch();
-    3e66:	8f d0       	rcall	.+286    	; 0x3f86 <getch>
-
-    if(ch == STK_GET_PARAMETER) {
-    3e68:	81 34       	cpi	r24, 0x41	; 65
-    3e6a:	69 f4       	brne	.+26     	; 0x3e86 <main+0x86>
-      unsigned char which = getch();
-    3e6c:	8c d0       	rcall	.+280    	; 0x3f86 <getch>
-    3e6e:	08 2f       	mov	r16, r24
-      verifySpace();
-    3e70:	9c d0       	rcall	.+312    	; 0x3faa <verifySpace>
-      /*
-       * Send optiboot version as "SW version"
-       * Note that the references to memory are optimized away.
-       */
-      if (which == 0x82) {
-    3e72:	02 38       	cpi	r16, 0x82	; 130
-    3e74:	11 f4       	brne	.+4      	; 0x3e7a <main+0x7a>
-	  putch(optiboot_version & 0xFF);
-    3e76:	82 e0       	ldi	r24, 0x02	; 2
-    3e78:	04 c0       	rjmp	.+8      	; 0x3e82 <main+0x82>
-      } else if (which == 0x81) {
-    3e7a:	01 38       	cpi	r16, 0x81	; 129
-    3e7c:	09 f4       	brne	.+2      	; 0x3e80 <main+0x80>
-    3e7e:	71 c0       	rjmp	.+226    	; 0x3f62 <main+0x162>
-      } else {
-	/*
-	 * GET PARAMETER returns a generic 0x03 reply for
-         * other parameters - enough to keep Avrdude happy
-	 */
-	putch(0x03);
-    3e80:	83 e0       	ldi	r24, 0x03	; 3
-    3e82:	79 d0       	rcall	.+242    	; 0x3f76 <putch>
-    3e84:	75 c0       	rjmp	.+234    	; 0x3f70 <main+0x170>
-      }
-    }
-    else if(ch == STK_SET_DEVICE) {
-    3e86:	82 34       	cpi	r24, 0x42	; 66
-    3e88:	11 f4       	brne	.+4      	; 0x3e8e <main+0x8e>
-      // SET DEVICE is ignored
-      getNch(20);
-    3e8a:	84 e1       	ldi	r24, 0x14	; 20
-    3e8c:	03 c0       	rjmp	.+6      	; 0x3e94 <main+0x94>
-    }
-    else if(ch == STK_SET_DEVICE_EXT) {
-    3e8e:	85 34       	cpi	r24, 0x45	; 69
-    3e90:	19 f4       	brne	.+6      	; 0x3e98 <main+0x98>
-      // SET DEVICE EXT is ignored
-      getNch(5);
-    3e92:	85 e0       	ldi	r24, 0x05	; 5
-    3e94:	92 d0       	rcall	.+292    	; 0x3fba <getNch>
-    3e96:	6c c0       	rjmp	.+216    	; 0x3f70 <main+0x170>
-    }
-    else if(ch == STK_LOAD_ADDRESS) {
-    3e98:	85 35       	cpi	r24, 0x55	; 85
-    3e9a:	79 f4       	brne	.+30     	; 0x3eba <main+0xba>
-      // LOAD ADDRESS
-      uint16_t newAddress;
-      newAddress = getch();
-    3e9c:	74 d0       	rcall	.+232    	; 0x3f86 <getch>
-      newAddress = (newAddress & 0xff) | (getch() << 8);
-    3e9e:	e8 2e       	mov	r14, r24
-    3ea0:	ff 24       	eor	r15, r15
-    3ea2:	71 d0       	rcall	.+226    	; 0x3f86 <getch>
-    3ea4:	08 2f       	mov	r16, r24
-    3ea6:	10 e0       	ldi	r17, 0x00	; 0
-    3ea8:	10 2f       	mov	r17, r16
-    3eaa:	00 27       	eor	r16, r16
-    3eac:	0e 29       	or	r16, r14
-    3eae:	1f 29       	or	r17, r15
-#ifdef RAMPZ
-      // Transfer top bit to RAMPZ
-      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
-#endif
-      newAddress += newAddress; // Convert from word address to byte address
-    3eb0:	00 0f       	add	r16, r16
-    3eb2:	11 1f       	adc	r17, r17
-      address = newAddress;
-      verifySpace();
-    3eb4:	7a d0       	rcall	.+244    	; 0x3faa <verifySpace>
-    3eb6:	78 01       	movw	r14, r16
-    3eb8:	5b c0       	rjmp	.+182    	; 0x3f70 <main+0x170>
-    }
-    else if(ch == STK_UNIVERSAL) {
-    3eba:	86 35       	cpi	r24, 0x56	; 86
-    3ebc:	21 f4       	brne	.+8      	; 0x3ec6 <main+0xc6>
-      // UNIVERSAL command is ignored
-      getNch(4);
-    3ebe:	84 e0       	ldi	r24, 0x04	; 4
-    3ec0:	7c d0       	rcall	.+248    	; 0x3fba <getNch>
-      putch(0x00);
-    3ec2:	80 e0       	ldi	r24, 0x00	; 0
-    3ec4:	de cf       	rjmp	.-68     	; 0x3e82 <main+0x82>
-    }
-    /* Write memory, length is big endian and is in bytes */
-    else if(ch == STK_PROG_PAGE) {
-    3ec6:	84 36       	cpi	r24, 0x64	; 100
-    3ec8:	09 f0       	breq	.+2      	; 0x3ecc <main+0xcc>
-    3eca:	35 c0       	rjmp	.+106    	; 0x3f36 <main+0x136>
-      // PROGRAM PAGE - we support flash programming only, not EEPROM
-      uint8_t desttype;
-      uint8_t *bufPtr;
-      pagelen_t savelength;
-
-      GETLENGTH(length);
-    3ecc:	5c d0       	rcall	.+184    	; 0x3f86 <getch>
-    3ece:	5b d0       	rcall	.+182    	; 0x3f86 <getch>
-    3ed0:	18 2f       	mov	r17, r24
-      savelength = length;
-      desttype = getch();
-    3ed2:	59 d0       	rcall	.+178    	; 0x3f86 <getch>
-    3ed4:	08 2f       	mov	r16, r24
-    3ed6:	c0 e0       	ldi	r28, 0x00	; 0
-    3ed8:	d1 e0       	ldi	r29, 0x01	; 1
-
-      // read a page worth of contents
-      bufPtr = buff;
-      do *bufPtr++ = getch();
-    3eda:	55 d0       	rcall	.+170    	; 0x3f86 <getch>
-    3edc:	89 93       	st	Y+, r24
-      while (--length);
-    3ede:	1c 17       	cp	r17, r28
-    3ee0:	e1 f7       	brne	.-8      	; 0x3eda <main+0xda>
-
-      // Read command terminator, start reply
-      verifySpace();
-    3ee2:	63 d0       	rcall	.+198    	; 0x3faa <verifySpace>
- * void writebuffer(memtype, buffer, address, length)
- */
-static inline void writebuffer(int8_t memtype, uint8_t *mybuff,
-			       uint16_t address, pagelen_t len)
-{
-    switch (memtype) {
-    3ee4:	05 34       	cpi	r16, 0x45	; 69
-    3ee6:	09 f4       	brne	.+2      	; 0x3eea <main+0xea>
-    3ee8:	ff cf       	rjmp	.-2      	; 0x3ee8 <main+0xe8>
-	     * Start the page erase and wait for it to finish.  There
-	     * used to be code to do this while receiving the data over
-	     * the serial link, but the performance improvement was slight,
-	     * and we needed the space back.
-	     */
-	    __boot_page_erase_short((uint16_t)(void*)address);
-    3eea:	f7 01       	movw	r30, r14
-    3eec:	a7 be       	out	0x37, r10	; 55
-    3eee:	e8 95       	spm
-	    boot_spm_busy_wait();
-    3ef0:	07 b6       	in	r0, 0x37	; 55
-    3ef2:	00 fc       	sbrc	r0, 0
-    3ef4:	fd cf       	rjmp	.-6      	; 0x3ef0 <main+0xf0>
-    3ef6:	a7 01       	movw	r20, r14
-    3ef8:	a0 e0       	ldi	r26, 0x00	; 0
-    3efa:	b1 e0       	ldi	r27, 0x01	; 1
-	    /*
-	     * Copy data from the buffer into the flash write buffer.
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-    3efc:	2c 91       	ld	r18, X
-    3efe:	30 e0       	ldi	r19, 0x00	; 0
-		a |= (*bufPtr++) << 8;
-    3f00:	11 96       	adiw	r26, 0x01	; 1
-    3f02:	8c 91       	ld	r24, X
-    3f04:	11 97       	sbiw	r26, 0x01	; 1
-    3f06:	90 e0       	ldi	r25, 0x00	; 0
-    3f08:	98 2f       	mov	r25, r24
-    3f0a:	88 27       	eor	r24, r24
-    3f0c:	82 2b       	or	r24, r18
-    3f0e:	93 2b       	or	r25, r19
-#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
-#endif
-
-
-/* main program starts here */
-int main(void) {
-    3f10:	12 96       	adiw	r26, 0x02	; 2
-	     */
-	    do {
-		uint16_t a;
-		a = *bufPtr++;
-		a |= (*bufPtr++) << 8;
-		__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
-    3f12:	fa 01       	movw	r30, r20
-    3f14:	0c 01       	movw	r0, r24
-    3f16:	b7 be       	out	0x37, r11	; 55
-    3f18:	e8 95       	spm
-    3f1a:	11 24       	eor	r1, r1
-		addrPtr += 2;
-    3f1c:	4e 5f       	subi	r20, 0xFE	; 254
-    3f1e:	5f 4f       	sbci	r21, 0xFF	; 255
-	    } while (len -= 2);
-    3f20:	1a 17       	cp	r17, r26
-    3f22:	61 f7       	brne	.-40     	; 0x3efc <main+0xfc>
-
-	    /*
-	     * Actually Write the buffer to flash (and wait for it to finish.)
-	     */
-	    __boot_page_write_short((uint16_t)(void*)address);
-    3f24:	f7 01       	movw	r30, r14
-    3f26:	d7 be       	out	0x37, r13	; 55
-    3f28:	e8 95       	spm
-	    boot_spm_busy_wait();
-    3f2a:	07 b6       	in	r0, 0x37	; 55
-    3f2c:	00 fc       	sbrc	r0, 0
-    3f2e:	fd cf       	rjmp	.-6      	; 0x3f2a <main+0x12a>
-#if defined(RWWSRE)
-	    // Reenable read access to flash
-	    boot_rww_enable();
-    3f30:	c7 be       	out	0x37, r12	; 55
-    3f32:	e8 95       	spm
-    3f34:	1d c0       	rjmp	.+58     	; 0x3f70 <main+0x170>
-      writebuffer(desttype, buff, address, savelength);
-
-
-    }
-    /* Read memory block mode, length is big endian.  */
-    else if(ch == STK_READ_PAGE) {
-    3f36:	84 37       	cpi	r24, 0x74	; 116
-    3f38:	69 f4       	brne	.+26     	; 0x3f54 <main+0x154>
-      uint8_t desttype;
-      GETLENGTH(length);
-    3f3a:	25 d0       	rcall	.+74     	; 0x3f86 <getch>
-    3f3c:	24 d0       	rcall	.+72     	; 0x3f86 <getch>
-    3f3e:	08 2f       	mov	r16, r24
-
-      desttype = getch();
-    3f40:	22 d0       	rcall	.+68     	; 0x3f86 <getch>
-
-      verifySpace();
-    3f42:	33 d0       	rcall	.+102    	; 0x3faa <verifySpace>
-    3f44:	e7 01       	movw	r28, r14
-	    __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#else
-	    // read a Flash byte and increment the address
-	    __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address): "1" (address));
-#endif
-	    putch(ch);
-    3f46:	fe 01       	movw	r30, r28
-    3f48:	85 91       	lpm	r24, Z+
-    3f4a:	ef 01       	movw	r28, r30
-    3f4c:	14 d0       	rcall	.+40     	; 0x3f76 <putch>
-	} while (--length);
-    3f4e:	01 50       	subi	r16, 0x01	; 1
-    3f50:	d1 f7       	brne	.-12     	; 0x3f46 <main+0x146>
-    3f52:	0e c0       	rjmp	.+28     	; 0x3f70 <main+0x170>
-	  
-      read_mem(desttype, address, length);
-    }
-
-    /* Get device signature bytes  */
-    else if(ch == STK_READ_SIGN) {
-    3f54:	85 37       	cpi	r24, 0x75	; 117
-    3f56:	39 f4       	brne	.+14     	; 0x3f66 <main+0x166>
-      // READ SIGN - return what Avrdude wants to hear
-      verifySpace();
-    3f58:	28 d0       	rcall	.+80     	; 0x3faa <verifySpace>
-      putch(SIGNATURE_0);
-    3f5a:	8e e1       	ldi	r24, 0x1E	; 30
-    3f5c:	0c d0       	rcall	.+24     	; 0x3f76 <putch>
-      putch(SIGNATURE_1);
-    3f5e:	84 e9       	ldi	r24, 0x94	; 148
-    3f60:	0a d0       	rcall	.+20     	; 0x3f76 <putch>
-      putch(SIGNATURE_2);
-    3f62:	86 e0       	ldi	r24, 0x06	; 6
-    3f64:	8e cf       	rjmp	.-228    	; 0x3e82 <main+0x82>
-    }
-    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
-    3f66:	81 35       	cpi	r24, 0x51	; 81
-    3f68:	11 f4       	brne	.+4      	; 0x3f6e <main+0x16e>
-      // Adaboot no-wait mod
-      watchdogConfig(WATCHDOG_16MS);
-    3f6a:	88 e0       	ldi	r24, 0x08	; 8
-    3f6c:	18 d0       	rcall	.+48     	; 0x3f9e <watchdogConfig>
-      verifySpace();
-    }
-    else {
-      // This covers the response to commands like STK_ENTER_PROGMODE
-      verifySpace();
-    3f6e:	1d d0       	rcall	.+58     	; 0x3faa <verifySpace>
-    }
-    putch(STK_OK);
-    3f70:	80 e1       	ldi	r24, 0x10	; 16
-    3f72:	01 d0       	rcall	.+2      	; 0x3f76 <putch>
-    3f74:	78 cf       	rjmp	.-272    	; 0x3e66 <main+0x66>
-
-00003f76 <putch>:
-  }
-}
-
-void putch(char ch) {
-    3f76:	98 2f       	mov	r25, r24
-#ifndef SOFT_UART
-  while (!(UART_SRA & _BV(UDRE0)));
-    3f78:	80 91 c0 00 	lds	r24, 0x00C0
-    3f7c:	85 ff       	sbrs	r24, 5
-    3f7e:	fc cf       	rjmp	.-8      	; 0x3f78 <putch+0x2>
-  UART_UDR = ch;
-    3f80:	90 93 c6 00 	sts	0x00C6, r25
-      [uartBit] "I" (UART_TX_BIT)
-    :
-      "r25"
-  );
-#endif
-}
-    3f84:	08 95       	ret
-
-00003f86 <getch>:
-      [uartBit] "I" (UART_RX_BIT)
-    :
-      "r25"
-);
-#else
-  while(!(UART_SRA & _BV(RXC0)))
-    3f86:	80 91 c0 00 	lds	r24, 0x00C0
-    3f8a:	87 ff       	sbrs	r24, 7
-    3f8c:	fc cf       	rjmp	.-8      	; 0x3f86 <getch>
-    ;
-  if (!(UART_SRA & _BV(FE0))) {
-    3f8e:	80 91 c0 00 	lds	r24, 0x00C0
-    3f92:	84 fd       	sbrc	r24, 4
-    3f94:	01 c0       	rjmp	.+2      	; 0x3f98 <getch+0x12>
-}
-#endif
-
-// Watchdog functions. These are only safe with interrupts turned off.
-void watchdogReset() {
-  __asm__ __volatile__ (
-    3f96:	a8 95       	wdr
-       * don't care that an invalid char is returned...)
-       */
-    watchdogReset();
-  }
-  
-  ch = UART_UDR;
-    3f98:	80 91 c6 00 	lds	r24, 0x00C6
-  LED_PIN |= _BV(LED);
-#endif
-#endif
-
-  return ch;
-}
-    3f9c:	08 95       	ret
-
-00003f9e <watchdogConfig>:
-    "wdr\n"
-  );
-}
-
-void watchdogConfig(uint8_t x) {
-  WDTCSR = _BV(WDCE) | _BV(WDE);
-    3f9e:	e0 e6       	ldi	r30, 0x60	; 96
-    3fa0:	f0 e0       	ldi	r31, 0x00	; 0
-    3fa2:	98 e1       	ldi	r25, 0x18	; 24
-    3fa4:	90 83       	st	Z, r25
-  WDTCSR = x;
-    3fa6:	80 83       	st	Z, r24
-}
-    3fa8:	08 95       	ret
-
-00003faa <verifySpace>:
-  do getch(); while (--count);
-  verifySpace();
-}
-
-void verifySpace() {
-  if (getch() != CRC_EOP) {
-    3faa:	ed df       	rcall	.-38     	; 0x3f86 <getch>
-    3fac:	80 32       	cpi	r24, 0x20	; 32
-    3fae:	19 f0       	breq	.+6      	; 0x3fb6 <verifySpace+0xc>
-    watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
-    3fb0:	88 e0       	ldi	r24, 0x08	; 8
-    3fb2:	f5 df       	rcall	.-22     	; 0x3f9e <watchdogConfig>
-    3fb4:	ff cf       	rjmp	.-2      	; 0x3fb4 <verifySpace+0xa>
-    while (1)			      // and busy-loop so that WD causes
-      ;				      //  a reset and app start.
-  }
-  putch(STK_INSYNC);
-    3fb6:	84 e1       	ldi	r24, 0x14	; 20
-}
-    3fb8:	de cf       	rjmp	.-68     	; 0x3f76 <putch>
-
-00003fba <getNch>:
-    ::[count] "M" (UART_B_VALUE)
-  );
-}
-#endif
-
-void getNch(uint8_t count) {
-    3fba:	1f 93       	push	r17
-    3fbc:	18 2f       	mov	r17, r24
-  do getch(); while (--count);
-    3fbe:	e3 df       	rcall	.-58     	; 0x3f86 <getch>
-    3fc0:	11 50       	subi	r17, 0x01	; 1
-    3fc2:	e9 f7       	brne	.-6      	; 0x3fbe <getNch+0x4>
-  verifySpace();
-    3fc4:	f2 df       	rcall	.-28     	; 0x3faa <verifySpace>
-}
-    3fc6:	1f 91       	pop	r17
-    3fc8:	08 95       	ret
-
-00003fca <appStart>:
-
-void appStart(uint8_t rstFlags) {
-  // save the reset flags in the designated register
-  //  This can be saved in a main program by putting code in .init0 (which
-  //  executes before normal c init code) to save R2 to a global variable.
-  __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
-    3fca:	28 2e       	mov	r2, r24
-
-  watchdogConfig(WATCHDOG_OFF);
-    3fcc:	80 e0       	ldi	r24, 0x00	; 0
-    3fce:	e7 df       	rcall	.-50     	; 0x3f9e <watchdogConfig>
-  __asm__ __volatile__ (
-    3fd0:	ee 27       	eor	r30, r30
-    3fd2:	ff 27       	eor	r31, r31
-    3fd4:	09 94       	ijmp