Browse Source

v3:
Withdraw support for 230400 baud due to incompatibility with Arduino 18 on PC platform
Merge NG support into Diecimila
Preliminary (and probably broken) support for virtual boot partition, for Luminet

cathedrow 15 years ago
parent
commit
5eab5df182

+ 34 - 19
optiboot/boards.txt

@@ -7,7 +7,7 @@
 atmega328o.name=[Optiboot] Arduino Duemilanove or Nano w/ ATmega328
 atmega328o.name=[Optiboot] Arduino Duemilanove or Nano w/ ATmega328
 atmega328o.upload.protocol=stk500
 atmega328o.upload.protocol=stk500
 atmega328o.upload.maximum_size=32256
 atmega328o.upload.maximum_size=32256
-atmega328o.upload.speed=230400
+atmega328o.upload.speed=115200
 atmega328o.bootloader.low_fuses=0xff
 atmega328o.bootloader.low_fuses=0xff
 atmega328o.bootloader.high_fuses=0xde
 atmega328o.bootloader.high_fuses=0xde
 atmega328o.bootloader.extended_fuses=0x05
 atmega328o.bootloader.extended_fuses=0x05
@@ -21,10 +21,27 @@ atmega328o.build.core=arduino
 
 
 ##############################################################
 ##############################################################
 
 
-diecimilao.name=[Optiboot] Arduino Diecimila, Duemilanove, or Nano w/ ATmega168
+atmega328o.name=[Optiboot] Arduino Duemilanove or Nano w/ ATmega328
+atmega328o.upload.protocol=stk500
+atmega328o.upload.maximum_size=32256
+atmega328o.upload.speed=115200
+atmega328o.bootloader.low_fuses=0xff
+atmega328o.bootloader.high_fuses=0xde
+atmega328o.bootloader.extended_fuses=0x05
+atmega328o.bootloader.path=optiboot
+atmega328o.bootloader.file=optiboot_atmega328.hex
+atmega328o.bootloader.unlock_bits=0x3F
+atmega328o.bootloader.lock_bits=0x0F
+atmega328o.build.mcu=atmega328p
+atmega328o.build.f_cpu=16000000L
+atmega328o.build.core=arduino
+
+##############################################################
+
+diecimilao.name=[Optiboot] Arduino Diecimila, Duemilanove, Nano, NG w/ ATmega168
 diecimilao.upload.protocol=stk500
 diecimilao.upload.protocol=stk500
 diecimilao.upload.maximum_size=15360
 diecimilao.upload.maximum_size=15360
-diecimilao.upload.speed=230400
+diecimilao.upload.speed=115200
 diecimilao.bootloader.low_fuses=0xff
 diecimilao.bootloader.low_fuses=0xff
 diecimilao.bootloader.high_fuses=0xdd
 diecimilao.bootloader.high_fuses=0xdd
 diecimilao.bootloader.extended_fuses=0x02
 diecimilao.bootloader.extended_fuses=0x02
@@ -41,7 +58,7 @@ diecimilao.build.core=arduino
 minio.name=[Optiboot] Arduino Mini
 minio.name=[Optiboot] Arduino Mini
 minio.upload.protocol=stk500
 minio.upload.protocol=stk500
 minio.upload.maximum_size=15360
 minio.upload.maximum_size=15360
-minio.upload.speed=230400
+minio.upload.speed=115200
 minio.bootloader.low_fuses=0xff
 minio.bootloader.low_fuses=0xff
 minio.bootloader.high_fuses=0xdd
 minio.bootloader.high_fuses=0xdd
 minio.bootloader.extended_fuses=0x02
 minio.bootloader.extended_fuses=0x02
@@ -122,18 +139,16 @@ proo.build.f_cpu=8000000L
 proo.build.core=arduino
 proo.build.core=arduino
 
 
 ##############################################################
 ##############################################################
-
-atmega168o.name=[Optiboot] Arduino NG or older w/ ATmega168
-atmega168o.upload.protocol=stk500
-atmega168o.upload.maximum_size=14336
-atmega168o.upload.speed=230400
-atmega168o.bootloader.low_fuses=0xff
-atmega168o.bootloader.high_fuses=0xdd
-atmega168o.bootloader.extended_fuses=0x02
-atmega168o.bootloader.path=optiboot
-atmega168o.bootloader.file=optiboot_ng.hex
-atmega168o.bootloader.unlock_bits=0x3F
-atmega168o.bootloader.lock_bits=0x0F
-atmega168o.build.mcu=atmega168
-atmega168o.build.f_cpu=16000000L
-atmega168o.build.core=arduino
+#
+#lumineto.name=[Optiboot] Luminet (in development)
+#lumineto.upload.protocol=stk500
+#lumineto.upload.maximum_size=7424
+#lumineto.upload.speed=9600
+#lumineto.bootloader.low_fuses=0x62
+#lumineto.bootloader.high_fuses=0xdf
+#lumineto.bootloader.extended_fuses=0xfe
+#lumineto.bootloader.path=optiboot
+#lumineto.bootloader.file=optiboot_luminet.hex
+#lumineto.build.mcu=attiny84
+#lumineto.build.f_cpu=1000000L
+#lumineto.build.core=arduino

+ 97 - 79
optiboot/bootloaders/optiboot/Makefile

@@ -63,100 +63,60 @@ override LDFLAGS       = -Wl,$(LDSECTION) -Wl,--relax -nostartfiles
 OBJCOPY        = avr-objcopy
 OBJCOPY        = avr-objcopy
 OBJDUMP        = avr-objdump
 OBJDUMP        = avr-objdump
 
 
-lilypad: TARGET = lilypad
-lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200'
-lilypad: AVR_FREQ = 8000000L
-lilypad: $(PROGRAM)_lilypad.hex
-lilypad: $(PROGRAM)_lilypad.lst
-
-lilypad_isp: lilypad
-lilypad_isp: TARGET = lilypad
-lilypad_isp: HFUSE = DD
-lilypad_isp: LFUSE = E2
-lilypad_isp: EFUSE = 02
-lilypad_isp: isp
-
-lilypad_resonator: TARGET = lilypad_resonator
-lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200'
-lilypad_resonator: AVR_FREQ = 8000000L
-lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
-lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst
+# 20MHz clocked platforms
+#
+# These are capable of 230400 baud, or 115200 baud on PC (Arduino Avrdude issue)
+#
 
 
-lilypad_resonator_isp: lilypad_resonator
-lilypad_resonator_isp: TARGET = lilypad_resonator
-lilypad_resonator_isp: HFUSE = DD
-lilypad_resonator_isp: LFUSE = C6
-lilypad_resonator_isp: EFUSE = 02
-lilypad_resonator_isp: isp
+pro20: TARGET = pro_20mhz
+pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+pro20: AVR_FREQ = 20000000L
+pro20: $(PROGRAM)_pro_20mhz.hex
+pro20: $(PROGRAM)_pro_20mhz.lst
 
 
-pro8: TARGET = pro_8MHz
-pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200'
-pro8: AVR_FREQ = 8000000L
-pro8: $(PROGRAM)_pro_8MHz.hex
-pro8: $(PROGRAM)_pro_8MHz.lst
+pro20_isp: pro20
+pro20_isp: TARGET = pro_20mhz
+pro20_isp: HFUSE = DD # 2.7V brownout
+pro20_isp: LFUSE = C6 # Full swing xtal (20MHz) 258CK/14CK+4.1ms
+pro20_isp: EFUSE = 02 # 512 byte boot
+pro20_isp: isp
 
 
-pro8_isp: pro8
-pro8_isp: TARGET = pro_8MHz
-pro8_isp: HFUSE = DD
-pro8_isp: LFUSE = C6
-pro8_isp: EFUSE = 02
-pro8_isp: isp
+# 16MHz clocked platforms
+#
+# These are capable of 230400 baud, or 115200 baud on PC (Arduino Avrdude issue)
+#
 
 
 pro16: TARGET = pro_16MHz
 pro16: TARGET = pro_16MHz
-pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=230400'
+pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
 pro16: AVR_FREQ = 16000000L
 pro16: AVR_FREQ = 16000000L
 pro16: $(PROGRAM)_pro_16MHz.hex
 pro16: $(PROGRAM)_pro_16MHz.hex
 pro16: $(PROGRAM)_pro_16MHz.lst
 pro16: $(PROGRAM)_pro_16MHz.lst
 
 
 pro16_isp: pro16
 pro16_isp: pro16
 pro16_isp: TARGET = pro_16MHz
 pro16_isp: TARGET = pro_16MHz
-pro16_isp: HFUSE = DD
-pro16_isp: LFUSE = C6
-pro16_isp: EFUSE = 02
+pro16_isp: HFUSE = DD # 2.7V brownout
+pro16_isp: LFUSE = C6 # Full swing xtal (20MHz) 258CK/14CK+4.1ms
+pro16_isp: EFUSE = 02 # 512 byte boot
 pro16_isp: isp
 pro16_isp: isp
 
 
-pro20: TARGET = pro_20mhz
-pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=230400'
-pro20: AVR_FREQ = 20000000L
-pro20: $(PROGRAM)_pro_20mhz.hex
-pro20: $(PROGRAM)_pro_20mhz.lst
-
-pro20_isp: pro20
-pro20_isp: TARGET = pro_20mhz
-pro20_isp: HFUSE = DD
-pro20_isp: LFUSE = C6
-pro20_isp: EFUSE = 02
-pro20_isp: isp
-
+# Diecimila and NG use identical bootloaders
+#
 diecimila: TARGET = diecimila
 diecimila: TARGET = diecimila
-diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=230400'
+diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
 diecimila: AVR_FREQ = 16000000L 
 diecimila: AVR_FREQ = 16000000L 
 diecimila: $(PROGRAM)_diecimila.hex
 diecimila: $(PROGRAM)_diecimila.hex
 diecimila: $(PROGRAM)_diecimila.lst
 diecimila: $(PROGRAM)_diecimila.lst
 
 
 diecimila_isp: diecimila
 diecimila_isp: diecimila
 diecimila_isp: TARGET = diecimila
 diecimila_isp: TARGET = diecimila
-diecimila_isp: HFUSE = DD
-diecimila_isp: LFUSE = FF
-diecimila_isp: EFUSE = 02
+diecimila_isp: HFUSE = DD # 2.7V brownout
+diecimila_isp: LFUSE = FF # Low power xtal (16MHz) 16KCK/14CK+65ms
+diecimila_isp: EFUSE = 02 # 512 byte boot
 diecimila_isp: isp
 diecimila_isp: isp
 
 
-ng: TARGET = ng
-ng: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=230400'
-ng: AVR_FREQ = 16000000L
-ng: $(PROGRAM)_ng.hex
-ng: $(PROGRAM)_ng.lst
-
-ng_isp: ng
-ng_isp: TARGET = ng
-ng_isp: HFUSE = DD
-ng_isp: LFUSE = FF
-ng_isp: EFUSE = 02
-ng_isp: isp
-
 atmega328: TARGET = atmega328
 atmega328: TARGET = atmega328
 atmega328: MCU_TARGET = atmega328p
 atmega328: MCU_TARGET = atmega328p
-atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=230400'
+atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
 atmega328: AVR_FREQ = 16000000L
 atmega328: AVR_FREQ = 16000000L
 atmega328: LDSECTION  = --section-start=.text=0x7e00
 atmega328: LDSECTION  = --section-start=.text=0x7e00
 atmega328: $(PROGRAM)_atmega328.hex
 atmega328: $(PROGRAM)_atmega328.hex
@@ -165,14 +125,58 @@ atmega328: $(PROGRAM)_atmega328.lst
 atmega328_isp: atmega328
 atmega328_isp: atmega328
 atmega328_isp: TARGET = atmega328
 atmega328_isp: TARGET = atmega328
 atmega328_isp: MCU_TARGET = atmega328p
 atmega328_isp: MCU_TARGET = atmega328p
-atmega328_isp: HFUSE = DE
-atmega328_isp: LFUSE = FF
-atmega328_isp: EFUSE = 05
+atmega328_isp: HFUSE = DE # 512 byte boot
+atmega328_isp: LFUSE = FF # Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega328_isp: EFUSE = 05 # 2.7V brownout
 atmega328_isp: isp
 atmega328_isp: isp
 
 
+# 8MHz clocked platforms
+#
+# These are capable of 115200 baud
+#
+
+lilypad: TARGET = lilypad
+lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200'
+lilypad: AVR_FREQ = 8000000L
+lilypad: $(PROGRAM)_lilypad.hex
+lilypad: $(PROGRAM)_lilypad.lst
+
+lilypad_isp: lilypad
+lilypad_isp: TARGET = lilypad
+lilypad_isp: HFUSE = DD # 2.7V brownout
+lilypad_isp: LFUSE = E2 # Internal 8MHz osc (8MHz) Slow rising power
+lilypad_isp: EFUSE = 02 # 512 byte boot
+lilypad_isp: isp
+
+lilypad_resonator: TARGET = lilypad_resonator
+lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200'
+lilypad_resonator: AVR_FREQ = 8000000L
+lilypad_resonator: $(PROGRAM)_lilypad_resonator.hex
+lilypad_resonator: $(PROGRAM)_lilypad_resonator.lst
+
+lilypad_resonator_isp: lilypad_resonator
+lilypad_resonator_isp: TARGET = lilypad_resonator
+lilypad_resonator_isp: HFUSE = DD # 2.7V brownout
+lilypad_resonator_isp: LFUSE = C6 # Full swing xtal (20MHz) 258CK/14CK+4.1ms
+lilypad_resonator_isp: EFUSE = 02 # 512 byte boot
+lilypad_resonator_isp: isp
+
+pro8: TARGET = pro_8MHz
+pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200'
+pro8: AVR_FREQ = 8000000L
+pro8: $(PROGRAM)_pro_8MHz.hex
+pro8: $(PROGRAM)_pro_8MHz.lst
+
+pro8_isp: pro8
+pro8_isp: TARGET = pro_8MHz
+pro8_isp: HFUSE = DD # 2.7V brownout
+pro8_isp: LFUSE = C6 # Full swing xtal (20MHz) 258CK/14CK+4.1ms
+pro8_isp: EFUSE = 02 # 512 byte boot
+pro8_isp: isp
+
 atmega328_pro8: TARGET = atmega328_pro_8MHz
 atmega328_pro8: TARGET = atmega328_pro_8MHz
 atmega328_pro8: MCU_TARGET = atmega328p
 atmega328_pro8: MCU_TARGET = atmega328p
-atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200'
+atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
 atmega328_pro8: AVR_FREQ = 8000000L
 atmega328_pro8: AVR_FREQ = 8000000L
 atmega328_pro8: LDSECTION  = --section-start=.text=0x7e00
 atmega328_pro8: LDSECTION  = --section-start=.text=0x7e00
 atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
 atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
@@ -181,19 +185,33 @@ atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
 atmega328_pro8_isp: atmega328_pro8
 atmega328_pro8_isp: atmega328_pro8
 atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
 atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
 atmega328_pro8_isp: MCU_TARGET = atmega328p
 atmega328_pro8_isp: MCU_TARGET = atmega328p
-atmega328_pro8_isp: HFUSE = DE
-atmega328_pro8_isp: LFUSE = FF
-atmega328_pro8_isp: EFUSE = 05
+atmega328_pro8_isp: HFUSE = DE # 512 byte boot
+atmega328_pro8_isp: LFUSE = FF # Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega328_pro8_isp: EFUSE = 05 # 2.7V brownout
 atmega328_pro8_isp: isp
 atmega328_pro8_isp: isp
 
 
+# 1MHz clocked platforms
+#
+# These are capable of 9600 baud
+#
+
 luminet: TARGET = luminet
 luminet: TARGET = luminet
 luminet: MCU_TARGET = attiny84
 luminet: MCU_TARGET = attiny84
-luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=115200'
+luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
+luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
 luminet: AVR_FREQ = 1000000L
 luminet: AVR_FREQ = 1000000L
-luminet: LDSECTION  = --section-start=.text=0x1e00
+luminet: LDSECTION  = --section-start=.text=0x1d00
 luminet: $(PROGRAM)_luminet.hex
 luminet: $(PROGRAM)_luminet.hex
 luminet: $(PROGRAM)_luminet.lst
 luminet: $(PROGRAM)_luminet.lst
 
 
+luminet_isp: luminet
+luminet_isp: TARGET = luminet
+luminet_isp: MCU_TARGET = attiny84
+luminet_isp: HFUSE = DF # Brownout disabled
+luminet_isp: LFUSE = 62 # 1MHz internal oscillator, slowly rising power
+luminet_isp: EFUSE = FE # Self-programming enable
+luminet_isp: isp
+
 isp: $(TARGET)
 isp: $(TARGET)
 	$(ISPFUSES)
 	$(ISPFUSES)
 	$(ISPFLASH)
 	$(ISPFLASH)

+ 2 - 0
optiboot/bootloaders/optiboot/makeall

@@ -9,3 +9,5 @@ make diecimila
 make ng
 make ng
 make atmega328
 make atmega328
 make atmega328_pro8
 make atmega328_pro8
+make luminet
+

+ 81 - 5
optiboot/bootloaders/optiboot/optiboot.c

@@ -86,7 +86,7 @@
 #define BAUD_RATE   19200
 #define BAUD_RATE   19200
 #endif
 #endif
 
 
-
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
 /* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */ 
 /* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */ 
 #define LED_DDR     DDRB
 #define LED_DDR     DDRB
 #define LED_PORT    PORTB
 #define LED_PORT    PORTB
@@ -101,6 +101,24 @@
 #define UART_TX_BIT 1
 #define UART_TX_BIT 1
 #define UART_RX_BIT 0
 #define UART_RX_BIT 0
 #endif
 #endif
+#endif
+
+#if defined(__AVR_ATtiny84__)
+/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */ 
+#define LED_DDR     DDRA
+#define LED_PORT    PORTA
+#define LED_PIN     PINA
+#define LED         PINA4
+
+/* Ports for soft UART - left port only for now*/
+#ifdef SOFT_UART
+#define UART_PORT   PORTA
+#define UART_PIN    PINA
+#define UART_DDR    DDRA
+#define UART_TX_BIT 2
+#define UART_RX_BIT 3
+#endif
+#endif
 
 
 /* STK500 constants list, from AVRDUDE */
 /* STK500 constants list, from AVRDUDE */
 #define STK_OK              0x10
 #define STK_OK              0x10
@@ -142,6 +160,19 @@
 #define STK_READ_FUSE_EXT   0x77  // 'w'
 #define STK_READ_FUSE_EXT   0x77  // 'w'
 #define STK_READ_OSCCAL_EXT 0x78  // 'x'
 #define STK_READ_OSCCAL_EXT 0x78  // 'x'
 
 
+/* Watchdog settings */
+#define WATCHDOG_OFF    (0)
+#define WATCHDOG_16MS   (_BV(WDE))
+#define WATCHDOG_32MS   (_BV(WDP0) | _BV(WDE))
+#define WATCHDOG_64MS   (_BV(WDP1) | _BV(WDE))
+#define WATCHDOG_125MS  (_BV(WDP1) | _BV(WDP0) | _BV(WDE))
+#define WATCHDOG_250MS  (_BV(WDP2) | _BV(WDE))
+#define WATCHDOG_500MS  (_BV(WDP2) | _BV(WDP0) | _BV(WDE))
+#define WATCHDOG_1S     (_BV(WDP2) | _BV(WDP1) | _BV(WDE))
+#define WATCHDOG_2S     (_BV(WDP2) | _BV(WDP1) | _BV(WDP0) | _BV(WDE))
+#define WATCHDOG_4S     (_BV(WDE3) | _BV(WDE))
+#define WATCHDOG_8S     (_BV(WDE3) | _BV(WDE0) | _BV(WDE))
+
 /* Function Prototypes */
 /* Function Prototypes */
 /* The main function is in init9, which removes the interrupt vector table */
 /* The main function is in init9, which removes the interrupt vector table */
 /* we don't need. It is also 'naked', which means the compiler does not    */
 /* we don't need. It is also 'naked', which means the compiler does not    */
@@ -166,7 +197,10 @@ void appStart() __attribute__ ((naked));
 #define buff    ((uint8_t*)(0x100))
 #define buff    ((uint8_t*)(0x100))
 #define address (*(uint16_t*)(0x200))
 #define address (*(uint16_t*)(0x200))
 #define length  (*(uint8_t*)(0x202))
 #define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
   // After the zero init loop, this is the first code to run.
   // After the zero init loop, this is the first code to run.
@@ -200,7 +234,7 @@ int main(void) {
   if (!(ch & _BV(EXTRF))) appStart();
   if (!(ch & _BV(EXTRF))) appStart();
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
+  watchdogConfig(WATCHDOG_500MS);
 
 
   /* Set LED pin as output */
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
   LED_DDR |= _BV(LED);
@@ -268,6 +302,25 @@ int main(void) {
       // So check that here
       // So check that here
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#ifdef VIRTUAL_BOOT_PARTITION
+      if ((uint16_t)(void*)address == 0) {
+        // This is the reset vector page. We need to live-patch the code so the
+        // bootloader runs.
+        //
+        // Move RESET vector to WDT vector
+        uint16_t vect = buff[0] | (buff[1]<<8);
+        rstVect = vect;
+        wdtVect = buff[10] | (buff[11]<<8);
+        vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
+        buff[10] = vect & 0xff;
+        buff[11] = vect >> 8;
+
+        // Add jump to bootloader at RESET vector
+        buff[0] = 0x7f;
+        buff[1] = 0xce; // rjmp 0x1d00 instruction
+      }
+#endif
+
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       addrPtr = (uint16_t)(void*)address;
@@ -284,16 +337,32 @@ int main(void) {
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
       // READ PAGE - we only read flash
       // READ PAGE - we only read flash
       getLen();
       getLen();
       verifySpace();
       verifySpace();
+#ifdef VIRTUAL_BOOT_PARTITION
+      do {
+        // Undo vector patch in bottom page so verify passes
+        if (address == 0)       ch=rstVect & 0xff;
+        else if (address == 1)  ch=rstVect >> 8;
+        else if (address == 10)  ch=wdtVect & 0xff;
+        else if (address == 11) ch=wdtVect >> 8;
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
       while (--length);
       while (--length);
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
@@ -306,7 +375,7 @@ int main(void) {
     }
     }
     else if (ch == 'Q') {
     else if (ch == 'Q') {
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
+      watchdogConfig(WATCHDOG_16MS);
       verifySpace();
       verifySpace();
     }
     }
     else {
     else {
@@ -451,10 +520,17 @@ void watchdogConfig(uint8_t x) {
 }
 }
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
+  watchdogConfig(WATCHDOG_OFF);
   __asm__ __volatile__ (
   __asm__ __volatile__ (
+#ifdef VIRTUAL_BOOT_PARTITION
+    // Jump to WDT vector
+    "ldi r30,5\n"
+    "clr r31\n"
+#else
+    // Jump to RST vector
     "clr r30\n"
     "clr r30\n"
     "clr r31\n"
     "clr r31\n"
+#endif
     "ijmp\n"
     "ijmp\n"
   );
   );
 }
 }

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

@@ -1,34 +1,33 @@
-:107E000085E08093810084B714BE81FFE4D08DE0CB
-:107E1000DCD0259A519A86E020E33CEF91E0309344
-:107E200085002093840096BBB09BFECF1D9AA89539
-:107E30008150A9F7DD24D394A5E0EA2EF1E1FF2ECD
-:107E4000ABD0813421F481E0D1D083E024C08234EE
-:107E500011F484E103C0853419F485E0C7D08AC0E9
-:107E60008535A1F499D0082F10E0109301020093FA
-:107E7000000292D090E0982F8827802B912B880FBA
-:107E8000991F909301028093000273C0863529F4F4
-:107E900084E0ACD080E071D06DC0843609F043C07E
-:107EA0008FD0E0910002F091010283E080935700AF
-:107EB000E895C0E0D1E070D08993809102028150B2
-:107EC000809302028823B9F78BD007B600FCFDCF60
-:107ED0004091000250910102A0E0B1E02C9130E00D
-:107EE00011968C91119790E0982F8827822B932BD5
-:107EF0001296FA010C01D0925700E89511244E5FBA
-:107F00005F4FF1E0A038BF0749F7E0910002F09120
-:107F10000102E0925700E89507B600FCFDCFF09211
-:107F20005700E89527C08437B9F44AD059D0E0917A
-:107F30000002F09101023196F0930102E0930002F9
-:107F40003197E4918E2F19D0809102028150809355
-:107F50000202882361F70EC0853739F441D08EE1E3
-:107F60000CD085E90AD08FE096CF813511F488E0F6
-:107F70002CD036D080E101D063CF2AE030E080956C
-:107F8000089410F4599802C0599A000015D014D0E2
-:107F900086952A95B1F70895A89529E030E048998B
-:107FA000FECF0AD009D008D08894489908942A9521
-:107FB00011F08795F7CF089598E09A95F1F7089515
-:107FC000EBDFEADF80930202E7CFE0E6F0E098E142
-:107FD00090838083089580E0F8DFEE27FF270994DF
-:107FE000DBDF803209F0F7DF84E1C7CF1F93182F62
-:0C7FF000D3DF1150E9F7F4DF1F91089572
+:107E000085E08093810082E08093C00088E18093C8
+:107E1000C10086E08093C20080E18093C40084B7F3
+:107E200014BE81FFD0D08DE0C8D0259A86E020E333
+:107E30003CEF91E0309385002093840096BBB09B8B
+:107E4000FECF1D9AA8958150A9F7DD24D394A5E013
+:107E5000EA2EF1E1FF2EA4D0813421F481E0BED0DE
+:107E600083E024C0823411F484E103C0853419F422
+:107E700085E0B4D08AC08535A1F492D0082F10E0F7
+:107E800010930102009300028BD090E0982F882776
+:107E9000802B912B880F991F9093010280930002F1
+:107EA00073C0863529F484E099D080E071D06DC02C
+:107EB000843609F043C07CD0E0910002F0910102C9
+:107EC00083E080935700E895C0E0D1E069D08993C2
+:107ED000809102028150809302028823B9F778D002
+:107EE00007B600FCFDCF4091000250910102A0E0D6
+:107EF000B1E02C9130E011968C91119790E0982F81
+:107F00008827822B932B1296FA010C01D0925700EE
+:107F1000E89511244E5F5F4FF1E0A038BF0749F7A5
+:107F2000E0910002F0910102E0925700E89507B657
+:107F300000FCFDCFF0925700E89527C08437B9F4D4
+:107F400037D046D0E0910002F09101023196F093D3
+:107F50000102E09300023197E4918E2F19D08091B5
+:107F60000202815080930202882361F70EC0853798
+:107F700039F42ED08EE10CD085E90AD08FE096CF6F
+:107F8000813511F488E019D023D080E101D063CF8E
+:107F9000982F8091C00085FFFCCF9093C600089574
+:107FA000A8958091C00087FFFCCF8091C6000895FE
+:107FB000F7DFF6DF80930202F3CFE0E6F0E098E12E
+:107FC00090838083089580E0F8DFEE27FF270994EF
+:107FD000E7DF803209F0F7DF84E1DACF1F93182F53
+:0C7FE000DFDF1150E9F7F4DF1F91089576
 :0400000300007E007B
 :0400000300007E007B
 :00000001FF
 :00000001FF

+ 267 - 268
optiboot/bootloaders/optiboot/optiboot_atmega328.lst

@@ -3,519 +3,518 @@ optiboot_atmega328.elf:     file format elf32-avr
 
 
 Sections:
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001fc  00007e00  00007e00  00000054  2**1
+  0 .text         000001ec  00007e00  00007e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000250  2**0
+  1 .debug_aranges 00000028  00000000  00000000  00000240  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000268  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000275  00000000  00000000  000002f0  2**0
+  3 .debug_info   00000269  00000000  00000000  000002d2  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a3  00000000  00000000  00000565  2**0
+  4 .debug_abbrev 00000196  00000000  00000000  0000053b  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003b8  00000000  00000000  00000708  2**0
+  5 .debug_line   000003d3  00000000  00000000  000006d1  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  000000a0  00000000  00000000  00000ac0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000aa4  2**2
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000133  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000135  00000000  00000000  00000b34  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001a0  00000000  00000000  00000c93  2**0
+  8 .debug_loc    000001d1  00000000  00000000  00000c69  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000070  00000000  00000000  00000e33  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000e3a  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
 
 
 Disassembly of section .text:
 Disassembly of section .text:
 
 
 00007e00 <main>:
 00007e00 <main>:
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     7e00:	85 e0       	ldi	r24, 0x05	; 5
     7e00:	85 e0       	ldi	r24, 0x05	; 5
     7e02:	80 93 81 00 	sts	0x0081, r24
     7e02:	80 93 81 00 	sts	0x0081, r24
+#if LED_START_FLASHES > 0
+  // Set up Timer 1 for timeout counter
+  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+#endif
+#ifndef SOFT_UART
+  UCSR0A = _BV(U2X0); //Double speed mode USART0
+    7e06:	82 e0       	ldi	r24, 0x02	; 2
+    7e08:	80 93 c0 00 	sts	0x00C0, r24
+  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+    7e0c:	88 e1       	ldi	r24, 0x18	; 24
+    7e0e:	80 93 c1 00 	sts	0x00C1, r24
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+    7e12:	86 e0       	ldi	r24, 0x06	; 6
+    7e14:	80 93 c2 00 	sts	0x00C2, r24
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+    7e18:	80 e1       	ldi	r24, 0x10	; 16
+    7e1a:	80 93 c4 00 	sts	0x00C4, r24
 #endif
 #endif
 
 
   // Adaboot no-wait mod
   // Adaboot no-wait mod
   ch = MCUSR;
   ch = MCUSR;
-    7e06:	84 b7       	in	r24, 0x34	; 52
+    7e1e:	84 b7       	in	r24, 0x34	; 52
   MCUSR = 0;
   MCUSR = 0;
-    7e08:	14 be       	out	0x34, r1	; 52
+    7e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
   if (!(ch & _BV(EXTRF))) appStart();
-    7e0a:	81 ff       	sbrs	r24, 1
-    7e0c:	e4 d0       	rcall	.+456    	; 0x7fd6 <appStart>
+    7e22:	81 ff       	sbrs	r24, 1
+    7e24:	d0 d0       	rcall	.+416    	; 0x7fc6 <appStart>
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
-    7e0e:	8d e0       	ldi	r24, 0x0D	; 13
-    7e10:	dc d0       	rcall	.+440    	; 0x7fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_500MS);
+    7e26:	8d e0       	ldi	r24, 0x0D	; 13
+    7e28:	c8 d0       	rcall	.+400    	; 0x7fba <watchdogConfig>
 
 
   /* Set LED pin as output */
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
   LED_DDR |= _BV(LED);
-    7e12:	25 9a       	sbi	0x04, 5	; 4
-
-#ifdef SOFT_UART
-  /* Set TX pin as output */
-  UART_DDR |= _BV(UART_TX_BIT);
-    7e14:	51 9a       	sbi	0x0a, 1	; 10
-    7e16:	86 e0       	ldi	r24, 0x06	; 6
+    7e2a:	25 9a       	sbi	0x04, 5	; 4
+    7e2c:	86 e0       	ldi	r24, 0x06	; 6
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    7e18:	20 e3       	ldi	r18, 0x30	; 48
-    7e1a:	3c ef       	ldi	r19, 0xFC	; 252
+    7e2e:	20 e3       	ldi	r18, 0x30	; 48
+    7e30:	3c ef       	ldi	r19, 0xFC	; 252
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    7e1c:	91 e0       	ldi	r25, 0x01	; 1
+    7e32:	91 e0       	ldi	r25, 0x01	; 1
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    7e1e:	30 93 85 00 	sts	0x0085, r19
-    7e22:	20 93 84 00 	sts	0x0084, r18
+    7e34:	30 93 85 00 	sts	0x0085, r19
+    7e38:	20 93 84 00 	sts	0x0084, r18
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    7e26:	96 bb       	out	0x16, r25	; 22
+    7e3c:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
-    7e28:	b0 9b       	sbis	0x16, 0	; 22
-    7e2a:	fe cf       	rjmp	.-4      	; 0x7e28 <main+0x28>
+    7e3e:	b0 9b       	sbis	0x16, 0	; 22
+    7e40:	fe cf       	rjmp	.-4      	; 0x7e3e <main+0x3e>
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
-    7e2c:	1d 9a       	sbi	0x03, 5	; 3
+    7e42:	1d 9a       	sbi	0x03, 5	; 3
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    7e2e:	a8 95       	wdr
+    7e44:	a8 95       	wdr
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
     watchdogReset();
     watchdogReset();
   } while (--count);
   } while (--count);
-    7e30:	81 50       	subi	r24, 0x01	; 1
-    7e32:	a9 f7       	brne	.-22     	; 0x7e1e <main+0x1e>
+    7e46:	81 50       	subi	r24, 0x01	; 1
+    7e48:	a9 f7       	brne	.-22     	; 0x7e34 <main+0x34>
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    7e34:	dd 24       	eor	r13, r13
-    7e36:	d3 94       	inc	r13
+    7e4a:	dd 24       	eor	r13, r13
+    7e4c:	d3 94       	inc	r13
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         addrPtr += 2;
         addrPtr += 2;
       } while (--ch);
       } while (--ch);
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    7e38:	a5 e0       	ldi	r26, 0x05	; 5
-    7e3a:	ea 2e       	mov	r14, r26
+    7e4e:	a5 e0       	ldi	r26, 0x05	; 5
+    7e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    7e3c:	f1 e1       	ldi	r31, 0x11	; 17
-    7e3e:	ff 2e       	mov	r15, r31
+    7e52:	f1 e1       	ldi	r31, 0x11	; 17
+    7e54:	ff 2e       	mov	r15, r31
 #endif
 #endif
 
 
   /* Forever loop */
   /* Forever loop */
   for (;;) {
   for (;;) {
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
-    7e40:	ab d0       	rcall	.+342    	; 0x7f98 <getch>
+    7e56:	a4 d0       	rcall	.+328    	; 0x7fa0 <getch>
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
-    7e42:	81 34       	cpi	r24, 0x41	; 65
-    7e44:	21 f4       	brne	.+8      	; 0x7e4e <main+0x4e>
+    7e58:	81 34       	cpi	r24, 0x41	; 65
+    7e5a:	21 f4       	brne	.+8      	; 0x7e64 <main+0x64>
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    7e46:	81 e0       	ldi	r24, 0x01	; 1
-    7e48:	d1 d0       	rcall	.+418    	; 0x7fec <verifySpace+0xc>
+    7e5c:	81 e0       	ldi	r24, 0x01	; 1
+    7e5e:	be d0       	rcall	.+380    	; 0x7fdc <verifySpace+0xc>
       putch(0x03);
       putch(0x03);
-    7e4a:	83 e0       	ldi	r24, 0x03	; 3
-    7e4c:	24 c0       	rjmp	.+72     	; 0x7e96 <main+0x96>
+    7e60:	83 e0       	ldi	r24, 0x03	; 3
+    7e62:	24 c0       	rjmp	.+72     	; 0x7eac <main+0xac>
     }
     }
     else if(ch == STK_SET_DEVICE) {
     else if(ch == STK_SET_DEVICE) {
-    7e4e:	82 34       	cpi	r24, 0x42	; 66
-    7e50:	11 f4       	brne	.+4      	; 0x7e56 <main+0x56>
+    7e64:	82 34       	cpi	r24, 0x42	; 66
+    7e66:	11 f4       	brne	.+4      	; 0x7e6c <main+0x6c>
       // SET DEVICE is ignored
       // SET DEVICE is ignored
       getNch(20);
       getNch(20);
-    7e52:	84 e1       	ldi	r24, 0x14	; 20
-    7e54:	03 c0       	rjmp	.+6      	; 0x7e5c <main+0x5c>
+    7e68:	84 e1       	ldi	r24, 0x14	; 20
+    7e6a:	03 c0       	rjmp	.+6      	; 0x7e72 <main+0x72>
     }
     }
     else if(ch == STK_SET_DEVICE_EXT) {
     else if(ch == STK_SET_DEVICE_EXT) {
-    7e56:	85 34       	cpi	r24, 0x45	; 69
-    7e58:	19 f4       	brne	.+6      	; 0x7e60 <main+0x60>
+    7e6c:	85 34       	cpi	r24, 0x45	; 69
+    7e6e:	19 f4       	brne	.+6      	; 0x7e76 <main+0x76>
       // SET DEVICE EXT is ignored
       // SET DEVICE EXT is ignored
       getNch(5);
       getNch(5);
-    7e5a:	85 e0       	ldi	r24, 0x05	; 5
-    7e5c:	c7 d0       	rcall	.+398    	; 0x7fec <verifySpace+0xc>
-    7e5e:	8a c0       	rjmp	.+276    	; 0x7f74 <main+0x174>
+    7e70:	85 e0       	ldi	r24, 0x05	; 5
+    7e72:	b4 d0       	rcall	.+360    	; 0x7fdc <verifySpace+0xc>
+    7e74:	8a c0       	rjmp	.+276    	; 0x7f8a <main+0x18a>
     }
     }
     else if(ch == STK_LOAD_ADDRESS) {
     else if(ch == STK_LOAD_ADDRESS) {
-    7e60:	85 35       	cpi	r24, 0x55	; 85
-    7e62:	a1 f4       	brne	.+40     	; 0x7e8c <main+0x8c>
+    7e76:	85 35       	cpi	r24, 0x55	; 85
+    7e78:	a1 f4       	brne	.+40     	; 0x7ea2 <main+0xa2>
       // LOAD ADDRESS
       // LOAD ADDRESS
       address = getch();
       address = getch();
-    7e64:	99 d0       	rcall	.+306    	; 0x7f98 <getch>
-    7e66:	08 2f       	mov	r16, r24
-    7e68:	10 e0       	ldi	r17, 0x00	; 0
-    7e6a:	10 93 01 02 	sts	0x0201, r17
-    7e6e:	00 93 00 02 	sts	0x0200, r16
+    7e7a:	92 d0       	rcall	.+292    	; 0x7fa0 <getch>
+    7e7c:	08 2f       	mov	r16, r24
+    7e7e:	10 e0       	ldi	r17, 0x00	; 0
+    7e80:	10 93 01 02 	sts	0x0201, r17
+    7e84:	00 93 00 02 	sts	0x0200, r16
       address = (address & 0xff) | (getch() << 8);
       address = (address & 0xff) | (getch() << 8);
-    7e72:	92 d0       	rcall	.+292    	; 0x7f98 <getch>
-    7e74:	90 e0       	ldi	r25, 0x00	; 0
-    7e76:	98 2f       	mov	r25, r24
-    7e78:	88 27       	eor	r24, r24
-    7e7a:	80 2b       	or	r24, r16
-    7e7c:	91 2b       	or	r25, r17
+    7e88:	8b d0       	rcall	.+278    	; 0x7fa0 <getch>
+    7e8a:	90 e0       	ldi	r25, 0x00	; 0
+    7e8c:	98 2f       	mov	r25, r24
+    7e8e:	88 27       	eor	r24, r24
+    7e90:	80 2b       	or	r24, r16
+    7e92:	91 2b       	or	r25, r17
       address += address; // Convert from word address to byte address
       address += address; // Convert from word address to byte address
-    7e7e:	88 0f       	add	r24, r24
-    7e80:	99 1f       	adc	r25, r25
-    7e82:	90 93 01 02 	sts	0x0201, r25
-    7e86:	80 93 00 02 	sts	0x0200, r24
-    7e8a:	73 c0       	rjmp	.+230    	; 0x7f72 <main+0x172>
+    7e94:	88 0f       	add	r24, r24
+    7e96:	99 1f       	adc	r25, r25
+    7e98:	90 93 01 02 	sts	0x0201, r25
+    7e9c:	80 93 00 02 	sts	0x0200, r24
+    7ea0:	73 c0       	rjmp	.+230    	; 0x7f88 <main+0x188>
       verifySpace();
       verifySpace();
     }
     }
     else if(ch == STK_UNIVERSAL) {
     else if(ch == STK_UNIVERSAL) {
-    7e8c:	86 35       	cpi	r24, 0x56	; 86
-    7e8e:	29 f4       	brne	.+10     	; 0x7e9a <main+0x9a>
+    7ea2:	86 35       	cpi	r24, 0x56	; 86
+    7ea4:	29 f4       	brne	.+10     	; 0x7eb0 <main+0xb0>
       // UNIVERSAL command is ignored
       // UNIVERSAL command is ignored
       getNch(4);
       getNch(4);
-    7e90:	84 e0       	ldi	r24, 0x04	; 4
-    7e92:	ac d0       	rcall	.+344    	; 0x7fec <verifySpace+0xc>
+    7ea6:	84 e0       	ldi	r24, 0x04	; 4
+    7ea8:	99 d0       	rcall	.+306    	; 0x7fdc <verifySpace+0xc>
       putch(0x00);
       putch(0x00);
-    7e94:	80 e0       	ldi	r24, 0x00	; 0
-    7e96:	71 d0       	rcall	.+226    	; 0x7f7a <putch>
-    7e98:	6d c0       	rjmp	.+218    	; 0x7f74 <main+0x174>
+    7eaa:	80 e0       	ldi	r24, 0x00	; 0
+    7eac:	71 d0       	rcall	.+226    	; 0x7f90 <putch>
+    7eae:	6d c0       	rjmp	.+218    	; 0x7f8a <main+0x18a>
     }
     }
     /* Write memory, length is big endian and is in bytes  */
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     else if(ch == STK_PROG_PAGE) {
-    7e9a:	84 36       	cpi	r24, 0x64	; 100
-    7e9c:	09 f0       	breq	.+2      	; 0x7ea0 <main+0xa0>
-    7e9e:	43 c0       	rjmp	.+134    	; 0x7f26 <main+0x126>
+    7eb0:	84 36       	cpi	r24, 0x64	; 100
+    7eb2:	09 f0       	breq	.+2      	; 0x7eb6 <main+0xb6>
+    7eb4:	43 c0       	rjmp	.+134    	; 0x7f3c <main+0x13c>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint8_t *bufPtr;
       uint16_t addrPtr;
       uint16_t addrPtr;
 
 
       getLen();
       getLen();
-    7ea0:	8f d0       	rcall	.+286    	; 0x7fc0 <getLen>
+    7eb6:	7c d0       	rcall	.+248    	; 0x7fb0 <getLen>
 
 
       // Immediately start page erase - this will 4.5ms
       // Immediately start page erase - this will 4.5ms
       boot_page_erase((uint16_t)(void*)address);
       boot_page_erase((uint16_t)(void*)address);
-    7ea2:	e0 91 00 02 	lds	r30, 0x0200
-    7ea6:	f0 91 01 02 	lds	r31, 0x0201
-    7eaa:	83 e0       	ldi	r24, 0x03	; 3
-    7eac:	80 93 57 00 	sts	0x0057, r24
-    7eb0:	e8 95       	spm
-    7eb2:	c0 e0       	ldi	r28, 0x00	; 0
-    7eb4:	d1 e0       	ldi	r29, 0x01	; 1
+    7eb8:	e0 91 00 02 	lds	r30, 0x0200
+    7ebc:	f0 91 01 02 	lds	r31, 0x0201
+    7ec0:	83 e0       	ldi	r24, 0x03	; 3
+    7ec2:	80 93 57 00 	sts	0x0057, r24
+    7ec6:	e8 95       	spm
+    7ec8:	c0 e0       	ldi	r28, 0x00	; 0
+    7eca:	d1 e0       	ldi	r29, 0x01	; 1
 
 
       // While that is going on, read in page contents
       // While that is going on, read in page contents
       bufPtr = buff;
       bufPtr = buff;
       do *bufPtr++ = getch();
       do *bufPtr++ = getch();
-    7eb6:	70 d0       	rcall	.+224    	; 0x7f98 <getch>
-    7eb8:	89 93       	st	Y+, r24
+    7ecc:	69 d0       	rcall	.+210    	; 0x7fa0 <getch>
+    7ece:	89 93       	st	Y+, r24
       while (--length);
       while (--length);
-    7eba:	80 91 02 02 	lds	r24, 0x0202
-    7ebe:	81 50       	subi	r24, 0x01	; 1
-    7ec0:	80 93 02 02 	sts	0x0202, r24
-    7ec4:	88 23       	and	r24, r24
-    7ec6:	b9 f7       	brne	.-18     	; 0x7eb6 <main+0xb6>
+    7ed0:	80 91 02 02 	lds	r24, 0x0202
+    7ed4:	81 50       	subi	r24, 0x01	; 1
+    7ed6:	80 93 02 02 	sts	0x0202, r24
+    7eda:	88 23       	and	r24, r24
+    7edc:	b9 f7       	brne	.-18     	; 0x7ecc <main+0xcc>
 
 
       // Read command terminator, start reply
       // Read command terminator, start reply
       verifySpace();
       verifySpace();
-    7ec8:	8b d0       	rcall	.+278    	; 0x7fe0 <verifySpace>
+    7ede:	78 d0       	rcall	.+240    	; 0x7fd0 <verifySpace>
       
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       // So check that here
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    7eca:	07 b6       	in	r0, 0x37	; 55
-    7ecc:	00 fc       	sbrc	r0, 0
-    7ece:	fd cf       	rjmp	.-6      	; 0x7eca <main+0xca>
+    7ee0:	07 b6       	in	r0, 0x37	; 55
+    7ee2:	00 fc       	sbrc	r0, 0
+    7ee4:	fd cf       	rjmp	.-6      	; 0x7ee0 <main+0xe0>
+      }
+#endif
 
 
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       addrPtr = (uint16_t)(void*)address;
-    7ed0:	40 91 00 02 	lds	r20, 0x0200
-    7ed4:	50 91 01 02 	lds	r21, 0x0201
-    7ed8:	a0 e0       	ldi	r26, 0x00	; 0
-    7eda:	b1 e0       	ldi	r27, 0x01	; 1
+    7ee6:	40 91 00 02 	lds	r20, 0x0200
+    7eea:	50 91 01 02 	lds	r21, 0x0201
+    7eee:	a0 e0       	ldi	r26, 0x00	; 0
+    7ef0:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
-    7edc:	2c 91       	ld	r18, X
-    7ede:	30 e0       	ldi	r19, 0x00	; 0
+    7ef2:	2c 91       	ld	r18, X
+    7ef4:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
-    7ee0:	11 96       	adiw	r26, 0x01	; 1
-    7ee2:	8c 91       	ld	r24, X
-    7ee4:	11 97       	sbiw	r26, 0x01	; 1
-    7ee6:	90 e0       	ldi	r25, 0x00	; 0
-    7ee8:	98 2f       	mov	r25, r24
-    7eea:	88 27       	eor	r24, r24
-    7eec:	82 2b       	or	r24, r18
-    7eee:	93 2b       	or	r25, r19
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+    7ef6:	11 96       	adiw	r26, 0x01	; 1
+    7ef8:	8c 91       	ld	r24, X
+    7efa:	11 97       	sbiw	r26, 0x01	; 1
+    7efc:	90 e0       	ldi	r25, 0x00	; 0
+    7efe:	98 2f       	mov	r25, r24
+    7f00:	88 27       	eor	r24, r24
+    7f02:	82 2b       	or	r24, r18
+    7f04:	93 2b       	or	r25, r19
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
-    7ef0:	12 96       	adiw	r26, 0x02	; 2
+    7f06:	12 96       	adiw	r26, 0x02	; 2
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
-    7ef2:	fa 01       	movw	r30, r20
-    7ef4:	0c 01       	movw	r0, r24
-    7ef6:	d0 92 57 00 	sts	0x0057, r13
-    7efa:	e8 95       	spm
-    7efc:	11 24       	eor	r1, r1
+    7f08:	fa 01       	movw	r30, r20
+    7f0a:	0c 01       	movw	r0, r24
+    7f0c:	d0 92 57 00 	sts	0x0057, r13
+    7f10:	e8 95       	spm
+    7f12:	11 24       	eor	r1, r1
         addrPtr += 2;
         addrPtr += 2;
-    7efe:	4e 5f       	subi	r20, 0xFE	; 254
-    7f00:	5f 4f       	sbci	r21, 0xFF	; 255
+    7f14:	4e 5f       	subi	r20, 0xFE	; 254
+    7f16:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
       } while (--ch);
-    7f02:	f1 e0       	ldi	r31, 0x01	; 1
-    7f04:	a0 38       	cpi	r26, 0x80	; 128
-    7f06:	bf 07       	cpc	r27, r31
-    7f08:	49 f7       	brne	.-46     	; 0x7edc <main+0xdc>
+    7f18:	f1 e0       	ldi	r31, 0x01	; 1
+    7f1a:	a0 38       	cpi	r26, 0x80	; 128
+    7f1c:	bf 07       	cpc	r27, r31
+    7f1e:	49 f7       	brne	.-46     	; 0x7ef2 <main+0xf2>
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    7f0a:	e0 91 00 02 	lds	r30, 0x0200
-    7f0e:	f0 91 01 02 	lds	r31, 0x0201
-    7f12:	e0 92 57 00 	sts	0x0057, r14
-    7f16:	e8 95       	spm
+    7f20:	e0 91 00 02 	lds	r30, 0x0200
+    7f24:	f0 91 01 02 	lds	r31, 0x0201
+    7f28:	e0 92 57 00 	sts	0x0057, r14
+    7f2c:	e8 95       	spm
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    7f18:	07 b6       	in	r0, 0x37	; 55
-    7f1a:	00 fc       	sbrc	r0, 0
-    7f1c:	fd cf       	rjmp	.-6      	; 0x7f18 <main+0x118>
+    7f2e:	07 b6       	in	r0, 0x37	; 55
+    7f30:	00 fc       	sbrc	r0, 0
+    7f32:	fd cf       	rjmp	.-6      	; 0x7f2e <main+0x12e>
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    7f1e:	f0 92 57 00 	sts	0x0057, r15
-    7f22:	e8 95       	spm
-    7f24:	27 c0       	rjmp	.+78     	; 0x7f74 <main+0x174>
+    7f34:	f0 92 57 00 	sts	0x0057, r15
+    7f38:	e8 95       	spm
+    7f3a:	27 c0       	rjmp	.+78     	; 0x7f8a <main+0x18a>
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
-    7f26:	84 37       	cpi	r24, 0x74	; 116
-    7f28:	b9 f4       	brne	.+46     	; 0x7f58 <main+0x158>
+    7f3c:	84 37       	cpi	r24, 0x74	; 116
+    7f3e:	b9 f4       	brne	.+46     	; 0x7f6e <main+0x16e>
       // READ PAGE - we only read flash
       // READ PAGE - we only read flash
       getLen();
       getLen();
-    7f2a:	4a d0       	rcall	.+148    	; 0x7fc0 <getLen>
+    7f40:	37 d0       	rcall	.+110    	; 0x7fb0 <getLen>
       verifySpace();
       verifySpace();
-    7f2c:	59 d0       	rcall	.+178    	; 0x7fe0 <verifySpace>
+    7f42:	46 d0       	rcall	.+140    	; 0x7fd0 <verifySpace>
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
-    7f2e:	e0 91 00 02 	lds	r30, 0x0200
-    7f32:	f0 91 01 02 	lds	r31, 0x0201
-    7f36:	31 96       	adiw	r30, 0x01	; 1
-    7f38:	f0 93 01 02 	sts	0x0201, r31
-    7f3c:	e0 93 00 02 	sts	0x0200, r30
-    7f40:	31 97       	sbiw	r30, 0x01	; 1
-    7f42:	e4 91       	lpm	r30, Z+
-    7f44:	8e 2f       	mov	r24, r30
-    7f46:	19 d0       	rcall	.+50     	; 0x7f7a <putch>
+    7f44:	e0 91 00 02 	lds	r30, 0x0200
+    7f48:	f0 91 01 02 	lds	r31, 0x0201
+    7f4c:	31 96       	adiw	r30, 0x01	; 1
+    7f4e:	f0 93 01 02 	sts	0x0201, r31
+    7f52:	e0 93 00 02 	sts	0x0200, r30
+    7f56:	31 97       	sbiw	r30, 0x01	; 1
+    7f58:	e4 91       	lpm	r30, Z+
+    7f5a:	8e 2f       	mov	r24, r30
+    7f5c:	19 d0       	rcall	.+50     	; 0x7f90 <putch>
       while (--length);
       while (--length);
-    7f48:	80 91 02 02 	lds	r24, 0x0202
-    7f4c:	81 50       	subi	r24, 0x01	; 1
-    7f4e:	80 93 02 02 	sts	0x0202, r24
-    7f52:	88 23       	and	r24, r24
-    7f54:	61 f7       	brne	.-40     	; 0x7f2e <main+0x12e>
-    7f56:	0e c0       	rjmp	.+28     	; 0x7f74 <main+0x174>
+    7f5e:	80 91 02 02 	lds	r24, 0x0202
+    7f62:	81 50       	subi	r24, 0x01	; 1
+    7f64:	80 93 02 02 	sts	0x0202, r24
+    7f68:	88 23       	and	r24, r24
+    7f6a:	61 f7       	brne	.-40     	; 0x7f44 <main+0x144>
+    7f6c:	0e c0       	rjmp	.+28     	; 0x7f8a <main+0x18a>
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
     else if(ch == STK_READ_SIGN) {
-    7f58:	85 37       	cpi	r24, 0x75	; 117
-    7f5a:	39 f4       	brne	.+14     	; 0x7f6a <main+0x16a>
+    7f6e:	85 37       	cpi	r24, 0x75	; 117
+    7f70:	39 f4       	brne	.+14     	; 0x7f80 <main+0x180>
       // READ SIGN - return what Avrdude wants to hear
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
       verifySpace();
-    7f5c:	41 d0       	rcall	.+130    	; 0x7fe0 <verifySpace>
+    7f72:	2e d0       	rcall	.+92     	; 0x7fd0 <verifySpace>
       putch(SIGNATURE_0);
       putch(SIGNATURE_0);
-    7f5e:	8e e1       	ldi	r24, 0x1E	; 30
-    7f60:	0c d0       	rcall	.+24     	; 0x7f7a <putch>
+    7f74:	8e e1       	ldi	r24, 0x1E	; 30
+    7f76:	0c d0       	rcall	.+24     	; 0x7f90 <putch>
       putch(SIGNATURE_1);
       putch(SIGNATURE_1);
-    7f62:	85 e9       	ldi	r24, 0x95	; 149
-    7f64:	0a d0       	rcall	.+20     	; 0x7f7a <putch>
+    7f78:	85 e9       	ldi	r24, 0x95	; 149
+    7f7a:	0a d0       	rcall	.+20     	; 0x7f90 <putch>
       putch(SIGNATURE_2);
       putch(SIGNATURE_2);
-    7f66:	8f e0       	ldi	r24, 0x0F	; 15
-    7f68:	96 cf       	rjmp	.-212    	; 0x7e96 <main+0x96>
+    7f7c:	8f e0       	ldi	r24, 0x0F	; 15
+    7f7e:	96 cf       	rjmp	.-212    	; 0x7eac <main+0xac>
     }
     }
     else if (ch == 'Q') {
     else if (ch == 'Q') {
-    7f6a:	81 35       	cpi	r24, 0x51	; 81
-    7f6c:	11 f4       	brne	.+4      	; 0x7f72 <main+0x172>
+    7f80:	81 35       	cpi	r24, 0x51	; 81
+    7f82:	11 f4       	brne	.+4      	; 0x7f88 <main+0x188>
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
-    7f6e:	88 e0       	ldi	r24, 0x08	; 8
-    7f70:	2c d0       	rcall	.+88     	; 0x7fca <watchdogConfig>
+      watchdogConfig(WATCHDOG_16MS);
+    7f84:	88 e0       	ldi	r24, 0x08	; 8
+    7f86:	19 d0       	rcall	.+50     	; 0x7fba <watchdogConfig>
       verifySpace();
       verifySpace();
     }
     }
     else {
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
       verifySpace();
-    7f72:	36 d0       	rcall	.+108    	; 0x7fe0 <verifySpace>
+    7f88:	23 d0       	rcall	.+70     	; 0x7fd0 <verifySpace>
     }
     }
     putch(STK_OK);
     putch(STK_OK);
-    7f74:	80 e1       	ldi	r24, 0x10	; 16
-    7f76:	01 d0       	rcall	.+2      	; 0x7f7a <putch>
-    7f78:	63 cf       	rjmp	.-314    	; 0x7e40 <main+0x40>
+    7f8a:	80 e1       	ldi	r24, 0x10	; 16
+    7f8c:	01 d0       	rcall	.+2      	; 0x7f90 <putch>
+    7f8e:	63 cf       	rjmp	.-314    	; 0x7e56 <main+0x56>
+
+00007f90 <putch>:
+  }
+}
 
 
-00007f7a <putch>:
 void putch(char ch) {
 void putch(char ch) {
+    7f90:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
   while (!(UCSR0A & _BV(UDRE0)));
+    7f92:	80 91 c0 00 	lds	r24, 0x00C0
+    7f96:	85 ff       	sbrs	r24, 5
+    7f98:	fc cf       	rjmp	.-8      	; 0x7f92 <putch+0x2>
   UDR0 = ch;
   UDR0 = ch;
-#else
-  __asm__ __volatile__ (
-    7f7a:	2a e0       	ldi	r18, 0x0A	; 10
-    7f7c:	30 e0       	ldi	r19, 0x00	; 0
-    7f7e:	80 95       	com	r24
-    7f80:	08 94       	sec
-    7f82:	10 f4       	brcc	.+4      	; 0x7f88 <putch+0xe>
-    7f84:	59 98       	cbi	0x0b, 1	; 11
-    7f86:	02 c0       	rjmp	.+4      	; 0x7f8c <putch+0x12>
-    7f88:	59 9a       	sbi	0x0b, 1	; 11
-    7f8a:	00 00       	nop
-    7f8c:	15 d0       	rcall	.+42     	; 0x7fb8 <uartDelay>
-    7f8e:	14 d0       	rcall	.+40     	; 0x7fb8 <uartDelay>
-    7f90:	86 95       	lsr	r24
-    7f92:	2a 95       	dec	r18
-    7f94:	b1 f7       	brne	.-20     	; 0x7f82 <putch+0x8>
+    7f9a:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
       [uartBit] "I" (UART_TX_BIT)
     :
     :
       "r25"
       "r25"
   );
   );
 #endif
 #endif
 }
 }
-    7f96:	08 95       	ret
+    7f9e:	08 95       	ret
 
 
-00007f98 <getch>:
+00007fa0 <getch>:
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    7f98:	a8 95       	wdr
+    7fa0:	a8 95       	wdr
+      [uartBit] "I" (UART_RX_BIT)
+    :
+      "r25"
+);
+#else
+  while(!(UCSR0A & _BV(RXC0)));
+    7fa2:	80 91 c0 00 	lds	r24, 0x00C0
+    7fa6:	87 ff       	sbrs	r24, 7
+    7fa8:	fc cf       	rjmp	.-8      	; 0x7fa2 <getch+0x2>
+  ch = UDR0;
+    7faa:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
 
   return ch;
   return ch;
 }
 }
-    7f9a:	29 e0       	ldi	r18, 0x09	; 9
-    7f9c:	30 e0       	ldi	r19, 0x00	; 0
-    7f9e:	48 99       	sbic	0x09, 0	; 9
-    7fa0:	fe cf       	rjmp	.-4      	; 0x7f9e <getch+0x6>
-    7fa2:	0a d0       	rcall	.+20     	; 0x7fb8 <uartDelay>
-    7fa4:	09 d0       	rcall	.+18     	; 0x7fb8 <uartDelay>
-    7fa6:	08 d0       	rcall	.+16     	; 0x7fb8 <uartDelay>
-    7fa8:	88 94       	clc
-    7faa:	48 99       	sbic	0x09, 0	; 9
-    7fac:	08 94       	sec
-    7fae:	2a 95       	dec	r18
-    7fb0:	11 f0       	breq	.+4      	; 0x7fb6 <getch+0x1e>
-    7fb2:	87 95       	ror	r24
-    7fb4:	f7 cf       	rjmp	.-18     	; 0x7fa4 <getch+0xc>
-    7fb6:	08 95       	ret
-
-00007fb8 <uartDelay>:
-#if UART_B_VALUE > 255
-#error Baud rate too slow for soft UART
-#endif
-
-void uartDelay() {
-  __asm__ __volatile__ (
-    7fb8:	98 e0       	ldi	r25, 0x08	; 8
-    7fba:	9a 95       	dec	r25
-    7fbc:	f1 f7       	brne	.-4      	; 0x7fba <uartDelay+0x2>
-    7fbe:	08 95       	ret
+    7fae:	08 95       	ret
 
 
-00007fc0 <getLen>:
+00007fb0 <getLen>:
   } while (--count);
   } while (--count);
 }
 }
 #endif
 #endif
 
 
 uint8_t getLen() {
 uint8_t getLen() {
   getch();
   getch();
-    7fc0:	eb df       	rcall	.-42     	; 0x7f98 <getch>
+    7fb0:	f7 df       	rcall	.-18     	; 0x7fa0 <getch>
   length = getch();
   length = getch();
-    7fc2:	ea df       	rcall	.-44     	; 0x7f98 <getch>
-    7fc4:	80 93 02 02 	sts	0x0202, r24
+    7fb2:	f6 df       	rcall	.-20     	; 0x7fa0 <getch>
+    7fb4:	80 93 02 02 	sts	0x0202, r24
   return getch();
   return getch();
 }
 }
-    7fc8:	e7 cf       	rjmp	.-50     	; 0x7f98 <getch>
+    7fb8:	f3 cf       	rjmp	.-26     	; 0x7fa0 <getch>
 
 
-00007fca <watchdogConfig>:
+00007fba <watchdogConfig>:
     "wdr\n"
     "wdr\n"
   );
   );
 }
 }
 
 
 void watchdogConfig(uint8_t x) {
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7fca:	e0 e6       	ldi	r30, 0x60	; 96
-    7fcc:	f0 e0       	ldi	r31, 0x00	; 0
-    7fce:	98 e1       	ldi	r25, 0x18	; 24
-    7fd0:	90 83       	st	Z, r25
+    7fba:	e0 e6       	ldi	r30, 0x60	; 96
+    7fbc:	f0 e0       	ldi	r31, 0x00	; 0
+    7fbe:	98 e1       	ldi	r25, 0x18	; 24
+    7fc0:	90 83       	st	Z, r25
   WDTCSR = x;
   WDTCSR = x;
-    7fd2:	80 83       	st	Z, r24
+    7fc2:	80 83       	st	Z, r24
 }
 }
-    7fd4:	08 95       	ret
+    7fc4:	08 95       	ret
 
 
-00007fd6 <appStart>:
+00007fc6 <appStart>:
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
-    7fd6:	80 e0       	ldi	r24, 0x00	; 0
-    7fd8:	f8 df       	rcall	.-16     	; 0x7fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_OFF);
+    7fc6:	80 e0       	ldi	r24, 0x00	; 0
+    7fc8:	f8 df       	rcall	.-16     	; 0x7fba <watchdogConfig>
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    7fda:	ee 27       	eor	r30, r30
-    7fdc:	ff 27       	eor	r31, r31
-    7fde:	09 94       	ijmp
+    7fca:	ee 27       	eor	r30, r30
+    7fcc:	ff 27       	eor	r31, r31
+    7fce:	09 94       	ijmp
 
 
-00007fe0 <verifySpace>:
+00007fd0 <verifySpace>:
   do getch(); while (--count);
   do getch(); while (--count);
   verifySpace();
   verifySpace();
 }
 }
 
 
 void verifySpace() {
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
   if (getch() != CRC_EOP) appStart();
-    7fe0:	db df       	rcall	.-74     	; 0x7f98 <getch>
-    7fe2:	80 32       	cpi	r24, 0x20	; 32
-    7fe4:	09 f0       	breq	.+2      	; 0x7fe8 <verifySpace+0x8>
-    7fe6:	f7 df       	rcall	.-18     	; 0x7fd6 <appStart>
+    7fd0:	e7 df       	rcall	.-50     	; 0x7fa0 <getch>
+    7fd2:	80 32       	cpi	r24, 0x20	; 32
+    7fd4:	09 f0       	breq	.+2      	; 0x7fd8 <verifySpace+0x8>
+    7fd6:	f7 df       	rcall	.-18     	; 0x7fc6 <appStart>
   putch(STK_INSYNC);
   putch(STK_INSYNC);
-    7fe8:	84 e1       	ldi	r24, 0x14	; 20
+    7fd8:	84 e1       	ldi	r24, 0x14	; 20
 }
 }
-    7fea:	c7 cf       	rjmp	.-114    	; 0x7f7a <putch>
+    7fda:	da cf       	rjmp	.-76     	; 0x7f90 <putch>
     ::[count] "M" (UART_B_VALUE)
     ::[count] "M" (UART_B_VALUE)
   );
   );
 }
 }
 #endif
 #endif
 
 
 void getNch(uint8_t count) {
 void getNch(uint8_t count) {
-    7fec:	1f 93       	push	r17
-    7fee:	18 2f       	mov	r17, r24
+    7fdc:	1f 93       	push	r17
+    7fde:	18 2f       	mov	r17, r24
 
 
-00007ff0 <getNch>:
+00007fe0 <getNch>:
   do getch(); while (--count);
   do getch(); while (--count);
-    7ff0:	d3 df       	rcall	.-90     	; 0x7f98 <getch>
-    7ff2:	11 50       	subi	r17, 0x01	; 1
-    7ff4:	e9 f7       	brne	.-6      	; 0x7ff0 <getNch>
+    7fe0:	df df       	rcall	.-66     	; 0x7fa0 <getch>
+    7fe2:	11 50       	subi	r17, 0x01	; 1
+    7fe4:	e9 f7       	brne	.-6      	; 0x7fe0 <getNch>
   verifySpace();
   verifySpace();
-    7ff6:	f4 df       	rcall	.-24     	; 0x7fe0 <verifySpace>
+    7fe6:	f4 df       	rcall	.-24     	; 0x7fd0 <verifySpace>
 }
 }
-    7ff8:	1f 91       	pop	r17
-    7ffa:	08 95       	ret
+    7fe8:	1f 91       	pop	r17
+    7fea:	08 95       	ret

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

@@ -1,34 +1,33 @@
-:107E000085E08093810084B714BE81FFE4D08DE0CB
-:107E1000DCD0259A519A86E028E13EEF91E030933C
-:107E200085002093840096BBB09BFECF1D9AA89539
-:107E30008150A9F7DD24D394A5E0EA2EF1E1FF2ECD
-:107E4000ABD0813421F481E0D1D083E024C08234EE
-:107E500011F484E103C0853419F485E0C7D08AC0E9
-:107E60008535A1F499D0082F10E0109301020093FA
-:107E7000000292D090E0982F8827802B912B880FBA
-:107E8000991F909301028093000273C0863529F4F4
-:107E900084E0ACD080E071D06DC0843609F043C07E
-:107EA0008FD0E0910002F091010283E080935700AF
-:107EB000E895C0E0D1E070D08993809102028150B2
-:107EC000809302028823B9F78BD007B600FCFDCF60
-:107ED0004091000250910102A0E0B1E02C9130E00D
-:107EE00011968C91119790E0982F8827822B932BD5
-:107EF0001296FA010C01D0925700E89511244E5FBA
-:107F00005F4FF1E0A038BF0749F7E0910002F09120
-:107F10000102E0925700E89507B600FCFDCFF09211
-:107F20005700E89527C08437B9F44AD059D0E0917A
-:107F30000002F09101023196F0930102E0930002F9
-:107F40003197E4918E2F19D0809102028150809355
-:107F50000202882361F70EC0853739F441D08EE1E3
-:107F60000CD085E90AD08FE096CF813511F488E0F6
-:107F70002CD036D080E101D063CF2AE030E080956C
-:107F8000089410F4599802C0599A000015D014D0E2
-:107F900086952A95B1F70895A89529E030E048998B
-:107FA000FECF0AD009D008D08894489908942A9521
-:107FB00011F08795F7CF089598E09A95F1F7089515
-:107FC000EBDFEADF80930202E7CFE0E6F0E098E142
-:107FD00090838083089580E0F8DFEE27FF270994DF
-:107FE000DBDF803209F0F7DF84E1C7CF1F93182F62
-:0C7FF000D3DF1150E9F7F4DF1F91089572
+:107E000085E08093810082E08093C00088E18093C8
+:107E1000C10086E08093C20088E08093C40084B7EC
+:107E200014BE81FFD0D08DE0C8D0259A86E028E12D
+:107E30003EEF91E0309385002093840096BBB09B89
+:107E4000FECF1D9AA8958150A9F7DD24D394A5E013
+:107E5000EA2EF1E1FF2EA4D0813421F481E0BED0DE
+:107E600083E024C0823411F484E103C0853419F422
+:107E700085E0B4D08AC08535A1F492D0082F10E0F7
+:107E800010930102009300028BD090E0982F882776
+:107E9000802B912B880F991F9093010280930002F1
+:107EA00073C0863529F484E099D080E071D06DC02C
+:107EB000843609F043C07CD0E0910002F0910102C9
+:107EC00083E080935700E895C0E0D1E069D08993C2
+:107ED000809102028150809302028823B9F778D002
+:107EE00007B600FCFDCF4091000250910102A0E0D6
+:107EF000B1E02C9130E011968C91119790E0982F81
+:107F00008827822B932B1296FA010C01D0925700EE
+:107F1000E89511244E5F5F4FF1E0A038BF0749F7A5
+:107F2000E0910002F0910102E0925700E89507B657
+:107F300000FCFDCFF0925700E89527C08437B9F4D4
+:107F400037D046D0E0910002F09101023196F093D3
+:107F50000102E09300023197E4918E2F19D08091B5
+:107F60000202815080930202882361F70EC0853798
+:107F700039F42ED08EE10CD085E90AD08FE096CF6F
+:107F8000813511F488E019D023D080E101D063CF8E
+:107F9000982F8091C00085FFFCCF9093C600089574
+:107FA000A8958091C00087FFFCCF8091C6000895FE
+:107FB000F7DFF6DF80930202F3CFE0E6F0E098E12E
+:107FC00090838083089580E0F8DFEE27FF270994EF
+:107FD000E7DF803209F0F7DF84E1DACF1F93182F53
+:0C7FE000DFDF1150E9F7F4DF1F91089576
 :0400000300007E007B
 :0400000300007E007B
 :00000001FF
 :00000001FF

+ 267 - 268
optiboot/bootloaders/optiboot/optiboot_atmega328_pro_8MHz.lst

@@ -3,519 +3,518 @@ optiboot_atmega328_pro_8MHz.elf:     file format elf32-avr
 
 
 Sections:
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001fc  00007e00  00007e00  00000054  2**1
+  0 .text         000001ec  00007e00  00007e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000250  2**0
+  1 .debug_aranges 00000028  00000000  00000000  00000240  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000268  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000275  00000000  00000000  000002f0  2**0
+  3 .debug_info   00000269  00000000  00000000  000002d2  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a3  00000000  00000000  00000565  2**0
+  4 .debug_abbrev 00000196  00000000  00000000  0000053b  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003b8  00000000  00000000  00000708  2**0
+  5 .debug_line   000003d3  00000000  00000000  000006d1  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  000000a0  00000000  00000000  00000ac0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000aa4  2**2
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000133  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000135  00000000  00000000  00000b34  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001a0  00000000  00000000  00000c93  2**0
+  8 .debug_loc    000001d1  00000000  00000000  00000c69  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000070  00000000  00000000  00000e33  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000e3a  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
 
 
 Disassembly of section .text:
 Disassembly of section .text:
 
 
 00007e00 <main>:
 00007e00 <main>:
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     7e00:	85 e0       	ldi	r24, 0x05	; 5
     7e00:	85 e0       	ldi	r24, 0x05	; 5
     7e02:	80 93 81 00 	sts	0x0081, r24
     7e02:	80 93 81 00 	sts	0x0081, r24
+#if LED_START_FLASHES > 0
+  // Set up Timer 1 for timeout counter
+  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+#endif
+#ifndef SOFT_UART
+  UCSR0A = _BV(U2X0); //Double speed mode USART0
+    7e06:	82 e0       	ldi	r24, 0x02	; 2
+    7e08:	80 93 c0 00 	sts	0x00C0, r24
+  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+    7e0c:	88 e1       	ldi	r24, 0x18	; 24
+    7e0e:	80 93 c1 00 	sts	0x00C1, r24
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+    7e12:	86 e0       	ldi	r24, 0x06	; 6
+    7e14:	80 93 c2 00 	sts	0x00C2, r24
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+    7e18:	88 e0       	ldi	r24, 0x08	; 8
+    7e1a:	80 93 c4 00 	sts	0x00C4, r24
 #endif
 #endif
 
 
   // Adaboot no-wait mod
   // Adaboot no-wait mod
   ch = MCUSR;
   ch = MCUSR;
-    7e06:	84 b7       	in	r24, 0x34	; 52
+    7e1e:	84 b7       	in	r24, 0x34	; 52
   MCUSR = 0;
   MCUSR = 0;
-    7e08:	14 be       	out	0x34, r1	; 52
+    7e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
   if (!(ch & _BV(EXTRF))) appStart();
-    7e0a:	81 ff       	sbrs	r24, 1
-    7e0c:	e4 d0       	rcall	.+456    	; 0x7fd6 <appStart>
+    7e22:	81 ff       	sbrs	r24, 1
+    7e24:	d0 d0       	rcall	.+416    	; 0x7fc6 <appStart>
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
-    7e0e:	8d e0       	ldi	r24, 0x0D	; 13
-    7e10:	dc d0       	rcall	.+440    	; 0x7fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_500MS);
+    7e26:	8d e0       	ldi	r24, 0x0D	; 13
+    7e28:	c8 d0       	rcall	.+400    	; 0x7fba <watchdogConfig>
 
 
   /* Set LED pin as output */
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
   LED_DDR |= _BV(LED);
-    7e12:	25 9a       	sbi	0x04, 5	; 4
-
-#ifdef SOFT_UART
-  /* Set TX pin as output */
-  UART_DDR |= _BV(UART_TX_BIT);
-    7e14:	51 9a       	sbi	0x0a, 1	; 10
-    7e16:	86 e0       	ldi	r24, 0x06	; 6
+    7e2a:	25 9a       	sbi	0x04, 5	; 4
+    7e2c:	86 e0       	ldi	r24, 0x06	; 6
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    7e18:	28 e1       	ldi	r18, 0x18	; 24
-    7e1a:	3e ef       	ldi	r19, 0xFE	; 254
+    7e2e:	28 e1       	ldi	r18, 0x18	; 24
+    7e30:	3e ef       	ldi	r19, 0xFE	; 254
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    7e1c:	91 e0       	ldi	r25, 0x01	; 1
+    7e32:	91 e0       	ldi	r25, 0x01	; 1
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    7e1e:	30 93 85 00 	sts	0x0085, r19
-    7e22:	20 93 84 00 	sts	0x0084, r18
+    7e34:	30 93 85 00 	sts	0x0085, r19
+    7e38:	20 93 84 00 	sts	0x0084, r18
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    7e26:	96 bb       	out	0x16, r25	; 22
+    7e3c:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
-    7e28:	b0 9b       	sbis	0x16, 0	; 22
-    7e2a:	fe cf       	rjmp	.-4      	; 0x7e28 <main+0x28>
+    7e3e:	b0 9b       	sbis	0x16, 0	; 22
+    7e40:	fe cf       	rjmp	.-4      	; 0x7e3e <main+0x3e>
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
-    7e2c:	1d 9a       	sbi	0x03, 5	; 3
+    7e42:	1d 9a       	sbi	0x03, 5	; 3
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    7e2e:	a8 95       	wdr
+    7e44:	a8 95       	wdr
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
     watchdogReset();
     watchdogReset();
   } while (--count);
   } while (--count);
-    7e30:	81 50       	subi	r24, 0x01	; 1
-    7e32:	a9 f7       	brne	.-22     	; 0x7e1e <main+0x1e>
+    7e46:	81 50       	subi	r24, 0x01	; 1
+    7e48:	a9 f7       	brne	.-22     	; 0x7e34 <main+0x34>
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    7e34:	dd 24       	eor	r13, r13
-    7e36:	d3 94       	inc	r13
+    7e4a:	dd 24       	eor	r13, r13
+    7e4c:	d3 94       	inc	r13
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         addrPtr += 2;
         addrPtr += 2;
       } while (--ch);
       } while (--ch);
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    7e38:	a5 e0       	ldi	r26, 0x05	; 5
-    7e3a:	ea 2e       	mov	r14, r26
+    7e4e:	a5 e0       	ldi	r26, 0x05	; 5
+    7e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    7e3c:	f1 e1       	ldi	r31, 0x11	; 17
-    7e3e:	ff 2e       	mov	r15, r31
+    7e52:	f1 e1       	ldi	r31, 0x11	; 17
+    7e54:	ff 2e       	mov	r15, r31
 #endif
 #endif
 
 
   /* Forever loop */
   /* Forever loop */
   for (;;) {
   for (;;) {
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
-    7e40:	ab d0       	rcall	.+342    	; 0x7f98 <getch>
+    7e56:	a4 d0       	rcall	.+328    	; 0x7fa0 <getch>
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
-    7e42:	81 34       	cpi	r24, 0x41	; 65
-    7e44:	21 f4       	brne	.+8      	; 0x7e4e <main+0x4e>
+    7e58:	81 34       	cpi	r24, 0x41	; 65
+    7e5a:	21 f4       	brne	.+8      	; 0x7e64 <main+0x64>
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    7e46:	81 e0       	ldi	r24, 0x01	; 1
-    7e48:	d1 d0       	rcall	.+418    	; 0x7fec <verifySpace+0xc>
+    7e5c:	81 e0       	ldi	r24, 0x01	; 1
+    7e5e:	be d0       	rcall	.+380    	; 0x7fdc <verifySpace+0xc>
       putch(0x03);
       putch(0x03);
-    7e4a:	83 e0       	ldi	r24, 0x03	; 3
-    7e4c:	24 c0       	rjmp	.+72     	; 0x7e96 <main+0x96>
+    7e60:	83 e0       	ldi	r24, 0x03	; 3
+    7e62:	24 c0       	rjmp	.+72     	; 0x7eac <main+0xac>
     }
     }
     else if(ch == STK_SET_DEVICE) {
     else if(ch == STK_SET_DEVICE) {
-    7e4e:	82 34       	cpi	r24, 0x42	; 66
-    7e50:	11 f4       	brne	.+4      	; 0x7e56 <main+0x56>
+    7e64:	82 34       	cpi	r24, 0x42	; 66
+    7e66:	11 f4       	brne	.+4      	; 0x7e6c <main+0x6c>
       // SET DEVICE is ignored
       // SET DEVICE is ignored
       getNch(20);
       getNch(20);
-    7e52:	84 e1       	ldi	r24, 0x14	; 20
-    7e54:	03 c0       	rjmp	.+6      	; 0x7e5c <main+0x5c>
+    7e68:	84 e1       	ldi	r24, 0x14	; 20
+    7e6a:	03 c0       	rjmp	.+6      	; 0x7e72 <main+0x72>
     }
     }
     else if(ch == STK_SET_DEVICE_EXT) {
     else if(ch == STK_SET_DEVICE_EXT) {
-    7e56:	85 34       	cpi	r24, 0x45	; 69
-    7e58:	19 f4       	brne	.+6      	; 0x7e60 <main+0x60>
+    7e6c:	85 34       	cpi	r24, 0x45	; 69
+    7e6e:	19 f4       	brne	.+6      	; 0x7e76 <main+0x76>
       // SET DEVICE EXT is ignored
       // SET DEVICE EXT is ignored
       getNch(5);
       getNch(5);
-    7e5a:	85 e0       	ldi	r24, 0x05	; 5
-    7e5c:	c7 d0       	rcall	.+398    	; 0x7fec <verifySpace+0xc>
-    7e5e:	8a c0       	rjmp	.+276    	; 0x7f74 <main+0x174>
+    7e70:	85 e0       	ldi	r24, 0x05	; 5
+    7e72:	b4 d0       	rcall	.+360    	; 0x7fdc <verifySpace+0xc>
+    7e74:	8a c0       	rjmp	.+276    	; 0x7f8a <main+0x18a>
     }
     }
     else if(ch == STK_LOAD_ADDRESS) {
     else if(ch == STK_LOAD_ADDRESS) {
-    7e60:	85 35       	cpi	r24, 0x55	; 85
-    7e62:	a1 f4       	brne	.+40     	; 0x7e8c <main+0x8c>
+    7e76:	85 35       	cpi	r24, 0x55	; 85
+    7e78:	a1 f4       	brne	.+40     	; 0x7ea2 <main+0xa2>
       // LOAD ADDRESS
       // LOAD ADDRESS
       address = getch();
       address = getch();
-    7e64:	99 d0       	rcall	.+306    	; 0x7f98 <getch>
-    7e66:	08 2f       	mov	r16, r24
-    7e68:	10 e0       	ldi	r17, 0x00	; 0
-    7e6a:	10 93 01 02 	sts	0x0201, r17
-    7e6e:	00 93 00 02 	sts	0x0200, r16
+    7e7a:	92 d0       	rcall	.+292    	; 0x7fa0 <getch>
+    7e7c:	08 2f       	mov	r16, r24
+    7e7e:	10 e0       	ldi	r17, 0x00	; 0
+    7e80:	10 93 01 02 	sts	0x0201, r17
+    7e84:	00 93 00 02 	sts	0x0200, r16
       address = (address & 0xff) | (getch() << 8);
       address = (address & 0xff) | (getch() << 8);
-    7e72:	92 d0       	rcall	.+292    	; 0x7f98 <getch>
-    7e74:	90 e0       	ldi	r25, 0x00	; 0
-    7e76:	98 2f       	mov	r25, r24
-    7e78:	88 27       	eor	r24, r24
-    7e7a:	80 2b       	or	r24, r16
-    7e7c:	91 2b       	or	r25, r17
+    7e88:	8b d0       	rcall	.+278    	; 0x7fa0 <getch>
+    7e8a:	90 e0       	ldi	r25, 0x00	; 0
+    7e8c:	98 2f       	mov	r25, r24
+    7e8e:	88 27       	eor	r24, r24
+    7e90:	80 2b       	or	r24, r16
+    7e92:	91 2b       	or	r25, r17
       address += address; // Convert from word address to byte address
       address += address; // Convert from word address to byte address
-    7e7e:	88 0f       	add	r24, r24
-    7e80:	99 1f       	adc	r25, r25
-    7e82:	90 93 01 02 	sts	0x0201, r25
-    7e86:	80 93 00 02 	sts	0x0200, r24
-    7e8a:	73 c0       	rjmp	.+230    	; 0x7f72 <main+0x172>
+    7e94:	88 0f       	add	r24, r24
+    7e96:	99 1f       	adc	r25, r25
+    7e98:	90 93 01 02 	sts	0x0201, r25
+    7e9c:	80 93 00 02 	sts	0x0200, r24
+    7ea0:	73 c0       	rjmp	.+230    	; 0x7f88 <main+0x188>
       verifySpace();
       verifySpace();
     }
     }
     else if(ch == STK_UNIVERSAL) {
     else if(ch == STK_UNIVERSAL) {
-    7e8c:	86 35       	cpi	r24, 0x56	; 86
-    7e8e:	29 f4       	brne	.+10     	; 0x7e9a <main+0x9a>
+    7ea2:	86 35       	cpi	r24, 0x56	; 86
+    7ea4:	29 f4       	brne	.+10     	; 0x7eb0 <main+0xb0>
       // UNIVERSAL command is ignored
       // UNIVERSAL command is ignored
       getNch(4);
       getNch(4);
-    7e90:	84 e0       	ldi	r24, 0x04	; 4
-    7e92:	ac d0       	rcall	.+344    	; 0x7fec <verifySpace+0xc>
+    7ea6:	84 e0       	ldi	r24, 0x04	; 4
+    7ea8:	99 d0       	rcall	.+306    	; 0x7fdc <verifySpace+0xc>
       putch(0x00);
       putch(0x00);
-    7e94:	80 e0       	ldi	r24, 0x00	; 0
-    7e96:	71 d0       	rcall	.+226    	; 0x7f7a <putch>
-    7e98:	6d c0       	rjmp	.+218    	; 0x7f74 <main+0x174>
+    7eaa:	80 e0       	ldi	r24, 0x00	; 0
+    7eac:	71 d0       	rcall	.+226    	; 0x7f90 <putch>
+    7eae:	6d c0       	rjmp	.+218    	; 0x7f8a <main+0x18a>
     }
     }
     /* Write memory, length is big endian and is in bytes  */
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     else if(ch == STK_PROG_PAGE) {
-    7e9a:	84 36       	cpi	r24, 0x64	; 100
-    7e9c:	09 f0       	breq	.+2      	; 0x7ea0 <main+0xa0>
-    7e9e:	43 c0       	rjmp	.+134    	; 0x7f26 <main+0x126>
+    7eb0:	84 36       	cpi	r24, 0x64	; 100
+    7eb2:	09 f0       	breq	.+2      	; 0x7eb6 <main+0xb6>
+    7eb4:	43 c0       	rjmp	.+134    	; 0x7f3c <main+0x13c>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint8_t *bufPtr;
       uint16_t addrPtr;
       uint16_t addrPtr;
 
 
       getLen();
       getLen();
-    7ea0:	8f d0       	rcall	.+286    	; 0x7fc0 <getLen>
+    7eb6:	7c d0       	rcall	.+248    	; 0x7fb0 <getLen>
 
 
       // Immediately start page erase - this will 4.5ms
       // Immediately start page erase - this will 4.5ms
       boot_page_erase((uint16_t)(void*)address);
       boot_page_erase((uint16_t)(void*)address);
-    7ea2:	e0 91 00 02 	lds	r30, 0x0200
-    7ea6:	f0 91 01 02 	lds	r31, 0x0201
-    7eaa:	83 e0       	ldi	r24, 0x03	; 3
-    7eac:	80 93 57 00 	sts	0x0057, r24
-    7eb0:	e8 95       	spm
-    7eb2:	c0 e0       	ldi	r28, 0x00	; 0
-    7eb4:	d1 e0       	ldi	r29, 0x01	; 1
+    7eb8:	e0 91 00 02 	lds	r30, 0x0200
+    7ebc:	f0 91 01 02 	lds	r31, 0x0201
+    7ec0:	83 e0       	ldi	r24, 0x03	; 3
+    7ec2:	80 93 57 00 	sts	0x0057, r24
+    7ec6:	e8 95       	spm
+    7ec8:	c0 e0       	ldi	r28, 0x00	; 0
+    7eca:	d1 e0       	ldi	r29, 0x01	; 1
 
 
       // While that is going on, read in page contents
       // While that is going on, read in page contents
       bufPtr = buff;
       bufPtr = buff;
       do *bufPtr++ = getch();
       do *bufPtr++ = getch();
-    7eb6:	70 d0       	rcall	.+224    	; 0x7f98 <getch>
-    7eb8:	89 93       	st	Y+, r24
+    7ecc:	69 d0       	rcall	.+210    	; 0x7fa0 <getch>
+    7ece:	89 93       	st	Y+, r24
       while (--length);
       while (--length);
-    7eba:	80 91 02 02 	lds	r24, 0x0202
-    7ebe:	81 50       	subi	r24, 0x01	; 1
-    7ec0:	80 93 02 02 	sts	0x0202, r24
-    7ec4:	88 23       	and	r24, r24
-    7ec6:	b9 f7       	brne	.-18     	; 0x7eb6 <main+0xb6>
+    7ed0:	80 91 02 02 	lds	r24, 0x0202
+    7ed4:	81 50       	subi	r24, 0x01	; 1
+    7ed6:	80 93 02 02 	sts	0x0202, r24
+    7eda:	88 23       	and	r24, r24
+    7edc:	b9 f7       	brne	.-18     	; 0x7ecc <main+0xcc>
 
 
       // Read command terminator, start reply
       // Read command terminator, start reply
       verifySpace();
       verifySpace();
-    7ec8:	8b d0       	rcall	.+278    	; 0x7fe0 <verifySpace>
+    7ede:	78 d0       	rcall	.+240    	; 0x7fd0 <verifySpace>
       
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       // So check that here
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    7eca:	07 b6       	in	r0, 0x37	; 55
-    7ecc:	00 fc       	sbrc	r0, 0
-    7ece:	fd cf       	rjmp	.-6      	; 0x7eca <main+0xca>
+    7ee0:	07 b6       	in	r0, 0x37	; 55
+    7ee2:	00 fc       	sbrc	r0, 0
+    7ee4:	fd cf       	rjmp	.-6      	; 0x7ee0 <main+0xe0>
+      }
+#endif
 
 
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       addrPtr = (uint16_t)(void*)address;
-    7ed0:	40 91 00 02 	lds	r20, 0x0200
-    7ed4:	50 91 01 02 	lds	r21, 0x0201
-    7ed8:	a0 e0       	ldi	r26, 0x00	; 0
-    7eda:	b1 e0       	ldi	r27, 0x01	; 1
+    7ee6:	40 91 00 02 	lds	r20, 0x0200
+    7eea:	50 91 01 02 	lds	r21, 0x0201
+    7eee:	a0 e0       	ldi	r26, 0x00	; 0
+    7ef0:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
-    7edc:	2c 91       	ld	r18, X
-    7ede:	30 e0       	ldi	r19, 0x00	; 0
+    7ef2:	2c 91       	ld	r18, X
+    7ef4:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
-    7ee0:	11 96       	adiw	r26, 0x01	; 1
-    7ee2:	8c 91       	ld	r24, X
-    7ee4:	11 97       	sbiw	r26, 0x01	; 1
-    7ee6:	90 e0       	ldi	r25, 0x00	; 0
-    7ee8:	98 2f       	mov	r25, r24
-    7eea:	88 27       	eor	r24, r24
-    7eec:	82 2b       	or	r24, r18
-    7eee:	93 2b       	or	r25, r19
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+    7ef6:	11 96       	adiw	r26, 0x01	; 1
+    7ef8:	8c 91       	ld	r24, X
+    7efa:	11 97       	sbiw	r26, 0x01	; 1
+    7efc:	90 e0       	ldi	r25, 0x00	; 0
+    7efe:	98 2f       	mov	r25, r24
+    7f00:	88 27       	eor	r24, r24
+    7f02:	82 2b       	or	r24, r18
+    7f04:	93 2b       	or	r25, r19
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
-    7ef0:	12 96       	adiw	r26, 0x02	; 2
+    7f06:	12 96       	adiw	r26, 0x02	; 2
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
-    7ef2:	fa 01       	movw	r30, r20
-    7ef4:	0c 01       	movw	r0, r24
-    7ef6:	d0 92 57 00 	sts	0x0057, r13
-    7efa:	e8 95       	spm
-    7efc:	11 24       	eor	r1, r1
+    7f08:	fa 01       	movw	r30, r20
+    7f0a:	0c 01       	movw	r0, r24
+    7f0c:	d0 92 57 00 	sts	0x0057, r13
+    7f10:	e8 95       	spm
+    7f12:	11 24       	eor	r1, r1
         addrPtr += 2;
         addrPtr += 2;
-    7efe:	4e 5f       	subi	r20, 0xFE	; 254
-    7f00:	5f 4f       	sbci	r21, 0xFF	; 255
+    7f14:	4e 5f       	subi	r20, 0xFE	; 254
+    7f16:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
       } while (--ch);
-    7f02:	f1 e0       	ldi	r31, 0x01	; 1
-    7f04:	a0 38       	cpi	r26, 0x80	; 128
-    7f06:	bf 07       	cpc	r27, r31
-    7f08:	49 f7       	brne	.-46     	; 0x7edc <main+0xdc>
+    7f18:	f1 e0       	ldi	r31, 0x01	; 1
+    7f1a:	a0 38       	cpi	r26, 0x80	; 128
+    7f1c:	bf 07       	cpc	r27, r31
+    7f1e:	49 f7       	brne	.-46     	; 0x7ef2 <main+0xf2>
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    7f0a:	e0 91 00 02 	lds	r30, 0x0200
-    7f0e:	f0 91 01 02 	lds	r31, 0x0201
-    7f12:	e0 92 57 00 	sts	0x0057, r14
-    7f16:	e8 95       	spm
+    7f20:	e0 91 00 02 	lds	r30, 0x0200
+    7f24:	f0 91 01 02 	lds	r31, 0x0201
+    7f28:	e0 92 57 00 	sts	0x0057, r14
+    7f2c:	e8 95       	spm
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    7f18:	07 b6       	in	r0, 0x37	; 55
-    7f1a:	00 fc       	sbrc	r0, 0
-    7f1c:	fd cf       	rjmp	.-6      	; 0x7f18 <main+0x118>
+    7f2e:	07 b6       	in	r0, 0x37	; 55
+    7f30:	00 fc       	sbrc	r0, 0
+    7f32:	fd cf       	rjmp	.-6      	; 0x7f2e <main+0x12e>
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    7f1e:	f0 92 57 00 	sts	0x0057, r15
-    7f22:	e8 95       	spm
-    7f24:	27 c0       	rjmp	.+78     	; 0x7f74 <main+0x174>
+    7f34:	f0 92 57 00 	sts	0x0057, r15
+    7f38:	e8 95       	spm
+    7f3a:	27 c0       	rjmp	.+78     	; 0x7f8a <main+0x18a>
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
-    7f26:	84 37       	cpi	r24, 0x74	; 116
-    7f28:	b9 f4       	brne	.+46     	; 0x7f58 <main+0x158>
+    7f3c:	84 37       	cpi	r24, 0x74	; 116
+    7f3e:	b9 f4       	brne	.+46     	; 0x7f6e <main+0x16e>
       // READ PAGE - we only read flash
       // READ PAGE - we only read flash
       getLen();
       getLen();
-    7f2a:	4a d0       	rcall	.+148    	; 0x7fc0 <getLen>
+    7f40:	37 d0       	rcall	.+110    	; 0x7fb0 <getLen>
       verifySpace();
       verifySpace();
-    7f2c:	59 d0       	rcall	.+178    	; 0x7fe0 <verifySpace>
+    7f42:	46 d0       	rcall	.+140    	; 0x7fd0 <verifySpace>
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
-    7f2e:	e0 91 00 02 	lds	r30, 0x0200
-    7f32:	f0 91 01 02 	lds	r31, 0x0201
-    7f36:	31 96       	adiw	r30, 0x01	; 1
-    7f38:	f0 93 01 02 	sts	0x0201, r31
-    7f3c:	e0 93 00 02 	sts	0x0200, r30
-    7f40:	31 97       	sbiw	r30, 0x01	; 1
-    7f42:	e4 91       	lpm	r30, Z+
-    7f44:	8e 2f       	mov	r24, r30
-    7f46:	19 d0       	rcall	.+50     	; 0x7f7a <putch>
+    7f44:	e0 91 00 02 	lds	r30, 0x0200
+    7f48:	f0 91 01 02 	lds	r31, 0x0201
+    7f4c:	31 96       	adiw	r30, 0x01	; 1
+    7f4e:	f0 93 01 02 	sts	0x0201, r31
+    7f52:	e0 93 00 02 	sts	0x0200, r30
+    7f56:	31 97       	sbiw	r30, 0x01	; 1
+    7f58:	e4 91       	lpm	r30, Z+
+    7f5a:	8e 2f       	mov	r24, r30
+    7f5c:	19 d0       	rcall	.+50     	; 0x7f90 <putch>
       while (--length);
       while (--length);
-    7f48:	80 91 02 02 	lds	r24, 0x0202
-    7f4c:	81 50       	subi	r24, 0x01	; 1
-    7f4e:	80 93 02 02 	sts	0x0202, r24
-    7f52:	88 23       	and	r24, r24
-    7f54:	61 f7       	brne	.-40     	; 0x7f2e <main+0x12e>
-    7f56:	0e c0       	rjmp	.+28     	; 0x7f74 <main+0x174>
+    7f5e:	80 91 02 02 	lds	r24, 0x0202
+    7f62:	81 50       	subi	r24, 0x01	; 1
+    7f64:	80 93 02 02 	sts	0x0202, r24
+    7f68:	88 23       	and	r24, r24
+    7f6a:	61 f7       	brne	.-40     	; 0x7f44 <main+0x144>
+    7f6c:	0e c0       	rjmp	.+28     	; 0x7f8a <main+0x18a>
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
     else if(ch == STK_READ_SIGN) {
-    7f58:	85 37       	cpi	r24, 0x75	; 117
-    7f5a:	39 f4       	brne	.+14     	; 0x7f6a <main+0x16a>
+    7f6e:	85 37       	cpi	r24, 0x75	; 117
+    7f70:	39 f4       	brne	.+14     	; 0x7f80 <main+0x180>
       // READ SIGN - return what Avrdude wants to hear
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
       verifySpace();
-    7f5c:	41 d0       	rcall	.+130    	; 0x7fe0 <verifySpace>
+    7f72:	2e d0       	rcall	.+92     	; 0x7fd0 <verifySpace>
       putch(SIGNATURE_0);
       putch(SIGNATURE_0);
-    7f5e:	8e e1       	ldi	r24, 0x1E	; 30
-    7f60:	0c d0       	rcall	.+24     	; 0x7f7a <putch>
+    7f74:	8e e1       	ldi	r24, 0x1E	; 30
+    7f76:	0c d0       	rcall	.+24     	; 0x7f90 <putch>
       putch(SIGNATURE_1);
       putch(SIGNATURE_1);
-    7f62:	85 e9       	ldi	r24, 0x95	; 149
-    7f64:	0a d0       	rcall	.+20     	; 0x7f7a <putch>
+    7f78:	85 e9       	ldi	r24, 0x95	; 149
+    7f7a:	0a d0       	rcall	.+20     	; 0x7f90 <putch>
       putch(SIGNATURE_2);
       putch(SIGNATURE_2);
-    7f66:	8f e0       	ldi	r24, 0x0F	; 15
-    7f68:	96 cf       	rjmp	.-212    	; 0x7e96 <main+0x96>
+    7f7c:	8f e0       	ldi	r24, 0x0F	; 15
+    7f7e:	96 cf       	rjmp	.-212    	; 0x7eac <main+0xac>
     }
     }
     else if (ch == 'Q') {
     else if (ch == 'Q') {
-    7f6a:	81 35       	cpi	r24, 0x51	; 81
-    7f6c:	11 f4       	brne	.+4      	; 0x7f72 <main+0x172>
+    7f80:	81 35       	cpi	r24, 0x51	; 81
+    7f82:	11 f4       	brne	.+4      	; 0x7f88 <main+0x188>
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
-    7f6e:	88 e0       	ldi	r24, 0x08	; 8
-    7f70:	2c d0       	rcall	.+88     	; 0x7fca <watchdogConfig>
+      watchdogConfig(WATCHDOG_16MS);
+    7f84:	88 e0       	ldi	r24, 0x08	; 8
+    7f86:	19 d0       	rcall	.+50     	; 0x7fba <watchdogConfig>
       verifySpace();
       verifySpace();
     }
     }
     else {
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
       verifySpace();
-    7f72:	36 d0       	rcall	.+108    	; 0x7fe0 <verifySpace>
+    7f88:	23 d0       	rcall	.+70     	; 0x7fd0 <verifySpace>
     }
     }
     putch(STK_OK);
     putch(STK_OK);
-    7f74:	80 e1       	ldi	r24, 0x10	; 16
-    7f76:	01 d0       	rcall	.+2      	; 0x7f7a <putch>
-    7f78:	63 cf       	rjmp	.-314    	; 0x7e40 <main+0x40>
+    7f8a:	80 e1       	ldi	r24, 0x10	; 16
+    7f8c:	01 d0       	rcall	.+2      	; 0x7f90 <putch>
+    7f8e:	63 cf       	rjmp	.-314    	; 0x7e56 <main+0x56>
+
+00007f90 <putch>:
+  }
+}
 
 
-00007f7a <putch>:
 void putch(char ch) {
 void putch(char ch) {
+    7f90:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
   while (!(UCSR0A & _BV(UDRE0)));
+    7f92:	80 91 c0 00 	lds	r24, 0x00C0
+    7f96:	85 ff       	sbrs	r24, 5
+    7f98:	fc cf       	rjmp	.-8      	; 0x7f92 <putch+0x2>
   UDR0 = ch;
   UDR0 = ch;
-#else
-  __asm__ __volatile__ (
-    7f7a:	2a e0       	ldi	r18, 0x0A	; 10
-    7f7c:	30 e0       	ldi	r19, 0x00	; 0
-    7f7e:	80 95       	com	r24
-    7f80:	08 94       	sec
-    7f82:	10 f4       	brcc	.+4      	; 0x7f88 <putch+0xe>
-    7f84:	59 98       	cbi	0x0b, 1	; 11
-    7f86:	02 c0       	rjmp	.+4      	; 0x7f8c <putch+0x12>
-    7f88:	59 9a       	sbi	0x0b, 1	; 11
-    7f8a:	00 00       	nop
-    7f8c:	15 d0       	rcall	.+42     	; 0x7fb8 <uartDelay>
-    7f8e:	14 d0       	rcall	.+40     	; 0x7fb8 <uartDelay>
-    7f90:	86 95       	lsr	r24
-    7f92:	2a 95       	dec	r18
-    7f94:	b1 f7       	brne	.-20     	; 0x7f82 <putch+0x8>
+    7f9a:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
       [uartBit] "I" (UART_TX_BIT)
     :
     :
       "r25"
       "r25"
   );
   );
 #endif
 #endif
 }
 }
-    7f96:	08 95       	ret
+    7f9e:	08 95       	ret
 
 
-00007f98 <getch>:
+00007fa0 <getch>:
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    7f98:	a8 95       	wdr
+    7fa0:	a8 95       	wdr
+      [uartBit] "I" (UART_RX_BIT)
+    :
+      "r25"
+);
+#else
+  while(!(UCSR0A & _BV(RXC0)));
+    7fa2:	80 91 c0 00 	lds	r24, 0x00C0
+    7fa6:	87 ff       	sbrs	r24, 7
+    7fa8:	fc cf       	rjmp	.-8      	; 0x7fa2 <getch+0x2>
+  ch = UDR0;
+    7faa:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
 
   return ch;
   return ch;
 }
 }
-    7f9a:	29 e0       	ldi	r18, 0x09	; 9
-    7f9c:	30 e0       	ldi	r19, 0x00	; 0
-    7f9e:	48 99       	sbic	0x09, 0	; 9
-    7fa0:	fe cf       	rjmp	.-4      	; 0x7f9e <getch+0x6>
-    7fa2:	0a d0       	rcall	.+20     	; 0x7fb8 <uartDelay>
-    7fa4:	09 d0       	rcall	.+18     	; 0x7fb8 <uartDelay>
-    7fa6:	08 d0       	rcall	.+16     	; 0x7fb8 <uartDelay>
-    7fa8:	88 94       	clc
-    7faa:	48 99       	sbic	0x09, 0	; 9
-    7fac:	08 94       	sec
-    7fae:	2a 95       	dec	r18
-    7fb0:	11 f0       	breq	.+4      	; 0x7fb6 <getch+0x1e>
-    7fb2:	87 95       	ror	r24
-    7fb4:	f7 cf       	rjmp	.-18     	; 0x7fa4 <getch+0xc>
-    7fb6:	08 95       	ret
-
-00007fb8 <uartDelay>:
-#if UART_B_VALUE > 255
-#error Baud rate too slow for soft UART
-#endif
-
-void uartDelay() {
-  __asm__ __volatile__ (
-    7fb8:	98 e0       	ldi	r25, 0x08	; 8
-    7fba:	9a 95       	dec	r25
-    7fbc:	f1 f7       	brne	.-4      	; 0x7fba <uartDelay+0x2>
-    7fbe:	08 95       	ret
+    7fae:	08 95       	ret
 
 
-00007fc0 <getLen>:
+00007fb0 <getLen>:
   } while (--count);
   } while (--count);
 }
 }
 #endif
 #endif
 
 
 uint8_t getLen() {
 uint8_t getLen() {
   getch();
   getch();
-    7fc0:	eb df       	rcall	.-42     	; 0x7f98 <getch>
+    7fb0:	f7 df       	rcall	.-18     	; 0x7fa0 <getch>
   length = getch();
   length = getch();
-    7fc2:	ea df       	rcall	.-44     	; 0x7f98 <getch>
-    7fc4:	80 93 02 02 	sts	0x0202, r24
+    7fb2:	f6 df       	rcall	.-20     	; 0x7fa0 <getch>
+    7fb4:	80 93 02 02 	sts	0x0202, r24
   return getch();
   return getch();
 }
 }
-    7fc8:	e7 cf       	rjmp	.-50     	; 0x7f98 <getch>
+    7fb8:	f3 cf       	rjmp	.-26     	; 0x7fa0 <getch>
 
 
-00007fca <watchdogConfig>:
+00007fba <watchdogConfig>:
     "wdr\n"
     "wdr\n"
   );
   );
 }
 }
 
 
 void watchdogConfig(uint8_t x) {
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    7fca:	e0 e6       	ldi	r30, 0x60	; 96
-    7fcc:	f0 e0       	ldi	r31, 0x00	; 0
-    7fce:	98 e1       	ldi	r25, 0x18	; 24
-    7fd0:	90 83       	st	Z, r25
+    7fba:	e0 e6       	ldi	r30, 0x60	; 96
+    7fbc:	f0 e0       	ldi	r31, 0x00	; 0
+    7fbe:	98 e1       	ldi	r25, 0x18	; 24
+    7fc0:	90 83       	st	Z, r25
   WDTCSR = x;
   WDTCSR = x;
-    7fd2:	80 83       	st	Z, r24
+    7fc2:	80 83       	st	Z, r24
 }
 }
-    7fd4:	08 95       	ret
+    7fc4:	08 95       	ret
 
 
-00007fd6 <appStart>:
+00007fc6 <appStart>:
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
-    7fd6:	80 e0       	ldi	r24, 0x00	; 0
-    7fd8:	f8 df       	rcall	.-16     	; 0x7fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_OFF);
+    7fc6:	80 e0       	ldi	r24, 0x00	; 0
+    7fc8:	f8 df       	rcall	.-16     	; 0x7fba <watchdogConfig>
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    7fda:	ee 27       	eor	r30, r30
-    7fdc:	ff 27       	eor	r31, r31
-    7fde:	09 94       	ijmp
+    7fca:	ee 27       	eor	r30, r30
+    7fcc:	ff 27       	eor	r31, r31
+    7fce:	09 94       	ijmp
 
 
-00007fe0 <verifySpace>:
+00007fd0 <verifySpace>:
   do getch(); while (--count);
   do getch(); while (--count);
   verifySpace();
   verifySpace();
 }
 }
 
 
 void verifySpace() {
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
   if (getch() != CRC_EOP) appStart();
-    7fe0:	db df       	rcall	.-74     	; 0x7f98 <getch>
-    7fe2:	80 32       	cpi	r24, 0x20	; 32
-    7fe4:	09 f0       	breq	.+2      	; 0x7fe8 <verifySpace+0x8>
-    7fe6:	f7 df       	rcall	.-18     	; 0x7fd6 <appStart>
+    7fd0:	e7 df       	rcall	.-50     	; 0x7fa0 <getch>
+    7fd2:	80 32       	cpi	r24, 0x20	; 32
+    7fd4:	09 f0       	breq	.+2      	; 0x7fd8 <verifySpace+0x8>
+    7fd6:	f7 df       	rcall	.-18     	; 0x7fc6 <appStart>
   putch(STK_INSYNC);
   putch(STK_INSYNC);
-    7fe8:	84 e1       	ldi	r24, 0x14	; 20
+    7fd8:	84 e1       	ldi	r24, 0x14	; 20
 }
 }
-    7fea:	c7 cf       	rjmp	.-114    	; 0x7f7a <putch>
+    7fda:	da cf       	rjmp	.-76     	; 0x7f90 <putch>
     ::[count] "M" (UART_B_VALUE)
     ::[count] "M" (UART_B_VALUE)
   );
   );
 }
 }
 #endif
 #endif
 
 
 void getNch(uint8_t count) {
 void getNch(uint8_t count) {
-    7fec:	1f 93       	push	r17
-    7fee:	18 2f       	mov	r17, r24
+    7fdc:	1f 93       	push	r17
+    7fde:	18 2f       	mov	r17, r24
 
 
-00007ff0 <getNch>:
+00007fe0 <getNch>:
   do getch(); while (--count);
   do getch(); while (--count);
-    7ff0:	d3 df       	rcall	.-90     	; 0x7f98 <getch>
-    7ff2:	11 50       	subi	r17, 0x01	; 1
-    7ff4:	e9 f7       	brne	.-6      	; 0x7ff0 <getNch>
+    7fe0:	df df       	rcall	.-66     	; 0x7fa0 <getch>
+    7fe2:	11 50       	subi	r17, 0x01	; 1
+    7fe4:	e9 f7       	brne	.-6      	; 0x7fe0 <getNch>
   verifySpace();
   verifySpace();
-    7ff6:	f4 df       	rcall	.-24     	; 0x7fe0 <verifySpace>
+    7fe6:	f4 df       	rcall	.-24     	; 0x7fd0 <verifySpace>
 }
 }
-    7ff8:	1f 91       	pop	r17
-    7ffa:	08 95       	ret
+    7fe8:	1f 91       	pop	r17
+    7fea:	08 95       	ret

+ 31 - 32
optiboot/bootloaders/optiboot/optiboot_diecimila.hex

@@ -1,34 +1,33 @@
-:103E000085E08093810084B714BE81FFE4D08DE00B
-:103E1000DCD0259A519A86E020E33CEF91E0309384
-:103E200085002093840096BBB09BFECF1D9AA89579
-:103E30008150A9F7DD24D394A5E0EA2EF1E1FF2E0D
-:103E4000ABD0813421F481E0D1D083E024C082342E
-:103E500011F484E103C0853419F485E0C7D08AC029
-:103E60008535A1F499D0082F10E01093010200933A
-:103E7000000292D090E0982F8827802B912B880FFA
-:103E8000991F909301028093000273C0863529F434
-:103E900084E0ACD080E071D06DC0843609F043C0BE
-:103EA0008FD0E0910002F091010283E080935700EF
-:103EB000E895C0E0D1E070D08993809102028150F2
-:103EC000809302028823B9F78BD007B600FCFDCFA0
-:103ED0004091000250910102A0E0B1E02C9130E04D
-:103EE00011968C91119790E0982F8827822B932B15
-:103EF0001296FA010C01D0925700E89511244E5FFA
-:103F00005F4FF1E0A038BF0749F7E0910002F09160
-:103F10000102E0925700E89507B600FCFDCFF09251
-:103F20005700E89527C08437B9F44AD059D0E091BA
-:103F30000002F09101023196F0930102E093000239
-:103F40003197E4918E2F19D0809102028150809395
-:103F50000202882361F70EC0853739F441D08EE123
-:103F60000CD084E90AD086E096CF813511F488E040
-:103F70002CD036D080E101D063CF2AE030E08095AC
-:103F8000089410F4599802C0599A000015D014D022
-:103F900086952A95B1F70895A89529E030E04899CB
-:103FA000FECF0AD009D008D08894489908942A9561
-:103FB00011F08795F7CF089598E09A95F1F7089555
-:103FC000EBDFEADF80930202E7CFE0E6F0E098E182
-:103FD00090838083089580E0F8DFEE27FF2709941F
-:103FE000DBDF803209F0F7DF84E1C7CF1F93182FA2
-:0C3FF000D3DF1150E9F7F4DF1F910895B2
+:103E000085E08093810082E08093C00088E1809308
+:103E1000C10086E08093C20080E18093C40084B733
+:103E200014BE81FFD0D08DE0C8D0259A86E020E373
+:103E30003CEF91E0309385002093840096BBB09BCB
+:103E4000FECF1D9AA8958150A9F7DD24D394A5E053
+:103E5000EA2EF1E1FF2EA4D0813421F481E0BED01E
+:103E600083E024C0823411F484E103C0853419F462
+:103E700085E0B4D08AC08535A1F492D0082F10E037
+:103E800010930102009300028BD090E0982F8827B6
+:103E9000802B912B880F991F909301028093000231
+:103EA00073C0863529F484E099D080E071D06DC06C
+:103EB000843609F043C07CD0E0910002F091010209
+:103EC00083E080935700E895C0E0D1E069D0899302
+:103ED000809102028150809302028823B9F778D042
+:103EE00007B600FCFDCF4091000250910102A0E016
+:103EF000B1E02C9130E011968C91119790E0982FC1
+:103F00008827822B932B1296FA010C01D09257002E
+:103F1000E89511244E5F5F4FF1E0A038BF0749F7E5
+:103F2000E0910002F0910102E0925700E89507B697
+:103F300000FCFDCFF0925700E89527C08437B9F414
+:103F400037D046D0E0910002F09101023196F09313
+:103F50000102E09300023197E4918E2F19D08091F5
+:103F60000202815080930202882361F70EC08537D8
+:103F700039F42ED08EE10CD084E90AD086E096CFB9
+:103F8000813511F488E019D023D080E101D063CFCE
+:103F9000982F8091C00085FFFCCF9093C6000895B4
+:103FA000A8958091C00087FFFCCF8091C60008953E
+:103FB000F7DFF6DF80930202F3CFE0E6F0E098E16E
+:103FC00090838083089580E0F8DFEE27FF2709942F
+:103FD000E7DF803209F0F7DF84E1DACF1F93182F93
+:0C3FE000DFDF1150E9F7F4DF1F910895B6
 :0400000300003E00BB
 :0400000300003E00BB
 :00000001FF
 :00000001FF

+ 267 - 268
optiboot/bootloaders/optiboot/optiboot_diecimila.lst

@@ -3,519 +3,518 @@ optiboot_diecimila.elf:     file format elf32-avr
 
 
 Sections:
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001fc  00003e00  00003e00  00000054  2**1
+  0 .text         000001ec  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000250  2**0
+  1 .debug_aranges 00000028  00000000  00000000  00000240  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000268  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000275  00000000  00000000  000002f0  2**0
+  3 .debug_info   00000269  00000000  00000000  000002d2  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a3  00000000  00000000  00000565  2**0
+  4 .debug_abbrev 00000196  00000000  00000000  0000053b  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003b8  00000000  00000000  00000708  2**0
+  5 .debug_line   000003d3  00000000  00000000  000006d1  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  000000a0  00000000  00000000  00000ac0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000aa4  2**2
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000133  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000135  00000000  00000000  00000b34  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001a0  00000000  00000000  00000c93  2**0
+  8 .debug_loc    000001d1  00000000  00000000  00000c69  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000070  00000000  00000000  00000e33  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000e3a  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
 
 
 Disassembly of section .text:
 Disassembly of section .text:
 
 
 00003e00 <main>:
 00003e00 <main>:
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e02:	80 93 81 00 	sts	0x0081, r24
     3e02:	80 93 81 00 	sts	0x0081, r24
+#if LED_START_FLASHES > 0
+  // Set up Timer 1 for timeout counter
+  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+#endif
+#ifndef SOFT_UART
+  UCSR0A = _BV(U2X0); //Double speed mode USART0
+    3e06:	82 e0       	ldi	r24, 0x02	; 2
+    3e08:	80 93 c0 00 	sts	0x00C0, r24
+  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+    3e0c:	88 e1       	ldi	r24, 0x18	; 24
+    3e0e:	80 93 c1 00 	sts	0x00C1, r24
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+    3e12:	86 e0       	ldi	r24, 0x06	; 6
+    3e14:	80 93 c2 00 	sts	0x00C2, r24
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+    3e18:	80 e1       	ldi	r24, 0x10	; 16
+    3e1a:	80 93 c4 00 	sts	0x00C4, r24
 #endif
 #endif
 
 
   // Adaboot no-wait mod
   // Adaboot no-wait mod
   ch = MCUSR;
   ch = MCUSR;
-    3e06:	84 b7       	in	r24, 0x34	; 52
+    3e1e:	84 b7       	in	r24, 0x34	; 52
   MCUSR = 0;
   MCUSR = 0;
-    3e08:	14 be       	out	0x34, r1	; 52
+    3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
   if (!(ch & _BV(EXTRF))) appStart();
-    3e0a:	81 ff       	sbrs	r24, 1
-    3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
+    3e22:	81 ff       	sbrs	r24, 1
+    3e24:	d0 d0       	rcall	.+416    	; 0x3fc6 <appStart>
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
-    3e0e:	8d e0       	ldi	r24, 0x0D	; 13
-    3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_500MS);
+    3e26:	8d e0       	ldi	r24, 0x0D	; 13
+    3e28:	c8 d0       	rcall	.+400    	; 0x3fba <watchdogConfig>
 
 
   /* Set LED pin as output */
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
   LED_DDR |= _BV(LED);
-    3e12:	25 9a       	sbi	0x04, 5	; 4
-
-#ifdef SOFT_UART
-  /* Set TX pin as output */
-  UART_DDR |= _BV(UART_TX_BIT);
-    3e14:	51 9a       	sbi	0x0a, 1	; 10
-    3e16:	86 e0       	ldi	r24, 0x06	; 6
+    3e2a:	25 9a       	sbi	0x04, 5	; 4
+    3e2c:	86 e0       	ldi	r24, 0x06	; 6
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    3e18:	20 e3       	ldi	r18, 0x30	; 48
-    3e1a:	3c ef       	ldi	r19, 0xFC	; 252
+    3e2e:	20 e3       	ldi	r18, 0x30	; 48
+    3e30:	3c ef       	ldi	r19, 0xFC	; 252
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    3e1c:	91 e0       	ldi	r25, 0x01	; 1
+    3e32:	91 e0       	ldi	r25, 0x01	; 1
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    3e1e:	30 93 85 00 	sts	0x0085, r19
-    3e22:	20 93 84 00 	sts	0x0084, r18
+    3e34:	30 93 85 00 	sts	0x0085, r19
+    3e38:	20 93 84 00 	sts	0x0084, r18
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    3e26:	96 bb       	out	0x16, r25	; 22
+    3e3c:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
-    3e28:	b0 9b       	sbis	0x16, 0	; 22
-    3e2a:	fe cf       	rjmp	.-4      	; 0x3e28 <main+0x28>
+    3e3e:	b0 9b       	sbis	0x16, 0	; 22
+    3e40:	fe cf       	rjmp	.-4      	; 0x3e3e <main+0x3e>
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
-    3e2c:	1d 9a       	sbi	0x03, 5	; 3
+    3e42:	1d 9a       	sbi	0x03, 5	; 3
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3e2e:	a8 95       	wdr
+    3e44:	a8 95       	wdr
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
     watchdogReset();
     watchdogReset();
   } while (--count);
   } while (--count);
-    3e30:	81 50       	subi	r24, 0x01	; 1
-    3e32:	a9 f7       	brne	.-22     	; 0x3e1e <main+0x1e>
+    3e46:	81 50       	subi	r24, 0x01	; 1
+    3e48:	a9 f7       	brne	.-22     	; 0x3e34 <main+0x34>
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    3e34:	dd 24       	eor	r13, r13
-    3e36:	d3 94       	inc	r13
+    3e4a:	dd 24       	eor	r13, r13
+    3e4c:	d3 94       	inc	r13
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         addrPtr += 2;
         addrPtr += 2;
       } while (--ch);
       } while (--ch);
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    3e38:	a5 e0       	ldi	r26, 0x05	; 5
-    3e3a:	ea 2e       	mov	r14, r26
+    3e4e:	a5 e0       	ldi	r26, 0x05	; 5
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    3e3c:	f1 e1       	ldi	r31, 0x11	; 17
-    3e3e:	ff 2e       	mov	r15, r31
+    3e52:	f1 e1       	ldi	r31, 0x11	; 17
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 #endif
 
 
   /* Forever loop */
   /* Forever loop */
   for (;;) {
   for (;;) {
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
-    3e40:	ab d0       	rcall	.+342    	; 0x3f98 <getch>
+    3e56:	a4 d0       	rcall	.+328    	; 0x3fa0 <getch>
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
-    3e42:	81 34       	cpi	r24, 0x41	; 65
-    3e44:	21 f4       	brne	.+8      	; 0x3e4e <main+0x4e>
+    3e58:	81 34       	cpi	r24, 0x41	; 65
+    3e5a:	21 f4       	brne	.+8      	; 0x3e64 <main+0x64>
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    3e46:	81 e0       	ldi	r24, 0x01	; 1
-    3e48:	d1 d0       	rcall	.+418    	; 0x3fec <verifySpace+0xc>
+    3e5c:	81 e0       	ldi	r24, 0x01	; 1
+    3e5e:	be d0       	rcall	.+380    	; 0x3fdc <verifySpace+0xc>
       putch(0x03);
       putch(0x03);
-    3e4a:	83 e0       	ldi	r24, 0x03	; 3
-    3e4c:	24 c0       	rjmp	.+72     	; 0x3e96 <main+0x96>
+    3e60:	83 e0       	ldi	r24, 0x03	; 3
+    3e62:	24 c0       	rjmp	.+72     	; 0x3eac <main+0xac>
     }
     }
     else if(ch == STK_SET_DEVICE) {
     else if(ch == STK_SET_DEVICE) {
-    3e4e:	82 34       	cpi	r24, 0x42	; 66
-    3e50:	11 f4       	brne	.+4      	; 0x3e56 <main+0x56>
+    3e64:	82 34       	cpi	r24, 0x42	; 66
+    3e66:	11 f4       	brne	.+4      	; 0x3e6c <main+0x6c>
       // SET DEVICE is ignored
       // SET DEVICE is ignored
       getNch(20);
       getNch(20);
-    3e52:	84 e1       	ldi	r24, 0x14	; 20
-    3e54:	03 c0       	rjmp	.+6      	; 0x3e5c <main+0x5c>
+    3e68:	84 e1       	ldi	r24, 0x14	; 20
+    3e6a:	03 c0       	rjmp	.+6      	; 0x3e72 <main+0x72>
     }
     }
     else if(ch == STK_SET_DEVICE_EXT) {
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e56:	85 34       	cpi	r24, 0x45	; 69
-    3e58:	19 f4       	brne	.+6      	; 0x3e60 <main+0x60>
+    3e6c:	85 34       	cpi	r24, 0x45	; 69
+    3e6e:	19 f4       	brne	.+6      	; 0x3e76 <main+0x76>
       // SET DEVICE EXT is ignored
       // SET DEVICE EXT is ignored
       getNch(5);
       getNch(5);
-    3e5a:	85 e0       	ldi	r24, 0x05	; 5
-    3e5c:	c7 d0       	rcall	.+398    	; 0x3fec <verifySpace+0xc>
-    3e5e:	8a c0       	rjmp	.+276    	; 0x3f74 <main+0x174>
+    3e70:	85 e0       	ldi	r24, 0x05	; 5
+    3e72:	b4 d0       	rcall	.+360    	; 0x3fdc <verifySpace+0xc>
+    3e74:	8a c0       	rjmp	.+276    	; 0x3f8a <main+0x18a>
     }
     }
     else if(ch == STK_LOAD_ADDRESS) {
     else if(ch == STK_LOAD_ADDRESS) {
-    3e60:	85 35       	cpi	r24, 0x55	; 85
-    3e62:	a1 f4       	brne	.+40     	; 0x3e8c <main+0x8c>
+    3e76:	85 35       	cpi	r24, 0x55	; 85
+    3e78:	a1 f4       	brne	.+40     	; 0x3ea2 <main+0xa2>
       // LOAD ADDRESS
       // LOAD ADDRESS
       address = getch();
       address = getch();
-    3e64:	99 d0       	rcall	.+306    	; 0x3f98 <getch>
-    3e66:	08 2f       	mov	r16, r24
-    3e68:	10 e0       	ldi	r17, 0x00	; 0
-    3e6a:	10 93 01 02 	sts	0x0201, r17
-    3e6e:	00 93 00 02 	sts	0x0200, r16
+    3e7a:	92 d0       	rcall	.+292    	; 0x3fa0 <getch>
+    3e7c:	08 2f       	mov	r16, r24
+    3e7e:	10 e0       	ldi	r17, 0x00	; 0
+    3e80:	10 93 01 02 	sts	0x0201, r17
+    3e84:	00 93 00 02 	sts	0x0200, r16
       address = (address & 0xff) | (getch() << 8);
       address = (address & 0xff) | (getch() << 8);
-    3e72:	92 d0       	rcall	.+292    	; 0x3f98 <getch>
-    3e74:	90 e0       	ldi	r25, 0x00	; 0
-    3e76:	98 2f       	mov	r25, r24
-    3e78:	88 27       	eor	r24, r24
-    3e7a:	80 2b       	or	r24, r16
-    3e7c:	91 2b       	or	r25, r17
+    3e88:	8b d0       	rcall	.+278    	; 0x3fa0 <getch>
+    3e8a:	90 e0       	ldi	r25, 0x00	; 0
+    3e8c:	98 2f       	mov	r25, r24
+    3e8e:	88 27       	eor	r24, r24
+    3e90:	80 2b       	or	r24, r16
+    3e92:	91 2b       	or	r25, r17
       address += address; // Convert from word address to byte address
       address += address; // Convert from word address to byte address
-    3e7e:	88 0f       	add	r24, r24
-    3e80:	99 1f       	adc	r25, r25
-    3e82:	90 93 01 02 	sts	0x0201, r25
-    3e86:	80 93 00 02 	sts	0x0200, r24
-    3e8a:	73 c0       	rjmp	.+230    	; 0x3f72 <main+0x172>
+    3e94:	88 0f       	add	r24, r24
+    3e96:	99 1f       	adc	r25, r25
+    3e98:	90 93 01 02 	sts	0x0201, r25
+    3e9c:	80 93 00 02 	sts	0x0200, r24
+    3ea0:	73 c0       	rjmp	.+230    	; 0x3f88 <main+0x188>
       verifySpace();
       verifySpace();
     }
     }
     else if(ch == STK_UNIVERSAL) {
     else if(ch == STK_UNIVERSAL) {
-    3e8c:	86 35       	cpi	r24, 0x56	; 86
-    3e8e:	29 f4       	brne	.+10     	; 0x3e9a <main+0x9a>
+    3ea2:	86 35       	cpi	r24, 0x56	; 86
+    3ea4:	29 f4       	brne	.+10     	; 0x3eb0 <main+0xb0>
       // UNIVERSAL command is ignored
       // UNIVERSAL command is ignored
       getNch(4);
       getNch(4);
-    3e90:	84 e0       	ldi	r24, 0x04	; 4
-    3e92:	ac d0       	rcall	.+344    	; 0x3fec <verifySpace+0xc>
+    3ea6:	84 e0       	ldi	r24, 0x04	; 4
+    3ea8:	99 d0       	rcall	.+306    	; 0x3fdc <verifySpace+0xc>
       putch(0x00);
       putch(0x00);
-    3e94:	80 e0       	ldi	r24, 0x00	; 0
-    3e96:	71 d0       	rcall	.+226    	; 0x3f7a <putch>
-    3e98:	6d c0       	rjmp	.+218    	; 0x3f74 <main+0x174>
+    3eaa:	80 e0       	ldi	r24, 0x00	; 0
+    3eac:	71 d0       	rcall	.+226    	; 0x3f90 <putch>
+    3eae:	6d c0       	rjmp	.+218    	; 0x3f8a <main+0x18a>
     }
     }
     /* Write memory, length is big endian and is in bytes  */
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     else if(ch == STK_PROG_PAGE) {
-    3e9a:	84 36       	cpi	r24, 0x64	; 100
-    3e9c:	09 f0       	breq	.+2      	; 0x3ea0 <main+0xa0>
-    3e9e:	43 c0       	rjmp	.+134    	; 0x3f26 <main+0x126>
+    3eb0:	84 36       	cpi	r24, 0x64	; 100
+    3eb2:	09 f0       	breq	.+2      	; 0x3eb6 <main+0xb6>
+    3eb4:	43 c0       	rjmp	.+134    	; 0x3f3c <main+0x13c>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint8_t *bufPtr;
       uint16_t addrPtr;
       uint16_t addrPtr;
 
 
       getLen();
       getLen();
-    3ea0:	8f d0       	rcall	.+286    	; 0x3fc0 <getLen>
+    3eb6:	7c d0       	rcall	.+248    	; 0x3fb0 <getLen>
 
 
       // Immediately start page erase - this will 4.5ms
       // Immediately start page erase - this will 4.5ms
       boot_page_erase((uint16_t)(void*)address);
       boot_page_erase((uint16_t)(void*)address);
-    3ea2:	e0 91 00 02 	lds	r30, 0x0200
-    3ea6:	f0 91 01 02 	lds	r31, 0x0201
-    3eaa:	83 e0       	ldi	r24, 0x03	; 3
-    3eac:	80 93 57 00 	sts	0x0057, r24
-    3eb0:	e8 95       	spm
-    3eb2:	c0 e0       	ldi	r28, 0x00	; 0
-    3eb4:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	e0 91 00 02 	lds	r30, 0x0200
+    3ebc:	f0 91 01 02 	lds	r31, 0x0201
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	80 93 57 00 	sts	0x0057, r24
+    3ec6:	e8 95       	spm
+    3ec8:	c0 e0       	ldi	r28, 0x00	; 0
+    3eca:	d1 e0       	ldi	r29, 0x01	; 1
 
 
       // While that is going on, read in page contents
       // While that is going on, read in page contents
       bufPtr = buff;
       bufPtr = buff;
       do *bufPtr++ = getch();
       do *bufPtr++ = getch();
-    3eb6:	70 d0       	rcall	.+224    	; 0x3f98 <getch>
-    3eb8:	89 93       	st	Y+, r24
+    3ecc:	69 d0       	rcall	.+210    	; 0x3fa0 <getch>
+    3ece:	89 93       	st	Y+, r24
       while (--length);
       while (--length);
-    3eba:	80 91 02 02 	lds	r24, 0x0202
-    3ebe:	81 50       	subi	r24, 0x01	; 1
-    3ec0:	80 93 02 02 	sts	0x0202, r24
-    3ec4:	88 23       	and	r24, r24
-    3ec6:	b9 f7       	brne	.-18     	; 0x3eb6 <main+0xb6>
+    3ed0:	80 91 02 02 	lds	r24, 0x0202
+    3ed4:	81 50       	subi	r24, 0x01	; 1
+    3ed6:	80 93 02 02 	sts	0x0202, r24
+    3eda:	88 23       	and	r24, r24
+    3edc:	b9 f7       	brne	.-18     	; 0x3ecc <main+0xcc>
 
 
       // Read command terminator, start reply
       // Read command terminator, start reply
       verifySpace();
       verifySpace();
-    3ec8:	8b d0       	rcall	.+278    	; 0x3fe0 <verifySpace>
+    3ede:	78 d0       	rcall	.+240    	; 0x3fd0 <verifySpace>
       
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       // So check that here
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    3eca:	07 b6       	in	r0, 0x37	; 55
-    3ecc:	00 fc       	sbrc	r0, 0
-    3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
+    3ee0:	07 b6       	in	r0, 0x37	; 55
+    3ee2:	00 fc       	sbrc	r0, 0
+    3ee4:	fd cf       	rjmp	.-6      	; 0x3ee0 <main+0xe0>
+      }
+#endif
 
 
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       addrPtr = (uint16_t)(void*)address;
-    3ed0:	40 91 00 02 	lds	r20, 0x0200
-    3ed4:	50 91 01 02 	lds	r21, 0x0201
-    3ed8:	a0 e0       	ldi	r26, 0x00	; 0
-    3eda:	b1 e0       	ldi	r27, 0x01	; 1
+    3ee6:	40 91 00 02 	lds	r20, 0x0200
+    3eea:	50 91 01 02 	lds	r21, 0x0201
+    3eee:	a0 e0       	ldi	r26, 0x00	; 0
+    3ef0:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
-    3edc:	2c 91       	ld	r18, X
-    3ede:	30 e0       	ldi	r19, 0x00	; 0
+    3ef2:	2c 91       	ld	r18, X
+    3ef4:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
-    3ee0:	11 96       	adiw	r26, 0x01	; 1
-    3ee2:	8c 91       	ld	r24, X
-    3ee4:	11 97       	sbiw	r26, 0x01	; 1
-    3ee6:	90 e0       	ldi	r25, 0x00	; 0
-    3ee8:	98 2f       	mov	r25, r24
-    3eea:	88 27       	eor	r24, r24
-    3eec:	82 2b       	or	r24, r18
-    3eee:	93 2b       	or	r25, r19
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+    3ef6:	11 96       	adiw	r26, 0x01	; 1
+    3ef8:	8c 91       	ld	r24, X
+    3efa:	11 97       	sbiw	r26, 0x01	; 1
+    3efc:	90 e0       	ldi	r25, 0x00	; 0
+    3efe:	98 2f       	mov	r25, r24
+    3f00:	88 27       	eor	r24, r24
+    3f02:	82 2b       	or	r24, r18
+    3f04:	93 2b       	or	r25, r19
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
-    3ef0:	12 96       	adiw	r26, 0x02	; 2
+    3f06:	12 96       	adiw	r26, 0x02	; 2
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
-    3ef2:	fa 01       	movw	r30, r20
-    3ef4:	0c 01       	movw	r0, r24
-    3ef6:	d0 92 57 00 	sts	0x0057, r13
-    3efa:	e8 95       	spm
-    3efc:	11 24       	eor	r1, r1
+    3f08:	fa 01       	movw	r30, r20
+    3f0a:	0c 01       	movw	r0, r24
+    3f0c:	d0 92 57 00 	sts	0x0057, r13
+    3f10:	e8 95       	spm
+    3f12:	11 24       	eor	r1, r1
         addrPtr += 2;
         addrPtr += 2;
-    3efe:	4e 5f       	subi	r20, 0xFE	; 254
-    3f00:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f14:	4e 5f       	subi	r20, 0xFE	; 254
+    3f16:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
       } while (--ch);
-    3f02:	f1 e0       	ldi	r31, 0x01	; 1
-    3f04:	a0 38       	cpi	r26, 0x80	; 128
-    3f06:	bf 07       	cpc	r27, r31
-    3f08:	49 f7       	brne	.-46     	; 0x3edc <main+0xdc>
+    3f18:	f1 e0       	ldi	r31, 0x01	; 1
+    3f1a:	a0 38       	cpi	r26, 0x80	; 128
+    3f1c:	bf 07       	cpc	r27, r31
+    3f1e:	49 f7       	brne	.-46     	; 0x3ef2 <main+0xf2>
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    3f0a:	e0 91 00 02 	lds	r30, 0x0200
-    3f0e:	f0 91 01 02 	lds	r31, 0x0201
-    3f12:	e0 92 57 00 	sts	0x0057, r14
-    3f16:	e8 95       	spm
+    3f20:	e0 91 00 02 	lds	r30, 0x0200
+    3f24:	f0 91 01 02 	lds	r31, 0x0201
+    3f28:	e0 92 57 00 	sts	0x0057, r14
+    3f2c:	e8 95       	spm
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    3f18:	07 b6       	in	r0, 0x37	; 55
-    3f1a:	00 fc       	sbrc	r0, 0
-    3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
+    3f2e:	07 b6       	in	r0, 0x37	; 55
+    3f30:	00 fc       	sbrc	r0, 0
+    3f32:	fd cf       	rjmp	.-6      	; 0x3f2e <main+0x12e>
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    3f1e:	f0 92 57 00 	sts	0x0057, r15
-    3f22:	e8 95       	spm
-    3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
+    3f34:	f0 92 57 00 	sts	0x0057, r15
+    3f38:	e8 95       	spm
+    3f3a:	27 c0       	rjmp	.+78     	; 0x3f8a <main+0x18a>
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
-    3f26:	84 37       	cpi	r24, 0x74	; 116
-    3f28:	b9 f4       	brne	.+46     	; 0x3f58 <main+0x158>
+    3f3c:	84 37       	cpi	r24, 0x74	; 116
+    3f3e:	b9 f4       	brne	.+46     	; 0x3f6e <main+0x16e>
       // READ PAGE - we only read flash
       // READ PAGE - we only read flash
       getLen();
       getLen();
-    3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
+    3f40:	37 d0       	rcall	.+110    	; 0x3fb0 <getLen>
       verifySpace();
       verifySpace();
-    3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
+    3f42:	46 d0       	rcall	.+140    	; 0x3fd0 <verifySpace>
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
-    3f2e:	e0 91 00 02 	lds	r30, 0x0200
-    3f32:	f0 91 01 02 	lds	r31, 0x0201
-    3f36:	31 96       	adiw	r30, 0x01	; 1
-    3f38:	f0 93 01 02 	sts	0x0201, r31
-    3f3c:	e0 93 00 02 	sts	0x0200, r30
-    3f40:	31 97       	sbiw	r30, 0x01	; 1
-    3f42:	e4 91       	lpm	r30, Z+
-    3f44:	8e 2f       	mov	r24, r30
-    3f46:	19 d0       	rcall	.+50     	; 0x3f7a <putch>
+    3f44:	e0 91 00 02 	lds	r30, 0x0200
+    3f48:	f0 91 01 02 	lds	r31, 0x0201
+    3f4c:	31 96       	adiw	r30, 0x01	; 1
+    3f4e:	f0 93 01 02 	sts	0x0201, r31
+    3f52:	e0 93 00 02 	sts	0x0200, r30
+    3f56:	31 97       	sbiw	r30, 0x01	; 1
+    3f58:	e4 91       	lpm	r30, Z+
+    3f5a:	8e 2f       	mov	r24, r30
+    3f5c:	19 d0       	rcall	.+50     	; 0x3f90 <putch>
       while (--length);
       while (--length);
-    3f48:	80 91 02 02 	lds	r24, 0x0202
-    3f4c:	81 50       	subi	r24, 0x01	; 1
-    3f4e:	80 93 02 02 	sts	0x0202, r24
-    3f52:	88 23       	and	r24, r24
-    3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
-    3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
+    3f5e:	80 91 02 02 	lds	r24, 0x0202
+    3f62:	81 50       	subi	r24, 0x01	; 1
+    3f64:	80 93 02 02 	sts	0x0202, r24
+    3f68:	88 23       	and	r24, r24
+    3f6a:	61 f7       	brne	.-40     	; 0x3f44 <main+0x144>
+    3f6c:	0e c0       	rjmp	.+28     	; 0x3f8a <main+0x18a>
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
     else if(ch == STK_READ_SIGN) {
-    3f58:	85 37       	cpi	r24, 0x75	; 117
-    3f5a:	39 f4       	brne	.+14     	; 0x3f6a <main+0x16a>
+    3f6e:	85 37       	cpi	r24, 0x75	; 117
+    3f70:	39 f4       	brne	.+14     	; 0x3f80 <main+0x180>
       // READ SIGN - return what Avrdude wants to hear
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
       verifySpace();
-    3f5c:	41 d0       	rcall	.+130    	; 0x3fe0 <verifySpace>
+    3f72:	2e d0       	rcall	.+92     	; 0x3fd0 <verifySpace>
       putch(SIGNATURE_0);
       putch(SIGNATURE_0);
-    3f5e:	8e e1       	ldi	r24, 0x1E	; 30
-    3f60:	0c d0       	rcall	.+24     	; 0x3f7a <putch>
+    3f74:	8e e1       	ldi	r24, 0x1E	; 30
+    3f76:	0c d0       	rcall	.+24     	; 0x3f90 <putch>
       putch(SIGNATURE_1);
       putch(SIGNATURE_1);
-    3f62:	84 e9       	ldi	r24, 0x94	; 148
-    3f64:	0a d0       	rcall	.+20     	; 0x3f7a <putch>
+    3f78:	84 e9       	ldi	r24, 0x94	; 148
+    3f7a:	0a d0       	rcall	.+20     	; 0x3f90 <putch>
       putch(SIGNATURE_2);
       putch(SIGNATURE_2);
-    3f66:	86 e0       	ldi	r24, 0x06	; 6
-    3f68:	96 cf       	rjmp	.-212    	; 0x3e96 <main+0x96>
+    3f7c:	86 e0       	ldi	r24, 0x06	; 6
+    3f7e:	96 cf       	rjmp	.-212    	; 0x3eac <main+0xac>
     }
     }
     else if (ch == 'Q') {
     else if (ch == 'Q') {
-    3f6a:	81 35       	cpi	r24, 0x51	; 81
-    3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
+    3f80:	81 35       	cpi	r24, 0x51	; 81
+    3f82:	11 f4       	brne	.+4      	; 0x3f88 <main+0x188>
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
-    3f6e:	88 e0       	ldi	r24, 0x08	; 8
-    3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
+      watchdogConfig(WATCHDOG_16MS);
+    3f84:	88 e0       	ldi	r24, 0x08	; 8
+    3f86:	19 d0       	rcall	.+50     	; 0x3fba <watchdogConfig>
       verifySpace();
       verifySpace();
     }
     }
     else {
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
       verifySpace();
-    3f72:	36 d0       	rcall	.+108    	; 0x3fe0 <verifySpace>
+    3f88:	23 d0       	rcall	.+70     	; 0x3fd0 <verifySpace>
     }
     }
     putch(STK_OK);
     putch(STK_OK);
-    3f74:	80 e1       	ldi	r24, 0x10	; 16
-    3f76:	01 d0       	rcall	.+2      	; 0x3f7a <putch>
-    3f78:	63 cf       	rjmp	.-314    	; 0x3e40 <main+0x40>
+    3f8a:	80 e1       	ldi	r24, 0x10	; 16
+    3f8c:	01 d0       	rcall	.+2      	; 0x3f90 <putch>
+    3f8e:	63 cf       	rjmp	.-314    	; 0x3e56 <main+0x56>
+
+00003f90 <putch>:
+  }
+}
 
 
-00003f7a <putch>:
 void putch(char ch) {
 void putch(char ch) {
+    3f90:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
   while (!(UCSR0A & _BV(UDRE0)));
+    3f92:	80 91 c0 00 	lds	r24, 0x00C0
+    3f96:	85 ff       	sbrs	r24, 5
+    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <putch+0x2>
   UDR0 = ch;
   UDR0 = ch;
-#else
-  __asm__ __volatile__ (
-    3f7a:	2a e0       	ldi	r18, 0x0A	; 10
-    3f7c:	30 e0       	ldi	r19, 0x00	; 0
-    3f7e:	80 95       	com	r24
-    3f80:	08 94       	sec
-    3f82:	10 f4       	brcc	.+4      	; 0x3f88 <putch+0xe>
-    3f84:	59 98       	cbi	0x0b, 1	; 11
-    3f86:	02 c0       	rjmp	.+4      	; 0x3f8c <putch+0x12>
-    3f88:	59 9a       	sbi	0x0b, 1	; 11
-    3f8a:	00 00       	nop
-    3f8c:	15 d0       	rcall	.+42     	; 0x3fb8 <uartDelay>
-    3f8e:	14 d0       	rcall	.+40     	; 0x3fb8 <uartDelay>
-    3f90:	86 95       	lsr	r24
-    3f92:	2a 95       	dec	r18
-    3f94:	b1 f7       	brne	.-20     	; 0x3f82 <putch+0x8>
+    3f9a:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
       [uartBit] "I" (UART_TX_BIT)
     :
     :
       "r25"
       "r25"
   );
   );
 #endif
 #endif
 }
 }
-    3f96:	08 95       	ret
+    3f9e:	08 95       	ret
 
 
-00003f98 <getch>:
+00003fa0 <getch>:
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3f98:	a8 95       	wdr
+    3fa0:	a8 95       	wdr
+      [uartBit] "I" (UART_RX_BIT)
+    :
+      "r25"
+);
+#else
+  while(!(UCSR0A & _BV(RXC0)));
+    3fa2:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa6:	87 ff       	sbrs	r24, 7
+    3fa8:	fc cf       	rjmp	.-8      	; 0x3fa2 <getch+0x2>
+  ch = UDR0;
+    3faa:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
 
   return ch;
   return ch;
 }
 }
-    3f9a:	29 e0       	ldi	r18, 0x09	; 9
-    3f9c:	30 e0       	ldi	r19, 0x00	; 0
-    3f9e:	48 99       	sbic	0x09, 0	; 9
-    3fa0:	fe cf       	rjmp	.-4      	; 0x3f9e <getch+0x6>
-    3fa2:	0a d0       	rcall	.+20     	; 0x3fb8 <uartDelay>
-    3fa4:	09 d0       	rcall	.+18     	; 0x3fb8 <uartDelay>
-    3fa6:	08 d0       	rcall	.+16     	; 0x3fb8 <uartDelay>
-    3fa8:	88 94       	clc
-    3faa:	48 99       	sbic	0x09, 0	; 9
-    3fac:	08 94       	sec
-    3fae:	2a 95       	dec	r18
-    3fb0:	11 f0       	breq	.+4      	; 0x3fb6 <getch+0x1e>
-    3fb2:	87 95       	ror	r24
-    3fb4:	f7 cf       	rjmp	.-18     	; 0x3fa4 <getch+0xc>
-    3fb6:	08 95       	ret
-
-00003fb8 <uartDelay>:
-#if UART_B_VALUE > 255
-#error Baud rate too slow for soft UART
-#endif
-
-void uartDelay() {
-  __asm__ __volatile__ (
-    3fb8:	98 e0       	ldi	r25, 0x08	; 8
-    3fba:	9a 95       	dec	r25
-    3fbc:	f1 f7       	brne	.-4      	; 0x3fba <uartDelay+0x2>
-    3fbe:	08 95       	ret
+    3fae:	08 95       	ret
 
 
-00003fc0 <getLen>:
+00003fb0 <getLen>:
   } while (--count);
   } while (--count);
 }
 }
 #endif
 #endif
 
 
 uint8_t getLen() {
 uint8_t getLen() {
   getch();
   getch();
-    3fc0:	eb df       	rcall	.-42     	; 0x3f98 <getch>
+    3fb0:	f7 df       	rcall	.-18     	; 0x3fa0 <getch>
   length = getch();
   length = getch();
-    3fc2:	ea df       	rcall	.-44     	; 0x3f98 <getch>
-    3fc4:	80 93 02 02 	sts	0x0202, r24
+    3fb2:	f6 df       	rcall	.-20     	; 0x3fa0 <getch>
+    3fb4:	80 93 02 02 	sts	0x0202, r24
   return getch();
   return getch();
 }
 }
-    3fc8:	e7 cf       	rjmp	.-50     	; 0x3f98 <getch>
+    3fb8:	f3 cf       	rjmp	.-26     	; 0x3fa0 <getch>
 
 
-00003fca <watchdogConfig>:
+00003fba <watchdogConfig>:
     "wdr\n"
     "wdr\n"
   );
   );
 }
 }
 
 
 void watchdogConfig(uint8_t x) {
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fca:	e0 e6       	ldi	r30, 0x60	; 96
-    3fcc:	f0 e0       	ldi	r31, 0x00	; 0
-    3fce:	98 e1       	ldi	r25, 0x18	; 24
-    3fd0:	90 83       	st	Z, r25
+    3fba:	e0 e6       	ldi	r30, 0x60	; 96
+    3fbc:	f0 e0       	ldi	r31, 0x00	; 0
+    3fbe:	98 e1       	ldi	r25, 0x18	; 24
+    3fc0:	90 83       	st	Z, r25
   WDTCSR = x;
   WDTCSR = x;
-    3fd2:	80 83       	st	Z, r24
+    3fc2:	80 83       	st	Z, r24
 }
 }
-    3fd4:	08 95       	ret
+    3fc4:	08 95       	ret
 
 
-00003fd6 <appStart>:
+00003fc6 <appStart>:
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
-    3fd6:	80 e0       	ldi	r24, 0x00	; 0
-    3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_OFF);
+    3fc6:	80 e0       	ldi	r24, 0x00	; 0
+    3fc8:	f8 df       	rcall	.-16     	; 0x3fba <watchdogConfig>
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3fda:	ee 27       	eor	r30, r30
-    3fdc:	ff 27       	eor	r31, r31
-    3fde:	09 94       	ijmp
+    3fca:	ee 27       	eor	r30, r30
+    3fcc:	ff 27       	eor	r31, r31
+    3fce:	09 94       	ijmp
 
 
-00003fe0 <verifySpace>:
+00003fd0 <verifySpace>:
   do getch(); while (--count);
   do getch(); while (--count);
   verifySpace();
   verifySpace();
 }
 }
 
 
 void verifySpace() {
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
   if (getch() != CRC_EOP) appStart();
-    3fe0:	db df       	rcall	.-74     	; 0x3f98 <getch>
-    3fe2:	80 32       	cpi	r24, 0x20	; 32
-    3fe4:	09 f0       	breq	.+2      	; 0x3fe8 <verifySpace+0x8>
-    3fe6:	f7 df       	rcall	.-18     	; 0x3fd6 <appStart>
+    3fd0:	e7 df       	rcall	.-50     	; 0x3fa0 <getch>
+    3fd2:	80 32       	cpi	r24, 0x20	; 32
+    3fd4:	09 f0       	breq	.+2      	; 0x3fd8 <verifySpace+0x8>
+    3fd6:	f7 df       	rcall	.-18     	; 0x3fc6 <appStart>
   putch(STK_INSYNC);
   putch(STK_INSYNC);
-    3fe8:	84 e1       	ldi	r24, 0x14	; 20
+    3fd8:	84 e1       	ldi	r24, 0x14	; 20
 }
 }
-    3fea:	c7 cf       	rjmp	.-114    	; 0x3f7a <putch>
+    3fda:	da cf       	rjmp	.-76     	; 0x3f90 <putch>
     ::[count] "M" (UART_B_VALUE)
     ::[count] "M" (UART_B_VALUE)
   );
   );
 }
 }
 #endif
 #endif
 
 
 void getNch(uint8_t count) {
 void getNch(uint8_t count) {
-    3fec:	1f 93       	push	r17
-    3fee:	18 2f       	mov	r17, r24
+    3fdc:	1f 93       	push	r17
+    3fde:	18 2f       	mov	r17, r24
 
 
-00003ff0 <getNch>:
+00003fe0 <getNch>:
   do getch(); while (--count);
   do getch(); while (--count);
-    3ff0:	d3 df       	rcall	.-90     	; 0x3f98 <getch>
-    3ff2:	11 50       	subi	r17, 0x01	; 1
-    3ff4:	e9 f7       	brne	.-6      	; 0x3ff0 <getNch>
+    3fe0:	df df       	rcall	.-66     	; 0x3fa0 <getch>
+    3fe2:	11 50       	subi	r17, 0x01	; 1
+    3fe4:	e9 f7       	brne	.-6      	; 0x3fe0 <getNch>
   verifySpace();
   verifySpace();
-    3ff6:	f4 df       	rcall	.-24     	; 0x3fe0 <verifySpace>
+    3fe6:	f4 df       	rcall	.-24     	; 0x3fd0 <verifySpace>
 }
 }
-    3ff8:	1f 91       	pop	r17
-    3ffa:	08 95       	ret
+    3fe8:	1f 91       	pop	r17
+    3fea:	08 95       	ret

+ 30 - 18
optiboot/bootloaders/optiboot/optiboot_lilypad.lst

@@ -9,28 +9,28 @@ Idx Name          Size      VMA       LMA       File off  Algn
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
   2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
   2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000275  00000000  00000000  000002f0  2**0
+  3 .debug_info   00000277  00000000  00000000  000002f0  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a3  00000000  00000000  00000565  2**0
+  4 .debug_abbrev 00000194  00000000  00000000  00000567  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003b8  00000000  00000000  00000708  2**0
+  5 .debug_line   000003bb  00000000  00000000  000006fb  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  000000a0  00000000  00000000  00000ac0  2**2
+  6 .debug_frame  000000a0  00000000  00000000  00000ab8  2**2
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000133  00000000  00000000  00000b60  2**0
+  7 .debug_str    0000013f  00000000  00000000  00000b58  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001a0  00000000  00000000  00000c93  2**0
+  8 .debug_loc    000001a0  00000000  00000000  00000c97  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000070  00000000  00000000  00000e33  2**0
+  9 .debug_ranges 00000070  00000000  00000000  00000e37  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
 
 
 Disassembly of section .text:
 Disassembly of section .text:
 
 
 00003e00 <main>:
 00003e00 <main>:
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e00:	85 e0       	ldi	r24, 0x05	; 5
@@ -49,7 +49,7 @@ int main(void) {
     3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
     3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
+  watchdogConfig(WATCHDOG_500MS);
     3e0e:	8d e0       	ldi	r24, 0x0D	; 13
     3e0e:	8d e0       	ldi	r24, 0x0D	; 13
     3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
     3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
 
 
@@ -120,6 +120,7 @@ void watchdogReset() {
     3e3a:	ea 2e       	mov	r14, r26
     3e3a:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
     3e3c:	f1 e1       	ldi	r31, 0x11	; 17
     3e3c:	f1 e1       	ldi	r31, 0x11	; 17
@@ -241,6 +242,8 @@ void watchdogReset() {
     3eca:	07 b6       	in	r0, 0x37	; 55
     3eca:	07 b6       	in	r0, 0x37	; 55
     3ecc:	00 fc       	sbrc	r0, 0
     3ecc:	00 fc       	sbrc	r0, 0
     3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
     3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
+      }
+#endif
 
 
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
@@ -264,10 +267,10 @@ void watchdogReset() {
     3eea:	88 27       	eor	r24, r24
     3eea:	88 27       	eor	r24, r24
     3eec:	82 2b       	or	r24, r18
     3eec:	82 2b       	or	r24, r18
     3eee:	93 2b       	or	r25, r19
     3eee:	93 2b       	or	r25, r19
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3ef0:	12 96       	adiw	r26, 0x02	; 2
     3ef0:	12 96       	adiw	r26, 0x02	; 2
@@ -302,11 +305,14 @@ int main(void) {
     3f1a:	00 fc       	sbrc	r0, 0
     3f1a:	00 fc       	sbrc	r0, 0
     3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
     3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
     3f1e:	f0 92 57 00 	sts	0x0057, r15
     3f1e:	f0 92 57 00 	sts	0x0057, r15
     3f22:	e8 95       	spm
     3f22:	e8 95       	spm
     3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
     3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
@@ -317,6 +323,11 @@ int main(void) {
     3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
     3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
       verifySpace();
       verifySpace();
     3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
     3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
     3f2e:	e0 91 00 02 	lds	r30, 0x0200
     3f2e:	e0 91 00 02 	lds	r30, 0x0200
     3f32:	f0 91 01 02 	lds	r31, 0x0201
     3f32:	f0 91 01 02 	lds	r31, 0x0201
@@ -334,6 +345,7 @@ int main(void) {
     3f52:	88 23       	and	r24, r24
     3f52:	88 23       	and	r24, r24
     3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
     3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
     3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
     3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
@@ -357,7 +369,7 @@ int main(void) {
     3f6a:	81 35       	cpi	r24, 0x51	; 81
     3f6a:	81 35       	cpi	r24, 0x51	; 81
     3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
     3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
+      watchdogConfig(WATCHDOG_16MS);
     3f6e:	88 e0       	ldi	r24, 0x08	; 8
     3f6e:	88 e0       	ldi	r24, 0x08	; 8
     3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
     3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
       verifySpace();
       verifySpace();
@@ -477,7 +489,7 @@ void watchdogConfig(uint8_t x) {
 00003fd6 <appStart>:
 00003fd6 <appStart>:
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
+  watchdogConfig(WATCHDOG_OFF);
     3fd6:	80 e0       	ldi	r24, 0x00	; 0
     3fd6:	80 e0       	ldi	r24, 0x00	; 0
     3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
     3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
   __asm__ __volatile__ (
   __asm__ __volatile__ (

+ 30 - 18
optiboot/bootloaders/optiboot/optiboot_lilypad_resonator.lst

@@ -9,28 +9,28 @@ Idx Name          Size      VMA       LMA       File off  Algn
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
   2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
   2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000275  00000000  00000000  000002f0  2**0
+  3 .debug_info   00000277  00000000  00000000  000002f0  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a3  00000000  00000000  00000565  2**0
+  4 .debug_abbrev 00000194  00000000  00000000  00000567  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003b8  00000000  00000000  00000708  2**0
+  5 .debug_line   000003bb  00000000  00000000  000006fb  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  000000a0  00000000  00000000  00000ac0  2**2
+  6 .debug_frame  000000a0  00000000  00000000  00000ab8  2**2
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000133  00000000  00000000  00000b60  2**0
+  7 .debug_str    0000013f  00000000  00000000  00000b58  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001a0  00000000  00000000  00000c93  2**0
+  8 .debug_loc    000001a0  00000000  00000000  00000c97  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000070  00000000  00000000  00000e33  2**0
+  9 .debug_ranges 00000070  00000000  00000000  00000e37  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
 
 
 Disassembly of section .text:
 Disassembly of section .text:
 
 
 00003e00 <main>:
 00003e00 <main>:
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e00:	85 e0       	ldi	r24, 0x05	; 5
@@ -49,7 +49,7 @@ int main(void) {
     3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
     3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
+  watchdogConfig(WATCHDOG_500MS);
     3e0e:	8d e0       	ldi	r24, 0x0D	; 13
     3e0e:	8d e0       	ldi	r24, 0x0D	; 13
     3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
     3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
 
 
@@ -120,6 +120,7 @@ void watchdogReset() {
     3e3a:	ea 2e       	mov	r14, r26
     3e3a:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
     3e3c:	f1 e1       	ldi	r31, 0x11	; 17
     3e3c:	f1 e1       	ldi	r31, 0x11	; 17
@@ -241,6 +242,8 @@ void watchdogReset() {
     3eca:	07 b6       	in	r0, 0x37	; 55
     3eca:	07 b6       	in	r0, 0x37	; 55
     3ecc:	00 fc       	sbrc	r0, 0
     3ecc:	00 fc       	sbrc	r0, 0
     3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
     3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
+      }
+#endif
 
 
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
@@ -264,10 +267,10 @@ void watchdogReset() {
     3eea:	88 27       	eor	r24, r24
     3eea:	88 27       	eor	r24, r24
     3eec:	82 2b       	or	r24, r18
     3eec:	82 2b       	or	r24, r18
     3eee:	93 2b       	or	r25, r19
     3eee:	93 2b       	or	r25, r19
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3ef0:	12 96       	adiw	r26, 0x02	; 2
     3ef0:	12 96       	adiw	r26, 0x02	; 2
@@ -302,11 +305,14 @@ int main(void) {
     3f1a:	00 fc       	sbrc	r0, 0
     3f1a:	00 fc       	sbrc	r0, 0
     3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
     3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
     3f1e:	f0 92 57 00 	sts	0x0057, r15
     3f1e:	f0 92 57 00 	sts	0x0057, r15
     3f22:	e8 95       	spm
     3f22:	e8 95       	spm
     3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
     3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
@@ -317,6 +323,11 @@ int main(void) {
     3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
     3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
       verifySpace();
       verifySpace();
     3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
     3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
     3f2e:	e0 91 00 02 	lds	r30, 0x0200
     3f2e:	e0 91 00 02 	lds	r30, 0x0200
     3f32:	f0 91 01 02 	lds	r31, 0x0201
     3f32:	f0 91 01 02 	lds	r31, 0x0201
@@ -334,6 +345,7 @@ int main(void) {
     3f52:	88 23       	and	r24, r24
     3f52:	88 23       	and	r24, r24
     3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
     3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
     3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
     3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
@@ -357,7 +369,7 @@ int main(void) {
     3f6a:	81 35       	cpi	r24, 0x51	; 81
     3f6a:	81 35       	cpi	r24, 0x51	; 81
     3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
     3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
+      watchdogConfig(WATCHDOG_16MS);
     3f6e:	88 e0       	ldi	r24, 0x08	; 8
     3f6e:	88 e0       	ldi	r24, 0x08	; 8
     3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
     3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
       verifySpace();
       verifySpace();
@@ -477,7 +489,7 @@ void watchdogConfig(uint8_t x) {
 00003fd6 <appStart>:
 00003fd6 <appStart>:
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
+  watchdogConfig(WATCHDOG_OFF);
     3fd6:	80 e0       	ldi	r24, 0x00	; 0
     3fd6:	80 e0       	ldi	r24, 0x00	; 0
     3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
     3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
   __asm__ __volatile__ (
   __asm__ __volatile__ (

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

@@ -1,34 +1,33 @@
-:103E000085E08093810084B714BE81FFE4D08DE00B
-:103E1000DCD0259A519A86E020E33CEF91E0309384
-:103E200085002093840096BBB09BFECF1D9AA89579
-:103E30008150A9F7DD24D394A5E0EA2EF1E1FF2E0D
-:103E4000ABD0813421F481E0D1D083E024C082342E
-:103E500011F484E103C0853419F485E0C7D08AC029
-:103E60008535A1F499D0082F10E01093010200933A
-:103E7000000292D090E0982F8827802B912B880FFA
-:103E8000991F909301028093000273C0863529F434
-:103E900084E0ACD080E071D06DC0843609F043C0BE
-:103EA0008FD0E0910002F091010283E080935700EF
-:103EB000E895C0E0D1E070D08993809102028150F2
-:103EC000809302028823B9F78BD007B600FCFDCFA0
-:103ED0004091000250910102A0E0B1E02C9130E04D
-:103EE00011968C91119790E0982F8827822B932B15
-:103EF0001296FA010C01D0925700E89511244E5FFA
-:103F00005F4FF1E0A038BF0749F7E0910002F09160
-:103F10000102E0925700E89507B600FCFDCFF09251
-:103F20005700E89527C08437B9F44AD059D0E091BA
-:103F30000002F09101023196F0930102E093000239
-:103F40003197E4918E2F19D0809102028150809395
-:103F50000202882361F70EC0853739F441D08EE123
-:103F60000CD084E90AD086E096CF813511F488E040
-:103F70002CD036D080E101D063CF2AE030E08095AC
-:103F8000089410F4599802C0599A000015D014D022
-:103F900086952A95B1F70895A89529E030E04899CB
-:103FA000FECF0AD009D008D08894489908942A9561
-:103FB00011F08795F7CF089598E09A95F1F7089555
-:103FC000EBDFEADF80930202E7CFE0E6F0E098E182
-:103FD00090838083089580E0F8DFEE27FF2709941F
-:103FE000DBDF803209F0F7DF84E1C7CF1F93182FA2
-:0C3FF000D3DF1150E9F7F4DF1F910895B2
+:103E000085E08093810082E08093C00088E1809308
+:103E1000C10086E08093C20080E18093C40084B733
+:103E200014BE81FFD0D08DE0C8D0259A86E020E373
+:103E30003CEF91E0309385002093840096BBB09BCB
+:103E4000FECF1D9AA8958150A9F7DD24D394A5E053
+:103E5000EA2EF1E1FF2EA4D0813421F481E0BED01E
+:103E600083E024C0823411F484E103C0853419F462
+:103E700085E0B4D08AC08535A1F492D0082F10E037
+:103E800010930102009300028BD090E0982F8827B6
+:103E9000802B912B880F991F909301028093000231
+:103EA00073C0863529F484E099D080E071D06DC06C
+:103EB000843609F043C07CD0E0910002F091010209
+:103EC00083E080935700E895C0E0D1E069D0899302
+:103ED000809102028150809302028823B9F778D042
+:103EE00007B600FCFDCF4091000250910102A0E016
+:103EF000B1E02C9130E011968C91119790E0982FC1
+:103F00008827822B932B1296FA010C01D09257002E
+:103F1000E89511244E5F5F4FF1E0A038BF0749F7E5
+:103F2000E0910002F0910102E0925700E89507B697
+:103F300000FCFDCFF0925700E89527C08437B9F414
+:103F400037D046D0E0910002F09101023196F09313
+:103F50000102E09300023197E4918E2F19D08091F5
+:103F60000202815080930202882361F70EC08537D8
+:103F700039F42ED08EE10CD084E90AD086E096CFB9
+:103F8000813511F488E019D023D080E101D063CFCE
+:103F9000982F8091C00085FFFCCF9093C6000895B4
+:103FA000A8958091C00087FFFCCF8091C60008953E
+:103FB000F7DFF6DF80930202F3CFE0E6F0E098E16E
+:103FC00090838083089580E0F8DFEE27FF2709942F
+:103FD000E7DF803209F0F7DF84E1DACF1F93182F93
+:0C3FE000DFDF1150E9F7F4DF1F910895B6
 :0400000300003E00BB
 :0400000300003E00BB
 :00000001FF
 :00000001FF

+ 267 - 268
optiboot/bootloaders/optiboot/optiboot_pro_16MHz.lst

@@ -3,519 +3,518 @@ optiboot_pro_16MHz.elf:     file format elf32-avr
 
 
 Sections:
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001fc  00003e00  00003e00  00000054  2**1
+  0 .text         000001ec  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000250  2**0
+  1 .debug_aranges 00000028  00000000  00000000  00000240  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000268  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000275  00000000  00000000  000002f0  2**0
+  3 .debug_info   00000269  00000000  00000000  000002d2  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a3  00000000  00000000  00000565  2**0
+  4 .debug_abbrev 00000196  00000000  00000000  0000053b  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003b8  00000000  00000000  00000708  2**0
+  5 .debug_line   000003d3  00000000  00000000  000006d1  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  000000a0  00000000  00000000  00000ac0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000aa4  2**2
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000133  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000135  00000000  00000000  00000b34  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001a0  00000000  00000000  00000c93  2**0
+  8 .debug_loc    000001d1  00000000  00000000  00000c69  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000070  00000000  00000000  00000e33  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000e3a  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
 
 
 Disassembly of section .text:
 Disassembly of section .text:
 
 
 00003e00 <main>:
 00003e00 <main>:
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e02:	80 93 81 00 	sts	0x0081, r24
     3e02:	80 93 81 00 	sts	0x0081, r24
+#if LED_START_FLASHES > 0
+  // Set up Timer 1 for timeout counter
+  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+#endif
+#ifndef SOFT_UART
+  UCSR0A = _BV(U2X0); //Double speed mode USART0
+    3e06:	82 e0       	ldi	r24, 0x02	; 2
+    3e08:	80 93 c0 00 	sts	0x00C0, r24
+  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+    3e0c:	88 e1       	ldi	r24, 0x18	; 24
+    3e0e:	80 93 c1 00 	sts	0x00C1, r24
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+    3e12:	86 e0       	ldi	r24, 0x06	; 6
+    3e14:	80 93 c2 00 	sts	0x00C2, r24
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+    3e18:	80 e1       	ldi	r24, 0x10	; 16
+    3e1a:	80 93 c4 00 	sts	0x00C4, r24
 #endif
 #endif
 
 
   // Adaboot no-wait mod
   // Adaboot no-wait mod
   ch = MCUSR;
   ch = MCUSR;
-    3e06:	84 b7       	in	r24, 0x34	; 52
+    3e1e:	84 b7       	in	r24, 0x34	; 52
   MCUSR = 0;
   MCUSR = 0;
-    3e08:	14 be       	out	0x34, r1	; 52
+    3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
   if (!(ch & _BV(EXTRF))) appStart();
-    3e0a:	81 ff       	sbrs	r24, 1
-    3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
+    3e22:	81 ff       	sbrs	r24, 1
+    3e24:	d0 d0       	rcall	.+416    	; 0x3fc6 <appStart>
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
-    3e0e:	8d e0       	ldi	r24, 0x0D	; 13
-    3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_500MS);
+    3e26:	8d e0       	ldi	r24, 0x0D	; 13
+    3e28:	c8 d0       	rcall	.+400    	; 0x3fba <watchdogConfig>
 
 
   /* Set LED pin as output */
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
   LED_DDR |= _BV(LED);
-    3e12:	25 9a       	sbi	0x04, 5	; 4
-
-#ifdef SOFT_UART
-  /* Set TX pin as output */
-  UART_DDR |= _BV(UART_TX_BIT);
-    3e14:	51 9a       	sbi	0x0a, 1	; 10
-    3e16:	86 e0       	ldi	r24, 0x06	; 6
+    3e2a:	25 9a       	sbi	0x04, 5	; 4
+    3e2c:	86 e0       	ldi	r24, 0x06	; 6
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    3e18:	20 e3       	ldi	r18, 0x30	; 48
-    3e1a:	3c ef       	ldi	r19, 0xFC	; 252
+    3e2e:	20 e3       	ldi	r18, 0x30	; 48
+    3e30:	3c ef       	ldi	r19, 0xFC	; 252
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    3e1c:	91 e0       	ldi	r25, 0x01	; 1
+    3e32:	91 e0       	ldi	r25, 0x01	; 1
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    3e1e:	30 93 85 00 	sts	0x0085, r19
-    3e22:	20 93 84 00 	sts	0x0084, r18
+    3e34:	30 93 85 00 	sts	0x0085, r19
+    3e38:	20 93 84 00 	sts	0x0084, r18
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    3e26:	96 bb       	out	0x16, r25	; 22
+    3e3c:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
-    3e28:	b0 9b       	sbis	0x16, 0	; 22
-    3e2a:	fe cf       	rjmp	.-4      	; 0x3e28 <main+0x28>
+    3e3e:	b0 9b       	sbis	0x16, 0	; 22
+    3e40:	fe cf       	rjmp	.-4      	; 0x3e3e <main+0x3e>
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
-    3e2c:	1d 9a       	sbi	0x03, 5	; 3
+    3e42:	1d 9a       	sbi	0x03, 5	; 3
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3e2e:	a8 95       	wdr
+    3e44:	a8 95       	wdr
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
     watchdogReset();
     watchdogReset();
   } while (--count);
   } while (--count);
-    3e30:	81 50       	subi	r24, 0x01	; 1
-    3e32:	a9 f7       	brne	.-22     	; 0x3e1e <main+0x1e>
+    3e46:	81 50       	subi	r24, 0x01	; 1
+    3e48:	a9 f7       	brne	.-22     	; 0x3e34 <main+0x34>
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    3e34:	dd 24       	eor	r13, r13
-    3e36:	d3 94       	inc	r13
+    3e4a:	dd 24       	eor	r13, r13
+    3e4c:	d3 94       	inc	r13
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         addrPtr += 2;
         addrPtr += 2;
       } while (--ch);
       } while (--ch);
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    3e38:	a5 e0       	ldi	r26, 0x05	; 5
-    3e3a:	ea 2e       	mov	r14, r26
+    3e4e:	a5 e0       	ldi	r26, 0x05	; 5
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    3e3c:	f1 e1       	ldi	r31, 0x11	; 17
-    3e3e:	ff 2e       	mov	r15, r31
+    3e52:	f1 e1       	ldi	r31, 0x11	; 17
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 #endif
 
 
   /* Forever loop */
   /* Forever loop */
   for (;;) {
   for (;;) {
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
-    3e40:	ab d0       	rcall	.+342    	; 0x3f98 <getch>
+    3e56:	a4 d0       	rcall	.+328    	; 0x3fa0 <getch>
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
-    3e42:	81 34       	cpi	r24, 0x41	; 65
-    3e44:	21 f4       	brne	.+8      	; 0x3e4e <main+0x4e>
+    3e58:	81 34       	cpi	r24, 0x41	; 65
+    3e5a:	21 f4       	brne	.+8      	; 0x3e64 <main+0x64>
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    3e46:	81 e0       	ldi	r24, 0x01	; 1
-    3e48:	d1 d0       	rcall	.+418    	; 0x3fec <verifySpace+0xc>
+    3e5c:	81 e0       	ldi	r24, 0x01	; 1
+    3e5e:	be d0       	rcall	.+380    	; 0x3fdc <verifySpace+0xc>
       putch(0x03);
       putch(0x03);
-    3e4a:	83 e0       	ldi	r24, 0x03	; 3
-    3e4c:	24 c0       	rjmp	.+72     	; 0x3e96 <main+0x96>
+    3e60:	83 e0       	ldi	r24, 0x03	; 3
+    3e62:	24 c0       	rjmp	.+72     	; 0x3eac <main+0xac>
     }
     }
     else if(ch == STK_SET_DEVICE) {
     else if(ch == STK_SET_DEVICE) {
-    3e4e:	82 34       	cpi	r24, 0x42	; 66
-    3e50:	11 f4       	brne	.+4      	; 0x3e56 <main+0x56>
+    3e64:	82 34       	cpi	r24, 0x42	; 66
+    3e66:	11 f4       	brne	.+4      	; 0x3e6c <main+0x6c>
       // SET DEVICE is ignored
       // SET DEVICE is ignored
       getNch(20);
       getNch(20);
-    3e52:	84 e1       	ldi	r24, 0x14	; 20
-    3e54:	03 c0       	rjmp	.+6      	; 0x3e5c <main+0x5c>
+    3e68:	84 e1       	ldi	r24, 0x14	; 20
+    3e6a:	03 c0       	rjmp	.+6      	; 0x3e72 <main+0x72>
     }
     }
     else if(ch == STK_SET_DEVICE_EXT) {
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e56:	85 34       	cpi	r24, 0x45	; 69
-    3e58:	19 f4       	brne	.+6      	; 0x3e60 <main+0x60>
+    3e6c:	85 34       	cpi	r24, 0x45	; 69
+    3e6e:	19 f4       	brne	.+6      	; 0x3e76 <main+0x76>
       // SET DEVICE EXT is ignored
       // SET DEVICE EXT is ignored
       getNch(5);
       getNch(5);
-    3e5a:	85 e0       	ldi	r24, 0x05	; 5
-    3e5c:	c7 d0       	rcall	.+398    	; 0x3fec <verifySpace+0xc>
-    3e5e:	8a c0       	rjmp	.+276    	; 0x3f74 <main+0x174>
+    3e70:	85 e0       	ldi	r24, 0x05	; 5
+    3e72:	b4 d0       	rcall	.+360    	; 0x3fdc <verifySpace+0xc>
+    3e74:	8a c0       	rjmp	.+276    	; 0x3f8a <main+0x18a>
     }
     }
     else if(ch == STK_LOAD_ADDRESS) {
     else if(ch == STK_LOAD_ADDRESS) {
-    3e60:	85 35       	cpi	r24, 0x55	; 85
-    3e62:	a1 f4       	brne	.+40     	; 0x3e8c <main+0x8c>
+    3e76:	85 35       	cpi	r24, 0x55	; 85
+    3e78:	a1 f4       	brne	.+40     	; 0x3ea2 <main+0xa2>
       // LOAD ADDRESS
       // LOAD ADDRESS
       address = getch();
       address = getch();
-    3e64:	99 d0       	rcall	.+306    	; 0x3f98 <getch>
-    3e66:	08 2f       	mov	r16, r24
-    3e68:	10 e0       	ldi	r17, 0x00	; 0
-    3e6a:	10 93 01 02 	sts	0x0201, r17
-    3e6e:	00 93 00 02 	sts	0x0200, r16
+    3e7a:	92 d0       	rcall	.+292    	; 0x3fa0 <getch>
+    3e7c:	08 2f       	mov	r16, r24
+    3e7e:	10 e0       	ldi	r17, 0x00	; 0
+    3e80:	10 93 01 02 	sts	0x0201, r17
+    3e84:	00 93 00 02 	sts	0x0200, r16
       address = (address & 0xff) | (getch() << 8);
       address = (address & 0xff) | (getch() << 8);
-    3e72:	92 d0       	rcall	.+292    	; 0x3f98 <getch>
-    3e74:	90 e0       	ldi	r25, 0x00	; 0
-    3e76:	98 2f       	mov	r25, r24
-    3e78:	88 27       	eor	r24, r24
-    3e7a:	80 2b       	or	r24, r16
-    3e7c:	91 2b       	or	r25, r17
+    3e88:	8b d0       	rcall	.+278    	; 0x3fa0 <getch>
+    3e8a:	90 e0       	ldi	r25, 0x00	; 0
+    3e8c:	98 2f       	mov	r25, r24
+    3e8e:	88 27       	eor	r24, r24
+    3e90:	80 2b       	or	r24, r16
+    3e92:	91 2b       	or	r25, r17
       address += address; // Convert from word address to byte address
       address += address; // Convert from word address to byte address
-    3e7e:	88 0f       	add	r24, r24
-    3e80:	99 1f       	adc	r25, r25
-    3e82:	90 93 01 02 	sts	0x0201, r25
-    3e86:	80 93 00 02 	sts	0x0200, r24
-    3e8a:	73 c0       	rjmp	.+230    	; 0x3f72 <main+0x172>
+    3e94:	88 0f       	add	r24, r24
+    3e96:	99 1f       	adc	r25, r25
+    3e98:	90 93 01 02 	sts	0x0201, r25
+    3e9c:	80 93 00 02 	sts	0x0200, r24
+    3ea0:	73 c0       	rjmp	.+230    	; 0x3f88 <main+0x188>
       verifySpace();
       verifySpace();
     }
     }
     else if(ch == STK_UNIVERSAL) {
     else if(ch == STK_UNIVERSAL) {
-    3e8c:	86 35       	cpi	r24, 0x56	; 86
-    3e8e:	29 f4       	brne	.+10     	; 0x3e9a <main+0x9a>
+    3ea2:	86 35       	cpi	r24, 0x56	; 86
+    3ea4:	29 f4       	brne	.+10     	; 0x3eb0 <main+0xb0>
       // UNIVERSAL command is ignored
       // UNIVERSAL command is ignored
       getNch(4);
       getNch(4);
-    3e90:	84 e0       	ldi	r24, 0x04	; 4
-    3e92:	ac d0       	rcall	.+344    	; 0x3fec <verifySpace+0xc>
+    3ea6:	84 e0       	ldi	r24, 0x04	; 4
+    3ea8:	99 d0       	rcall	.+306    	; 0x3fdc <verifySpace+0xc>
       putch(0x00);
       putch(0x00);
-    3e94:	80 e0       	ldi	r24, 0x00	; 0
-    3e96:	71 d0       	rcall	.+226    	; 0x3f7a <putch>
-    3e98:	6d c0       	rjmp	.+218    	; 0x3f74 <main+0x174>
+    3eaa:	80 e0       	ldi	r24, 0x00	; 0
+    3eac:	71 d0       	rcall	.+226    	; 0x3f90 <putch>
+    3eae:	6d c0       	rjmp	.+218    	; 0x3f8a <main+0x18a>
     }
     }
     /* Write memory, length is big endian and is in bytes  */
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     else if(ch == STK_PROG_PAGE) {
-    3e9a:	84 36       	cpi	r24, 0x64	; 100
-    3e9c:	09 f0       	breq	.+2      	; 0x3ea0 <main+0xa0>
-    3e9e:	43 c0       	rjmp	.+134    	; 0x3f26 <main+0x126>
+    3eb0:	84 36       	cpi	r24, 0x64	; 100
+    3eb2:	09 f0       	breq	.+2      	; 0x3eb6 <main+0xb6>
+    3eb4:	43 c0       	rjmp	.+134    	; 0x3f3c <main+0x13c>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint8_t *bufPtr;
       uint16_t addrPtr;
       uint16_t addrPtr;
 
 
       getLen();
       getLen();
-    3ea0:	8f d0       	rcall	.+286    	; 0x3fc0 <getLen>
+    3eb6:	7c d0       	rcall	.+248    	; 0x3fb0 <getLen>
 
 
       // Immediately start page erase - this will 4.5ms
       // Immediately start page erase - this will 4.5ms
       boot_page_erase((uint16_t)(void*)address);
       boot_page_erase((uint16_t)(void*)address);
-    3ea2:	e0 91 00 02 	lds	r30, 0x0200
-    3ea6:	f0 91 01 02 	lds	r31, 0x0201
-    3eaa:	83 e0       	ldi	r24, 0x03	; 3
-    3eac:	80 93 57 00 	sts	0x0057, r24
-    3eb0:	e8 95       	spm
-    3eb2:	c0 e0       	ldi	r28, 0x00	; 0
-    3eb4:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	e0 91 00 02 	lds	r30, 0x0200
+    3ebc:	f0 91 01 02 	lds	r31, 0x0201
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	80 93 57 00 	sts	0x0057, r24
+    3ec6:	e8 95       	spm
+    3ec8:	c0 e0       	ldi	r28, 0x00	; 0
+    3eca:	d1 e0       	ldi	r29, 0x01	; 1
 
 
       // While that is going on, read in page contents
       // While that is going on, read in page contents
       bufPtr = buff;
       bufPtr = buff;
       do *bufPtr++ = getch();
       do *bufPtr++ = getch();
-    3eb6:	70 d0       	rcall	.+224    	; 0x3f98 <getch>
-    3eb8:	89 93       	st	Y+, r24
+    3ecc:	69 d0       	rcall	.+210    	; 0x3fa0 <getch>
+    3ece:	89 93       	st	Y+, r24
       while (--length);
       while (--length);
-    3eba:	80 91 02 02 	lds	r24, 0x0202
-    3ebe:	81 50       	subi	r24, 0x01	; 1
-    3ec0:	80 93 02 02 	sts	0x0202, r24
-    3ec4:	88 23       	and	r24, r24
-    3ec6:	b9 f7       	brne	.-18     	; 0x3eb6 <main+0xb6>
+    3ed0:	80 91 02 02 	lds	r24, 0x0202
+    3ed4:	81 50       	subi	r24, 0x01	; 1
+    3ed6:	80 93 02 02 	sts	0x0202, r24
+    3eda:	88 23       	and	r24, r24
+    3edc:	b9 f7       	brne	.-18     	; 0x3ecc <main+0xcc>
 
 
       // Read command terminator, start reply
       // Read command terminator, start reply
       verifySpace();
       verifySpace();
-    3ec8:	8b d0       	rcall	.+278    	; 0x3fe0 <verifySpace>
+    3ede:	78 d0       	rcall	.+240    	; 0x3fd0 <verifySpace>
       
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       // So check that here
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    3eca:	07 b6       	in	r0, 0x37	; 55
-    3ecc:	00 fc       	sbrc	r0, 0
-    3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
+    3ee0:	07 b6       	in	r0, 0x37	; 55
+    3ee2:	00 fc       	sbrc	r0, 0
+    3ee4:	fd cf       	rjmp	.-6      	; 0x3ee0 <main+0xe0>
+      }
+#endif
 
 
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       addrPtr = (uint16_t)(void*)address;
-    3ed0:	40 91 00 02 	lds	r20, 0x0200
-    3ed4:	50 91 01 02 	lds	r21, 0x0201
-    3ed8:	a0 e0       	ldi	r26, 0x00	; 0
-    3eda:	b1 e0       	ldi	r27, 0x01	; 1
+    3ee6:	40 91 00 02 	lds	r20, 0x0200
+    3eea:	50 91 01 02 	lds	r21, 0x0201
+    3eee:	a0 e0       	ldi	r26, 0x00	; 0
+    3ef0:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
-    3edc:	2c 91       	ld	r18, X
-    3ede:	30 e0       	ldi	r19, 0x00	; 0
+    3ef2:	2c 91       	ld	r18, X
+    3ef4:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
-    3ee0:	11 96       	adiw	r26, 0x01	; 1
-    3ee2:	8c 91       	ld	r24, X
-    3ee4:	11 97       	sbiw	r26, 0x01	; 1
-    3ee6:	90 e0       	ldi	r25, 0x00	; 0
-    3ee8:	98 2f       	mov	r25, r24
-    3eea:	88 27       	eor	r24, r24
-    3eec:	82 2b       	or	r24, r18
-    3eee:	93 2b       	or	r25, r19
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+    3ef6:	11 96       	adiw	r26, 0x01	; 1
+    3ef8:	8c 91       	ld	r24, X
+    3efa:	11 97       	sbiw	r26, 0x01	; 1
+    3efc:	90 e0       	ldi	r25, 0x00	; 0
+    3efe:	98 2f       	mov	r25, r24
+    3f00:	88 27       	eor	r24, r24
+    3f02:	82 2b       	or	r24, r18
+    3f04:	93 2b       	or	r25, r19
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
-    3ef0:	12 96       	adiw	r26, 0x02	; 2
+    3f06:	12 96       	adiw	r26, 0x02	; 2
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
-    3ef2:	fa 01       	movw	r30, r20
-    3ef4:	0c 01       	movw	r0, r24
-    3ef6:	d0 92 57 00 	sts	0x0057, r13
-    3efa:	e8 95       	spm
-    3efc:	11 24       	eor	r1, r1
+    3f08:	fa 01       	movw	r30, r20
+    3f0a:	0c 01       	movw	r0, r24
+    3f0c:	d0 92 57 00 	sts	0x0057, r13
+    3f10:	e8 95       	spm
+    3f12:	11 24       	eor	r1, r1
         addrPtr += 2;
         addrPtr += 2;
-    3efe:	4e 5f       	subi	r20, 0xFE	; 254
-    3f00:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f14:	4e 5f       	subi	r20, 0xFE	; 254
+    3f16:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
       } while (--ch);
-    3f02:	f1 e0       	ldi	r31, 0x01	; 1
-    3f04:	a0 38       	cpi	r26, 0x80	; 128
-    3f06:	bf 07       	cpc	r27, r31
-    3f08:	49 f7       	brne	.-46     	; 0x3edc <main+0xdc>
+    3f18:	f1 e0       	ldi	r31, 0x01	; 1
+    3f1a:	a0 38       	cpi	r26, 0x80	; 128
+    3f1c:	bf 07       	cpc	r27, r31
+    3f1e:	49 f7       	brne	.-46     	; 0x3ef2 <main+0xf2>
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    3f0a:	e0 91 00 02 	lds	r30, 0x0200
-    3f0e:	f0 91 01 02 	lds	r31, 0x0201
-    3f12:	e0 92 57 00 	sts	0x0057, r14
-    3f16:	e8 95       	spm
+    3f20:	e0 91 00 02 	lds	r30, 0x0200
+    3f24:	f0 91 01 02 	lds	r31, 0x0201
+    3f28:	e0 92 57 00 	sts	0x0057, r14
+    3f2c:	e8 95       	spm
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    3f18:	07 b6       	in	r0, 0x37	; 55
-    3f1a:	00 fc       	sbrc	r0, 0
-    3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
+    3f2e:	07 b6       	in	r0, 0x37	; 55
+    3f30:	00 fc       	sbrc	r0, 0
+    3f32:	fd cf       	rjmp	.-6      	; 0x3f2e <main+0x12e>
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    3f1e:	f0 92 57 00 	sts	0x0057, r15
-    3f22:	e8 95       	spm
-    3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
+    3f34:	f0 92 57 00 	sts	0x0057, r15
+    3f38:	e8 95       	spm
+    3f3a:	27 c0       	rjmp	.+78     	; 0x3f8a <main+0x18a>
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
-    3f26:	84 37       	cpi	r24, 0x74	; 116
-    3f28:	b9 f4       	brne	.+46     	; 0x3f58 <main+0x158>
+    3f3c:	84 37       	cpi	r24, 0x74	; 116
+    3f3e:	b9 f4       	brne	.+46     	; 0x3f6e <main+0x16e>
       // READ PAGE - we only read flash
       // READ PAGE - we only read flash
       getLen();
       getLen();
-    3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
+    3f40:	37 d0       	rcall	.+110    	; 0x3fb0 <getLen>
       verifySpace();
       verifySpace();
-    3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
+    3f42:	46 d0       	rcall	.+140    	; 0x3fd0 <verifySpace>
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
-    3f2e:	e0 91 00 02 	lds	r30, 0x0200
-    3f32:	f0 91 01 02 	lds	r31, 0x0201
-    3f36:	31 96       	adiw	r30, 0x01	; 1
-    3f38:	f0 93 01 02 	sts	0x0201, r31
-    3f3c:	e0 93 00 02 	sts	0x0200, r30
-    3f40:	31 97       	sbiw	r30, 0x01	; 1
-    3f42:	e4 91       	lpm	r30, Z+
-    3f44:	8e 2f       	mov	r24, r30
-    3f46:	19 d0       	rcall	.+50     	; 0x3f7a <putch>
+    3f44:	e0 91 00 02 	lds	r30, 0x0200
+    3f48:	f0 91 01 02 	lds	r31, 0x0201
+    3f4c:	31 96       	adiw	r30, 0x01	; 1
+    3f4e:	f0 93 01 02 	sts	0x0201, r31
+    3f52:	e0 93 00 02 	sts	0x0200, r30
+    3f56:	31 97       	sbiw	r30, 0x01	; 1
+    3f58:	e4 91       	lpm	r30, Z+
+    3f5a:	8e 2f       	mov	r24, r30
+    3f5c:	19 d0       	rcall	.+50     	; 0x3f90 <putch>
       while (--length);
       while (--length);
-    3f48:	80 91 02 02 	lds	r24, 0x0202
-    3f4c:	81 50       	subi	r24, 0x01	; 1
-    3f4e:	80 93 02 02 	sts	0x0202, r24
-    3f52:	88 23       	and	r24, r24
-    3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
-    3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
+    3f5e:	80 91 02 02 	lds	r24, 0x0202
+    3f62:	81 50       	subi	r24, 0x01	; 1
+    3f64:	80 93 02 02 	sts	0x0202, r24
+    3f68:	88 23       	and	r24, r24
+    3f6a:	61 f7       	brne	.-40     	; 0x3f44 <main+0x144>
+    3f6c:	0e c0       	rjmp	.+28     	; 0x3f8a <main+0x18a>
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
     else if(ch == STK_READ_SIGN) {
-    3f58:	85 37       	cpi	r24, 0x75	; 117
-    3f5a:	39 f4       	brne	.+14     	; 0x3f6a <main+0x16a>
+    3f6e:	85 37       	cpi	r24, 0x75	; 117
+    3f70:	39 f4       	brne	.+14     	; 0x3f80 <main+0x180>
       // READ SIGN - return what Avrdude wants to hear
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
       verifySpace();
-    3f5c:	41 d0       	rcall	.+130    	; 0x3fe0 <verifySpace>
+    3f72:	2e d0       	rcall	.+92     	; 0x3fd0 <verifySpace>
       putch(SIGNATURE_0);
       putch(SIGNATURE_0);
-    3f5e:	8e e1       	ldi	r24, 0x1E	; 30
-    3f60:	0c d0       	rcall	.+24     	; 0x3f7a <putch>
+    3f74:	8e e1       	ldi	r24, 0x1E	; 30
+    3f76:	0c d0       	rcall	.+24     	; 0x3f90 <putch>
       putch(SIGNATURE_1);
       putch(SIGNATURE_1);
-    3f62:	84 e9       	ldi	r24, 0x94	; 148
-    3f64:	0a d0       	rcall	.+20     	; 0x3f7a <putch>
+    3f78:	84 e9       	ldi	r24, 0x94	; 148
+    3f7a:	0a d0       	rcall	.+20     	; 0x3f90 <putch>
       putch(SIGNATURE_2);
       putch(SIGNATURE_2);
-    3f66:	86 e0       	ldi	r24, 0x06	; 6
-    3f68:	96 cf       	rjmp	.-212    	; 0x3e96 <main+0x96>
+    3f7c:	86 e0       	ldi	r24, 0x06	; 6
+    3f7e:	96 cf       	rjmp	.-212    	; 0x3eac <main+0xac>
     }
     }
     else if (ch == 'Q') {
     else if (ch == 'Q') {
-    3f6a:	81 35       	cpi	r24, 0x51	; 81
-    3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
+    3f80:	81 35       	cpi	r24, 0x51	; 81
+    3f82:	11 f4       	brne	.+4      	; 0x3f88 <main+0x188>
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
-    3f6e:	88 e0       	ldi	r24, 0x08	; 8
-    3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
+      watchdogConfig(WATCHDOG_16MS);
+    3f84:	88 e0       	ldi	r24, 0x08	; 8
+    3f86:	19 d0       	rcall	.+50     	; 0x3fba <watchdogConfig>
       verifySpace();
       verifySpace();
     }
     }
     else {
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
       verifySpace();
-    3f72:	36 d0       	rcall	.+108    	; 0x3fe0 <verifySpace>
+    3f88:	23 d0       	rcall	.+70     	; 0x3fd0 <verifySpace>
     }
     }
     putch(STK_OK);
     putch(STK_OK);
-    3f74:	80 e1       	ldi	r24, 0x10	; 16
-    3f76:	01 d0       	rcall	.+2      	; 0x3f7a <putch>
-    3f78:	63 cf       	rjmp	.-314    	; 0x3e40 <main+0x40>
+    3f8a:	80 e1       	ldi	r24, 0x10	; 16
+    3f8c:	01 d0       	rcall	.+2      	; 0x3f90 <putch>
+    3f8e:	63 cf       	rjmp	.-314    	; 0x3e56 <main+0x56>
+
+00003f90 <putch>:
+  }
+}
 
 
-00003f7a <putch>:
 void putch(char ch) {
 void putch(char ch) {
+    3f90:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
   while (!(UCSR0A & _BV(UDRE0)));
+    3f92:	80 91 c0 00 	lds	r24, 0x00C0
+    3f96:	85 ff       	sbrs	r24, 5
+    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <putch+0x2>
   UDR0 = ch;
   UDR0 = ch;
-#else
-  __asm__ __volatile__ (
-    3f7a:	2a e0       	ldi	r18, 0x0A	; 10
-    3f7c:	30 e0       	ldi	r19, 0x00	; 0
-    3f7e:	80 95       	com	r24
-    3f80:	08 94       	sec
-    3f82:	10 f4       	brcc	.+4      	; 0x3f88 <putch+0xe>
-    3f84:	59 98       	cbi	0x0b, 1	; 11
-    3f86:	02 c0       	rjmp	.+4      	; 0x3f8c <putch+0x12>
-    3f88:	59 9a       	sbi	0x0b, 1	; 11
-    3f8a:	00 00       	nop
-    3f8c:	15 d0       	rcall	.+42     	; 0x3fb8 <uartDelay>
-    3f8e:	14 d0       	rcall	.+40     	; 0x3fb8 <uartDelay>
-    3f90:	86 95       	lsr	r24
-    3f92:	2a 95       	dec	r18
-    3f94:	b1 f7       	brne	.-20     	; 0x3f82 <putch+0x8>
+    3f9a:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
       [uartBit] "I" (UART_TX_BIT)
     :
     :
       "r25"
       "r25"
   );
   );
 #endif
 #endif
 }
 }
-    3f96:	08 95       	ret
+    3f9e:	08 95       	ret
 
 
-00003f98 <getch>:
+00003fa0 <getch>:
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3f98:	a8 95       	wdr
+    3fa0:	a8 95       	wdr
+      [uartBit] "I" (UART_RX_BIT)
+    :
+      "r25"
+);
+#else
+  while(!(UCSR0A & _BV(RXC0)));
+    3fa2:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa6:	87 ff       	sbrs	r24, 7
+    3fa8:	fc cf       	rjmp	.-8      	; 0x3fa2 <getch+0x2>
+  ch = UDR0;
+    3faa:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
 
   return ch;
   return ch;
 }
 }
-    3f9a:	29 e0       	ldi	r18, 0x09	; 9
-    3f9c:	30 e0       	ldi	r19, 0x00	; 0
-    3f9e:	48 99       	sbic	0x09, 0	; 9
-    3fa0:	fe cf       	rjmp	.-4      	; 0x3f9e <getch+0x6>
-    3fa2:	0a d0       	rcall	.+20     	; 0x3fb8 <uartDelay>
-    3fa4:	09 d0       	rcall	.+18     	; 0x3fb8 <uartDelay>
-    3fa6:	08 d0       	rcall	.+16     	; 0x3fb8 <uartDelay>
-    3fa8:	88 94       	clc
-    3faa:	48 99       	sbic	0x09, 0	; 9
-    3fac:	08 94       	sec
-    3fae:	2a 95       	dec	r18
-    3fb0:	11 f0       	breq	.+4      	; 0x3fb6 <getch+0x1e>
-    3fb2:	87 95       	ror	r24
-    3fb4:	f7 cf       	rjmp	.-18     	; 0x3fa4 <getch+0xc>
-    3fb6:	08 95       	ret
-
-00003fb8 <uartDelay>:
-#if UART_B_VALUE > 255
-#error Baud rate too slow for soft UART
-#endif
-
-void uartDelay() {
-  __asm__ __volatile__ (
-    3fb8:	98 e0       	ldi	r25, 0x08	; 8
-    3fba:	9a 95       	dec	r25
-    3fbc:	f1 f7       	brne	.-4      	; 0x3fba <uartDelay+0x2>
-    3fbe:	08 95       	ret
+    3fae:	08 95       	ret
 
 
-00003fc0 <getLen>:
+00003fb0 <getLen>:
   } while (--count);
   } while (--count);
 }
 }
 #endif
 #endif
 
 
 uint8_t getLen() {
 uint8_t getLen() {
   getch();
   getch();
-    3fc0:	eb df       	rcall	.-42     	; 0x3f98 <getch>
+    3fb0:	f7 df       	rcall	.-18     	; 0x3fa0 <getch>
   length = getch();
   length = getch();
-    3fc2:	ea df       	rcall	.-44     	; 0x3f98 <getch>
-    3fc4:	80 93 02 02 	sts	0x0202, r24
+    3fb2:	f6 df       	rcall	.-20     	; 0x3fa0 <getch>
+    3fb4:	80 93 02 02 	sts	0x0202, r24
   return getch();
   return getch();
 }
 }
-    3fc8:	e7 cf       	rjmp	.-50     	; 0x3f98 <getch>
+    3fb8:	f3 cf       	rjmp	.-26     	; 0x3fa0 <getch>
 
 
-00003fca <watchdogConfig>:
+00003fba <watchdogConfig>:
     "wdr\n"
     "wdr\n"
   );
   );
 }
 }
 
 
 void watchdogConfig(uint8_t x) {
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fca:	e0 e6       	ldi	r30, 0x60	; 96
-    3fcc:	f0 e0       	ldi	r31, 0x00	; 0
-    3fce:	98 e1       	ldi	r25, 0x18	; 24
-    3fd0:	90 83       	st	Z, r25
+    3fba:	e0 e6       	ldi	r30, 0x60	; 96
+    3fbc:	f0 e0       	ldi	r31, 0x00	; 0
+    3fbe:	98 e1       	ldi	r25, 0x18	; 24
+    3fc0:	90 83       	st	Z, r25
   WDTCSR = x;
   WDTCSR = x;
-    3fd2:	80 83       	st	Z, r24
+    3fc2:	80 83       	st	Z, r24
 }
 }
-    3fd4:	08 95       	ret
+    3fc4:	08 95       	ret
 
 
-00003fd6 <appStart>:
+00003fc6 <appStart>:
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
-    3fd6:	80 e0       	ldi	r24, 0x00	; 0
-    3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_OFF);
+    3fc6:	80 e0       	ldi	r24, 0x00	; 0
+    3fc8:	f8 df       	rcall	.-16     	; 0x3fba <watchdogConfig>
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3fda:	ee 27       	eor	r30, r30
-    3fdc:	ff 27       	eor	r31, r31
-    3fde:	09 94       	ijmp
+    3fca:	ee 27       	eor	r30, r30
+    3fcc:	ff 27       	eor	r31, r31
+    3fce:	09 94       	ijmp
 
 
-00003fe0 <verifySpace>:
+00003fd0 <verifySpace>:
   do getch(); while (--count);
   do getch(); while (--count);
   verifySpace();
   verifySpace();
 }
 }
 
 
 void verifySpace() {
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
   if (getch() != CRC_EOP) appStart();
-    3fe0:	db df       	rcall	.-74     	; 0x3f98 <getch>
-    3fe2:	80 32       	cpi	r24, 0x20	; 32
-    3fe4:	09 f0       	breq	.+2      	; 0x3fe8 <verifySpace+0x8>
-    3fe6:	f7 df       	rcall	.-18     	; 0x3fd6 <appStart>
+    3fd0:	e7 df       	rcall	.-50     	; 0x3fa0 <getch>
+    3fd2:	80 32       	cpi	r24, 0x20	; 32
+    3fd4:	09 f0       	breq	.+2      	; 0x3fd8 <verifySpace+0x8>
+    3fd6:	f7 df       	rcall	.-18     	; 0x3fc6 <appStart>
   putch(STK_INSYNC);
   putch(STK_INSYNC);
-    3fe8:	84 e1       	ldi	r24, 0x14	; 20
+    3fd8:	84 e1       	ldi	r24, 0x14	; 20
 }
 }
-    3fea:	c7 cf       	rjmp	.-114    	; 0x3f7a <putch>
+    3fda:	da cf       	rjmp	.-76     	; 0x3f90 <putch>
     ::[count] "M" (UART_B_VALUE)
     ::[count] "M" (UART_B_VALUE)
   );
   );
 }
 }
 #endif
 #endif
 
 
 void getNch(uint8_t count) {
 void getNch(uint8_t count) {
-    3fec:	1f 93       	push	r17
-    3fee:	18 2f       	mov	r17, r24
+    3fdc:	1f 93       	push	r17
+    3fde:	18 2f       	mov	r17, r24
 
 
-00003ff0 <getNch>:
+00003fe0 <getNch>:
   do getch(); while (--count);
   do getch(); while (--count);
-    3ff0:	d3 df       	rcall	.-90     	; 0x3f98 <getch>
-    3ff2:	11 50       	subi	r17, 0x01	; 1
-    3ff4:	e9 f7       	brne	.-6      	; 0x3ff0 <getNch>
+    3fe0:	df df       	rcall	.-66     	; 0x3fa0 <getch>
+    3fe2:	11 50       	subi	r17, 0x01	; 1
+    3fe4:	e9 f7       	brne	.-6      	; 0x3fe0 <getNch>
   verifySpace();
   verifySpace();
-    3ff6:	f4 df       	rcall	.-24     	; 0x3fe0 <verifySpace>
+    3fe6:	f4 df       	rcall	.-24     	; 0x3fd0 <verifySpace>
 }
 }
-    3ff8:	1f 91       	pop	r17
-    3ffa:	08 95       	ret
+    3fe8:	1f 91       	pop	r17
+    3fea:	08 95       	ret

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

@@ -1,34 +1,33 @@
-:103E000085E08093810084B714BE81FFE4D08DE00B
-:103E1000DCD0259A519A86E02CE33BEF91E0309379
-:103E200085002093840096BBB09BFECF1D9AA89579
-:103E30008150A9F7DD24D394A5E0EA2EF1E1FF2E0D
-:103E4000ABD0813421F481E0D1D083E024C082342E
-:103E500011F484E103C0853419F485E0C7D08AC029
-:103E60008535A1F499D0082F10E01093010200933A
-:103E7000000292D090E0982F8827802B912B880FFA
-:103E8000991F909301028093000273C0863529F434
-:103E900084E0ACD080E071D06DC0843609F043C0BE
-:103EA0008FD0E0910002F091010283E080935700EF
-:103EB000E895C0E0D1E070D08993809102028150F2
-:103EC000809302028823B9F78BD007B600FCFDCFA0
-:103ED0004091000250910102A0E0B1E02C9130E04D
-:103EE00011968C91119790E0982F8827822B932B15
-:103EF0001296FA010C01D0925700E89511244E5FFA
-:103F00005F4FF1E0A038BF0749F7E0910002F09160
-:103F10000102E0925700E89507B600FCFDCFF09251
-:103F20005700E89527C08437B9F44AD059D0E091BA
-:103F30000002F09101023196F0930102E093000239
-:103F40003197E4918E2F19D0809102028150809395
-:103F50000202882361F70EC0853739F441D08EE123
-:103F60000CD084E90AD086E096CF813511F488E040
-:103F70002CD036D080E101D063CF2AE030E08095AC
-:103F8000089410F4599802C0599A000015D014D022
-:103F900086952A95B1F70895A89529E030E04899CB
-:103FA000FECF0AD009D008D08894489908942A9561
-:103FB00011F08795F7CF08959BE09A95F1F7089552
-:103FC000EBDFEADF80930202E7CFE0E6F0E098E182
-:103FD00090838083089580E0F8DFEE27FF2709941F
-:103FE000DBDF803209F0F7DF84E1C7CF1F93182FA2
-:0C3FF000D3DF1150E9F7F4DF1F910895B2
+:103E000085E08093810082E08093C00088E1809308
+:103E1000C10086E08093C20085E18093C40084B72E
+:103E200014BE81FFD0D08DE0C8D0259A86E02CE367
+:103E30003BEF91E0309385002093840096BBB09BCC
+:103E4000FECF1D9AA8958150A9F7DD24D394A5E053
+:103E5000EA2EF1E1FF2EA4D0813421F481E0BED01E
+:103E600083E024C0823411F484E103C0853419F462
+:103E700085E0B4D08AC08535A1F492D0082F10E037
+:103E800010930102009300028BD090E0982F8827B6
+:103E9000802B912B880F991F909301028093000231
+:103EA00073C0863529F484E099D080E071D06DC06C
+:103EB000843609F043C07CD0E0910002F091010209
+:103EC00083E080935700E895C0E0D1E069D0899302
+:103ED000809102028150809302028823B9F778D042
+:103EE00007B600FCFDCF4091000250910102A0E016
+:103EF000B1E02C9130E011968C91119790E0982FC1
+:103F00008827822B932B1296FA010C01D09257002E
+:103F1000E89511244E5F5F4FF1E0A038BF0749F7E5
+:103F2000E0910002F0910102E0925700E89507B697
+:103F300000FCFDCFF0925700E89527C08437B9F414
+:103F400037D046D0E0910002F09101023196F09313
+:103F50000102E09300023197E4918E2F19D08091F5
+:103F60000202815080930202882361F70EC08537D8
+:103F700039F42ED08EE10CD084E90AD086E096CFB9
+:103F8000813511F488E019D023D080E101D063CFCE
+:103F9000982F8091C00085FFFCCF9093C6000895B4
+:103FA000A8958091C00087FFFCCF8091C60008953E
+:103FB000F7DFF6DF80930202F3CFE0E6F0E098E16E
+:103FC00090838083089580E0F8DFEE27FF2709942F
+:103FD000E7DF803209F0F7DF84E1DACF1F93182F93
+:0C3FE000DFDF1150E9F7F4DF1F910895B6
 :0400000300003E00BB
 :0400000300003E00BB
 :00000001FF
 :00000001FF

+ 267 - 268
optiboot/bootloaders/optiboot/optiboot_pro_20mhz.lst

@@ -3,519 +3,518 @@ optiboot_pro_20mhz.elf:     file format elf32-avr
 
 
 Sections:
 Sections:
 Idx Name          Size      VMA       LMA       File off  Algn
 Idx Name          Size      VMA       LMA       File off  Algn
-  0 .text         000001fc  00003e00  00003e00  00000054  2**1
+  0 .text         000001ec  00003e00  00003e00  00000054  2**1
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
                   CONTENTS, ALLOC, LOAD, READONLY, CODE
-  1 .debug_aranges 00000028  00000000  00000000  00000250  2**0
+  1 .debug_aranges 00000028  00000000  00000000  00000240  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
+  2 .debug_pubnames 0000006a  00000000  00000000  00000268  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000275  00000000  00000000  000002f0  2**0
+  3 .debug_info   00000269  00000000  00000000  000002d2  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a3  00000000  00000000  00000565  2**0
+  4 .debug_abbrev 00000196  00000000  00000000  0000053b  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003b8  00000000  00000000  00000708  2**0
+  5 .debug_line   000003d3  00000000  00000000  000006d1  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  000000a0  00000000  00000000  00000ac0  2**2
+  6 .debug_frame  00000090  00000000  00000000  00000aa4  2**2
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000133  00000000  00000000  00000b60  2**0
+  7 .debug_str    00000135  00000000  00000000  00000b34  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001a0  00000000  00000000  00000c93  2**0
+  8 .debug_loc    000001d1  00000000  00000000  00000c69  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000070  00000000  00000000  00000e33  2**0
+  9 .debug_ranges 00000068  00000000  00000000  00000e3a  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
 
 
 Disassembly of section .text:
 Disassembly of section .text:
 
 
 00003e00 <main>:
 00003e00 <main>:
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e02:	80 93 81 00 	sts	0x0081, r24
     3e02:	80 93 81 00 	sts	0x0081, r24
+#if LED_START_FLASHES > 0
+  // Set up Timer 1 for timeout counter
+  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+#endif
+#ifndef SOFT_UART
+  UCSR0A = _BV(U2X0); //Double speed mode USART0
+    3e06:	82 e0       	ldi	r24, 0x02	; 2
+    3e08:	80 93 c0 00 	sts	0x00C0, r24
+  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+    3e0c:	88 e1       	ldi	r24, 0x18	; 24
+    3e0e:	80 93 c1 00 	sts	0x00C1, r24
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
   UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+    3e12:	86 e0       	ldi	r24, 0x06	; 6
+    3e14:	80 93 c2 00 	sts	0x00C2, r24
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
   UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+    3e18:	85 e1       	ldi	r24, 0x15	; 21
+    3e1a:	80 93 c4 00 	sts	0x00C4, r24
 #endif
 #endif
 
 
   // Adaboot no-wait mod
   // Adaboot no-wait mod
   ch = MCUSR;
   ch = MCUSR;
-    3e06:	84 b7       	in	r24, 0x34	; 52
+    3e1e:	84 b7       	in	r24, 0x34	; 52
   MCUSR = 0;
   MCUSR = 0;
-    3e08:	14 be       	out	0x34, r1	; 52
+    3e20:	14 be       	out	0x34, r1	; 52
   if (!(ch & _BV(EXTRF))) appStart();
   if (!(ch & _BV(EXTRF))) appStart();
-    3e0a:	81 ff       	sbrs	r24, 1
-    3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
+    3e22:	81 ff       	sbrs	r24, 1
+    3e24:	d0 d0       	rcall	.+416    	; 0x3fc6 <appStart>
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
-    3e0e:	8d e0       	ldi	r24, 0x0D	; 13
-    3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_500MS);
+    3e26:	8d e0       	ldi	r24, 0x0D	; 13
+    3e28:	c8 d0       	rcall	.+400    	; 0x3fba <watchdogConfig>
 
 
   /* Set LED pin as output */
   /* Set LED pin as output */
   LED_DDR |= _BV(LED);
   LED_DDR |= _BV(LED);
-    3e12:	25 9a       	sbi	0x04, 5	; 4
-
-#ifdef SOFT_UART
-  /* Set TX pin as output */
-  UART_DDR |= _BV(UART_TX_BIT);
-    3e14:	51 9a       	sbi	0x0a, 1	; 10
-    3e16:	86 e0       	ldi	r24, 0x06	; 6
+    3e2a:	25 9a       	sbi	0x04, 5	; 4
+    3e2c:	86 e0       	ldi	r24, 0x06	; 6
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    3e18:	2c e3       	ldi	r18, 0x3C	; 60
-    3e1a:	3b ef       	ldi	r19, 0xFB	; 251
+    3e2e:	2c e3       	ldi	r18, 0x3C	; 60
+    3e30:	3b ef       	ldi	r19, 0xFB	; 251
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    3e1c:	91 e0       	ldi	r25, 0x01	; 1
+    3e32:	91 e0       	ldi	r25, 0x01	; 1
 }
 }
 
 
 #if LED_START_FLASHES > 0
 #if LED_START_FLASHES > 0
 void flash_led(uint8_t count) {
 void flash_led(uint8_t count) {
   do {
   do {
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
-    3e1e:	30 93 85 00 	sts	0x0085, r19
-    3e22:	20 93 84 00 	sts	0x0084, r18
+    3e34:	30 93 85 00 	sts	0x0085, r19
+    3e38:	20 93 84 00 	sts	0x0084, r18
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
-    3e26:	96 bb       	out	0x16, r25	; 22
+    3e3c:	96 bb       	out	0x16, r25	; 22
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
-    3e28:	b0 9b       	sbis	0x16, 0	; 22
-    3e2a:	fe cf       	rjmp	.-4      	; 0x3e28 <main+0x28>
+    3e3e:	b0 9b       	sbis	0x16, 0	; 22
+    3e40:	fe cf       	rjmp	.-4      	; 0x3e3e <main+0x3e>
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
-    3e2c:	1d 9a       	sbi	0x03, 5	; 3
+    3e42:	1d 9a       	sbi	0x03, 5	; 3
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3e2e:	a8 95       	wdr
+    3e44:	a8 95       	wdr
     TCNT1 = -(F_CPU/(1024*16));
     TCNT1 = -(F_CPU/(1024*16));
     TIFR1 = _BV(TOV1);
     TIFR1 = _BV(TOV1);
     while(!(TIFR1 & _BV(TOV1)));
     while(!(TIFR1 & _BV(TOV1)));
     LED_PIN |= _BV(LED);
     LED_PIN |= _BV(LED);
     watchdogReset();
     watchdogReset();
   } while (--count);
   } while (--count);
-    3e30:	81 50       	subi	r24, 0x01	; 1
-    3e32:	a9 f7       	brne	.-22     	; 0x3e1e <main+0x1e>
+    3e46:	81 50       	subi	r24, 0x01	; 1
+    3e48:	a9 f7       	brne	.-22     	; 0x3e34 <main+0x34>
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    3e34:	dd 24       	eor	r13, r13
-    3e36:	d3 94       	inc	r13
+    3e4a:	dd 24       	eor	r13, r13
+    3e4c:	d3 94       	inc	r13
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         addrPtr += 2;
         addrPtr += 2;
       } while (--ch);
       } while (--ch);
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    3e38:	a5 e0       	ldi	r26, 0x05	; 5
-    3e3a:	ea 2e       	mov	r14, r26
+    3e4e:	a5 e0       	ldi	r26, 0x05	; 5
+    3e50:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    3e3c:	f1 e1       	ldi	r31, 0x11	; 17
-    3e3e:	ff 2e       	mov	r15, r31
+    3e52:	f1 e1       	ldi	r31, 0x11	; 17
+    3e54:	ff 2e       	mov	r15, r31
 #endif
 #endif
 
 
   /* Forever loop */
   /* Forever loop */
   for (;;) {
   for (;;) {
     /* get character from UART */
     /* get character from UART */
     ch = getch();
     ch = getch();
-    3e40:	ab d0       	rcall	.+342    	; 0x3f98 <getch>
+    3e56:	a4 d0       	rcall	.+328    	; 0x3fa0 <getch>
 
 
     if(ch == STK_GET_PARAMETER) {
     if(ch == STK_GET_PARAMETER) {
-    3e42:	81 34       	cpi	r24, 0x41	; 65
-    3e44:	21 f4       	brne	.+8      	; 0x3e4e <main+0x4e>
+    3e58:	81 34       	cpi	r24, 0x41	; 65
+    3e5a:	21 f4       	brne	.+8      	; 0x3e64 <main+0x64>
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       // GET PARAMETER returns a generic 0x03 reply - enough to keep Avrdude happy
       getNch(1);
       getNch(1);
-    3e46:	81 e0       	ldi	r24, 0x01	; 1
-    3e48:	d1 d0       	rcall	.+418    	; 0x3fec <verifySpace+0xc>
+    3e5c:	81 e0       	ldi	r24, 0x01	; 1
+    3e5e:	be d0       	rcall	.+380    	; 0x3fdc <verifySpace+0xc>
       putch(0x03);
       putch(0x03);
-    3e4a:	83 e0       	ldi	r24, 0x03	; 3
-    3e4c:	24 c0       	rjmp	.+72     	; 0x3e96 <main+0x96>
+    3e60:	83 e0       	ldi	r24, 0x03	; 3
+    3e62:	24 c0       	rjmp	.+72     	; 0x3eac <main+0xac>
     }
     }
     else if(ch == STK_SET_DEVICE) {
     else if(ch == STK_SET_DEVICE) {
-    3e4e:	82 34       	cpi	r24, 0x42	; 66
-    3e50:	11 f4       	brne	.+4      	; 0x3e56 <main+0x56>
+    3e64:	82 34       	cpi	r24, 0x42	; 66
+    3e66:	11 f4       	brne	.+4      	; 0x3e6c <main+0x6c>
       // SET DEVICE is ignored
       // SET DEVICE is ignored
       getNch(20);
       getNch(20);
-    3e52:	84 e1       	ldi	r24, 0x14	; 20
-    3e54:	03 c0       	rjmp	.+6      	; 0x3e5c <main+0x5c>
+    3e68:	84 e1       	ldi	r24, 0x14	; 20
+    3e6a:	03 c0       	rjmp	.+6      	; 0x3e72 <main+0x72>
     }
     }
     else if(ch == STK_SET_DEVICE_EXT) {
     else if(ch == STK_SET_DEVICE_EXT) {
-    3e56:	85 34       	cpi	r24, 0x45	; 69
-    3e58:	19 f4       	brne	.+6      	; 0x3e60 <main+0x60>
+    3e6c:	85 34       	cpi	r24, 0x45	; 69
+    3e6e:	19 f4       	brne	.+6      	; 0x3e76 <main+0x76>
       // SET DEVICE EXT is ignored
       // SET DEVICE EXT is ignored
       getNch(5);
       getNch(5);
-    3e5a:	85 e0       	ldi	r24, 0x05	; 5
-    3e5c:	c7 d0       	rcall	.+398    	; 0x3fec <verifySpace+0xc>
-    3e5e:	8a c0       	rjmp	.+276    	; 0x3f74 <main+0x174>
+    3e70:	85 e0       	ldi	r24, 0x05	; 5
+    3e72:	b4 d0       	rcall	.+360    	; 0x3fdc <verifySpace+0xc>
+    3e74:	8a c0       	rjmp	.+276    	; 0x3f8a <main+0x18a>
     }
     }
     else if(ch == STK_LOAD_ADDRESS) {
     else if(ch == STK_LOAD_ADDRESS) {
-    3e60:	85 35       	cpi	r24, 0x55	; 85
-    3e62:	a1 f4       	brne	.+40     	; 0x3e8c <main+0x8c>
+    3e76:	85 35       	cpi	r24, 0x55	; 85
+    3e78:	a1 f4       	brne	.+40     	; 0x3ea2 <main+0xa2>
       // LOAD ADDRESS
       // LOAD ADDRESS
       address = getch();
       address = getch();
-    3e64:	99 d0       	rcall	.+306    	; 0x3f98 <getch>
-    3e66:	08 2f       	mov	r16, r24
-    3e68:	10 e0       	ldi	r17, 0x00	; 0
-    3e6a:	10 93 01 02 	sts	0x0201, r17
-    3e6e:	00 93 00 02 	sts	0x0200, r16
+    3e7a:	92 d0       	rcall	.+292    	; 0x3fa0 <getch>
+    3e7c:	08 2f       	mov	r16, r24
+    3e7e:	10 e0       	ldi	r17, 0x00	; 0
+    3e80:	10 93 01 02 	sts	0x0201, r17
+    3e84:	00 93 00 02 	sts	0x0200, r16
       address = (address & 0xff) | (getch() << 8);
       address = (address & 0xff) | (getch() << 8);
-    3e72:	92 d0       	rcall	.+292    	; 0x3f98 <getch>
-    3e74:	90 e0       	ldi	r25, 0x00	; 0
-    3e76:	98 2f       	mov	r25, r24
-    3e78:	88 27       	eor	r24, r24
-    3e7a:	80 2b       	or	r24, r16
-    3e7c:	91 2b       	or	r25, r17
+    3e88:	8b d0       	rcall	.+278    	; 0x3fa0 <getch>
+    3e8a:	90 e0       	ldi	r25, 0x00	; 0
+    3e8c:	98 2f       	mov	r25, r24
+    3e8e:	88 27       	eor	r24, r24
+    3e90:	80 2b       	or	r24, r16
+    3e92:	91 2b       	or	r25, r17
       address += address; // Convert from word address to byte address
       address += address; // Convert from word address to byte address
-    3e7e:	88 0f       	add	r24, r24
-    3e80:	99 1f       	adc	r25, r25
-    3e82:	90 93 01 02 	sts	0x0201, r25
-    3e86:	80 93 00 02 	sts	0x0200, r24
-    3e8a:	73 c0       	rjmp	.+230    	; 0x3f72 <main+0x172>
+    3e94:	88 0f       	add	r24, r24
+    3e96:	99 1f       	adc	r25, r25
+    3e98:	90 93 01 02 	sts	0x0201, r25
+    3e9c:	80 93 00 02 	sts	0x0200, r24
+    3ea0:	73 c0       	rjmp	.+230    	; 0x3f88 <main+0x188>
       verifySpace();
       verifySpace();
     }
     }
     else if(ch == STK_UNIVERSAL) {
     else if(ch == STK_UNIVERSAL) {
-    3e8c:	86 35       	cpi	r24, 0x56	; 86
-    3e8e:	29 f4       	brne	.+10     	; 0x3e9a <main+0x9a>
+    3ea2:	86 35       	cpi	r24, 0x56	; 86
+    3ea4:	29 f4       	brne	.+10     	; 0x3eb0 <main+0xb0>
       // UNIVERSAL command is ignored
       // UNIVERSAL command is ignored
       getNch(4);
       getNch(4);
-    3e90:	84 e0       	ldi	r24, 0x04	; 4
-    3e92:	ac d0       	rcall	.+344    	; 0x3fec <verifySpace+0xc>
+    3ea6:	84 e0       	ldi	r24, 0x04	; 4
+    3ea8:	99 d0       	rcall	.+306    	; 0x3fdc <verifySpace+0xc>
       putch(0x00);
       putch(0x00);
-    3e94:	80 e0       	ldi	r24, 0x00	; 0
-    3e96:	71 d0       	rcall	.+226    	; 0x3f7a <putch>
-    3e98:	6d c0       	rjmp	.+218    	; 0x3f74 <main+0x174>
+    3eaa:	80 e0       	ldi	r24, 0x00	; 0
+    3eac:	71 d0       	rcall	.+226    	; 0x3f90 <putch>
+    3eae:	6d c0       	rjmp	.+218    	; 0x3f8a <main+0x18a>
     }
     }
     /* Write memory, length is big endian and is in bytes  */
     /* Write memory, length is big endian and is in bytes  */
     else if(ch == STK_PROG_PAGE) {
     else if(ch == STK_PROG_PAGE) {
-    3e9a:	84 36       	cpi	r24, 0x64	; 100
-    3e9c:	09 f0       	breq	.+2      	; 0x3ea0 <main+0xa0>
-    3e9e:	43 c0       	rjmp	.+134    	; 0x3f26 <main+0x126>
+    3eb0:	84 36       	cpi	r24, 0x64	; 100
+    3eb2:	09 f0       	breq	.+2      	; 0x3eb6 <main+0xb6>
+    3eb4:	43 c0       	rjmp	.+134    	; 0x3f3c <main+0x13c>
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       // PROGRAM PAGE - we support flash programming only, not EEPROM
       uint8_t *bufPtr;
       uint8_t *bufPtr;
       uint16_t addrPtr;
       uint16_t addrPtr;
 
 
       getLen();
       getLen();
-    3ea0:	8f d0       	rcall	.+286    	; 0x3fc0 <getLen>
+    3eb6:	7c d0       	rcall	.+248    	; 0x3fb0 <getLen>
 
 
       // Immediately start page erase - this will 4.5ms
       // Immediately start page erase - this will 4.5ms
       boot_page_erase((uint16_t)(void*)address);
       boot_page_erase((uint16_t)(void*)address);
-    3ea2:	e0 91 00 02 	lds	r30, 0x0200
-    3ea6:	f0 91 01 02 	lds	r31, 0x0201
-    3eaa:	83 e0       	ldi	r24, 0x03	; 3
-    3eac:	80 93 57 00 	sts	0x0057, r24
-    3eb0:	e8 95       	spm
-    3eb2:	c0 e0       	ldi	r28, 0x00	; 0
-    3eb4:	d1 e0       	ldi	r29, 0x01	; 1
+    3eb8:	e0 91 00 02 	lds	r30, 0x0200
+    3ebc:	f0 91 01 02 	lds	r31, 0x0201
+    3ec0:	83 e0       	ldi	r24, 0x03	; 3
+    3ec2:	80 93 57 00 	sts	0x0057, r24
+    3ec6:	e8 95       	spm
+    3ec8:	c0 e0       	ldi	r28, 0x00	; 0
+    3eca:	d1 e0       	ldi	r29, 0x01	; 1
 
 
       // While that is going on, read in page contents
       // While that is going on, read in page contents
       bufPtr = buff;
       bufPtr = buff;
       do *bufPtr++ = getch();
       do *bufPtr++ = getch();
-    3eb6:	70 d0       	rcall	.+224    	; 0x3f98 <getch>
-    3eb8:	89 93       	st	Y+, r24
+    3ecc:	69 d0       	rcall	.+210    	; 0x3fa0 <getch>
+    3ece:	89 93       	st	Y+, r24
       while (--length);
       while (--length);
-    3eba:	80 91 02 02 	lds	r24, 0x0202
-    3ebe:	81 50       	subi	r24, 0x01	; 1
-    3ec0:	80 93 02 02 	sts	0x0202, r24
-    3ec4:	88 23       	and	r24, r24
-    3ec6:	b9 f7       	brne	.-18     	; 0x3eb6 <main+0xb6>
+    3ed0:	80 91 02 02 	lds	r24, 0x0202
+    3ed4:	81 50       	subi	r24, 0x01	; 1
+    3ed6:	80 93 02 02 	sts	0x0202, r24
+    3eda:	88 23       	and	r24, r24
+    3edc:	b9 f7       	brne	.-18     	; 0x3ecc <main+0xcc>
 
 
       // Read command terminator, start reply
       // Read command terminator, start reply
       verifySpace();
       verifySpace();
-    3ec8:	8b d0       	rcall	.+278    	; 0x3fe0 <verifySpace>
+    3ede:	78 d0       	rcall	.+240    	; 0x3fd0 <verifySpace>
       
       
       // If only a partial page is to be programmed, the erase might not be complete.
       // If only a partial page is to be programmed, the erase might not be complete.
       // So check that here
       // So check that here
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    3eca:	07 b6       	in	r0, 0x37	; 55
-    3ecc:	00 fc       	sbrc	r0, 0
-    3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
+    3ee0:	07 b6       	in	r0, 0x37	; 55
+    3ee2:	00 fc       	sbrc	r0, 0
+    3ee4:	fd cf       	rjmp	.-6      	; 0x3ee0 <main+0xe0>
+      }
+#endif
 
 
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
       addrPtr = (uint16_t)(void*)address;
       addrPtr = (uint16_t)(void*)address;
-    3ed0:	40 91 00 02 	lds	r20, 0x0200
-    3ed4:	50 91 01 02 	lds	r21, 0x0201
-    3ed8:	a0 e0       	ldi	r26, 0x00	; 0
-    3eda:	b1 e0       	ldi	r27, 0x01	; 1
+    3ee6:	40 91 00 02 	lds	r20, 0x0200
+    3eea:	50 91 01 02 	lds	r21, 0x0201
+    3eee:	a0 e0       	ldi	r26, 0x00	; 0
+    3ef0:	b1 e0       	ldi	r27, 0x01	; 1
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
-    3edc:	2c 91       	ld	r18, X
-    3ede:	30 e0       	ldi	r19, 0x00	; 0
+    3ef2:	2c 91       	ld	r18, X
+    3ef4:	30 e0       	ldi	r19, 0x00	; 0
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
-    3ee0:	11 96       	adiw	r26, 0x01	; 1
-    3ee2:	8c 91       	ld	r24, X
-    3ee4:	11 97       	sbiw	r26, 0x01	; 1
-    3ee6:	90 e0       	ldi	r25, 0x00	; 0
-    3ee8:	98 2f       	mov	r25, r24
-    3eea:	88 27       	eor	r24, r24
-    3eec:	82 2b       	or	r24, r18
-    3eee:	93 2b       	or	r25, r19
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+    3ef6:	11 96       	adiw	r26, 0x01	; 1
+    3ef8:	8c 91       	ld	r24, X
+    3efa:	11 97       	sbiw	r26, 0x01	; 1
+    3efc:	90 e0       	ldi	r25, 0x00	; 0
+    3efe:	98 2f       	mov	r25, r24
+    3f00:	88 27       	eor	r24, r24
+    3f02:	82 2b       	or	r24, r18
+    3f04:	93 2b       	or	r25, r19
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
-    3ef0:	12 96       	adiw	r26, 0x02	; 2
+    3f06:	12 96       	adiw	r26, 0x02	; 2
       ch = SPM_PAGESIZE / 2;
       ch = SPM_PAGESIZE / 2;
       do {
       do {
         uint16_t a;
         uint16_t a;
         a = *bufPtr++;
         a = *bufPtr++;
         a |= (*bufPtr++) << 8;
         a |= (*bufPtr++) << 8;
         boot_page_fill((uint16_t)(void*)addrPtr,a);
         boot_page_fill((uint16_t)(void*)addrPtr,a);
-    3ef2:	fa 01       	movw	r30, r20
-    3ef4:	0c 01       	movw	r0, r24
-    3ef6:	d0 92 57 00 	sts	0x0057, r13
-    3efa:	e8 95       	spm
-    3efc:	11 24       	eor	r1, r1
+    3f08:	fa 01       	movw	r30, r20
+    3f0a:	0c 01       	movw	r0, r24
+    3f0c:	d0 92 57 00 	sts	0x0057, r13
+    3f10:	e8 95       	spm
+    3f12:	11 24       	eor	r1, r1
         addrPtr += 2;
         addrPtr += 2;
-    3efe:	4e 5f       	subi	r20, 0xFE	; 254
-    3f00:	5f 4f       	sbci	r21, 0xFF	; 255
+    3f14:	4e 5f       	subi	r20, 0xFE	; 254
+    3f16:	5f 4f       	sbci	r21, 0xFF	; 255
       } while (--ch);
       } while (--ch);
-    3f02:	f1 e0       	ldi	r31, 0x01	; 1
-    3f04:	a0 38       	cpi	r26, 0x80	; 128
-    3f06:	bf 07       	cpc	r27, r31
-    3f08:	49 f7       	brne	.-46     	; 0x3edc <main+0xdc>
+    3f18:	f1 e0       	ldi	r31, 0x01	; 1
+    3f1a:	a0 38       	cpi	r26, 0x80	; 128
+    3f1c:	bf 07       	cpc	r27, r31
+    3f1e:	49 f7       	brne	.-46     	; 0x3ef2 <main+0xf2>
       
       
       // Write from programming buffer
       // Write from programming buffer
       boot_page_write((uint16_t)(void*)address);
       boot_page_write((uint16_t)(void*)address);
-    3f0a:	e0 91 00 02 	lds	r30, 0x0200
-    3f0e:	f0 91 01 02 	lds	r31, 0x0201
-    3f12:	e0 92 57 00 	sts	0x0057, r14
-    3f16:	e8 95       	spm
+    3f20:	e0 91 00 02 	lds	r30, 0x0200
+    3f24:	f0 91 01 02 	lds	r31, 0x0201
+    3f28:	e0 92 57 00 	sts	0x0057, r14
+    3f2c:	e8 95       	spm
       boot_spm_busy_wait();
       boot_spm_busy_wait();
-    3f18:	07 b6       	in	r0, 0x37	; 55
-    3f1a:	00 fc       	sbrc	r0, 0
-    3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
+    3f2e:	07 b6       	in	r0, 0x37	; 55
+    3f30:	00 fc       	sbrc	r0, 0
+    3f32:	fd cf       	rjmp	.-6      	; 0x3f2e <main+0x12e>
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
-    3f1e:	f0 92 57 00 	sts	0x0057, r15
-    3f22:	e8 95       	spm
-    3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
+    3f34:	f0 92 57 00 	sts	0x0057, r15
+    3f38:	e8 95       	spm
+    3f3a:	27 c0       	rjmp	.+78     	; 0x3f8a <main+0x18a>
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
-    3f26:	84 37       	cpi	r24, 0x74	; 116
-    3f28:	b9 f4       	brne	.+46     	; 0x3f58 <main+0x158>
+    3f3c:	84 37       	cpi	r24, 0x74	; 116
+    3f3e:	b9 f4       	brne	.+46     	; 0x3f6e <main+0x16e>
       // READ PAGE - we only read flash
       // READ PAGE - we only read flash
       getLen();
       getLen();
-    3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
+    3f40:	37 d0       	rcall	.+110    	; 0x3fb0 <getLen>
       verifySpace();
       verifySpace();
-    3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
+    3f42:	46 d0       	rcall	.+140    	; 0x3fd0 <verifySpace>
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
-    3f2e:	e0 91 00 02 	lds	r30, 0x0200
-    3f32:	f0 91 01 02 	lds	r31, 0x0201
-    3f36:	31 96       	adiw	r30, 0x01	; 1
-    3f38:	f0 93 01 02 	sts	0x0201, r31
-    3f3c:	e0 93 00 02 	sts	0x0200, r30
-    3f40:	31 97       	sbiw	r30, 0x01	; 1
-    3f42:	e4 91       	lpm	r30, Z+
-    3f44:	8e 2f       	mov	r24, r30
-    3f46:	19 d0       	rcall	.+50     	; 0x3f7a <putch>
+    3f44:	e0 91 00 02 	lds	r30, 0x0200
+    3f48:	f0 91 01 02 	lds	r31, 0x0201
+    3f4c:	31 96       	adiw	r30, 0x01	; 1
+    3f4e:	f0 93 01 02 	sts	0x0201, r31
+    3f52:	e0 93 00 02 	sts	0x0200, r30
+    3f56:	31 97       	sbiw	r30, 0x01	; 1
+    3f58:	e4 91       	lpm	r30, Z+
+    3f5a:	8e 2f       	mov	r24, r30
+    3f5c:	19 d0       	rcall	.+50     	; 0x3f90 <putch>
       while (--length);
       while (--length);
-    3f48:	80 91 02 02 	lds	r24, 0x0202
-    3f4c:	81 50       	subi	r24, 0x01	; 1
-    3f4e:	80 93 02 02 	sts	0x0202, r24
-    3f52:	88 23       	and	r24, r24
-    3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
-    3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
+    3f5e:	80 91 02 02 	lds	r24, 0x0202
+    3f62:	81 50       	subi	r24, 0x01	; 1
+    3f64:	80 93 02 02 	sts	0x0202, r24
+    3f68:	88 23       	and	r24, r24
+    3f6a:	61 f7       	brne	.-40     	; 0x3f44 <main+0x144>
+    3f6c:	0e c0       	rjmp	.+28     	; 0x3f8a <main+0x18a>
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
     else if(ch == STK_READ_SIGN) {
     else if(ch == STK_READ_SIGN) {
-    3f58:	85 37       	cpi	r24, 0x75	; 117
-    3f5a:	39 f4       	brne	.+14     	; 0x3f6a <main+0x16a>
+    3f6e:	85 37       	cpi	r24, 0x75	; 117
+    3f70:	39 f4       	brne	.+14     	; 0x3f80 <main+0x180>
       // READ SIGN - return what Avrdude wants to hear
       // READ SIGN - return what Avrdude wants to hear
       verifySpace();
       verifySpace();
-    3f5c:	41 d0       	rcall	.+130    	; 0x3fe0 <verifySpace>
+    3f72:	2e d0       	rcall	.+92     	; 0x3fd0 <verifySpace>
       putch(SIGNATURE_0);
       putch(SIGNATURE_0);
-    3f5e:	8e e1       	ldi	r24, 0x1E	; 30
-    3f60:	0c d0       	rcall	.+24     	; 0x3f7a <putch>
+    3f74:	8e e1       	ldi	r24, 0x1E	; 30
+    3f76:	0c d0       	rcall	.+24     	; 0x3f90 <putch>
       putch(SIGNATURE_1);
       putch(SIGNATURE_1);
-    3f62:	84 e9       	ldi	r24, 0x94	; 148
-    3f64:	0a d0       	rcall	.+20     	; 0x3f7a <putch>
+    3f78:	84 e9       	ldi	r24, 0x94	; 148
+    3f7a:	0a d0       	rcall	.+20     	; 0x3f90 <putch>
       putch(SIGNATURE_2);
       putch(SIGNATURE_2);
-    3f66:	86 e0       	ldi	r24, 0x06	; 6
-    3f68:	96 cf       	rjmp	.-212    	; 0x3e96 <main+0x96>
+    3f7c:	86 e0       	ldi	r24, 0x06	; 6
+    3f7e:	96 cf       	rjmp	.-212    	; 0x3eac <main+0xac>
     }
     }
     else if (ch == 'Q') {
     else if (ch == 'Q') {
-    3f6a:	81 35       	cpi	r24, 0x51	; 81
-    3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
+    3f80:	81 35       	cpi	r24, 0x51	; 81
+    3f82:	11 f4       	brne	.+4      	; 0x3f88 <main+0x188>
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
-    3f6e:	88 e0       	ldi	r24, 0x08	; 8
-    3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
+      watchdogConfig(WATCHDOG_16MS);
+    3f84:	88 e0       	ldi	r24, 0x08	; 8
+    3f86:	19 d0       	rcall	.+50     	; 0x3fba <watchdogConfig>
       verifySpace();
       verifySpace();
     }
     }
     else {
     else {
       // This covers the response to commands like STK_ENTER_PROGMODE
       // This covers the response to commands like STK_ENTER_PROGMODE
       verifySpace();
       verifySpace();
-    3f72:	36 d0       	rcall	.+108    	; 0x3fe0 <verifySpace>
+    3f88:	23 d0       	rcall	.+70     	; 0x3fd0 <verifySpace>
     }
     }
     putch(STK_OK);
     putch(STK_OK);
-    3f74:	80 e1       	ldi	r24, 0x10	; 16
-    3f76:	01 d0       	rcall	.+2      	; 0x3f7a <putch>
-    3f78:	63 cf       	rjmp	.-314    	; 0x3e40 <main+0x40>
+    3f8a:	80 e1       	ldi	r24, 0x10	; 16
+    3f8c:	01 d0       	rcall	.+2      	; 0x3f90 <putch>
+    3f8e:	63 cf       	rjmp	.-314    	; 0x3e56 <main+0x56>
+
+00003f90 <putch>:
+  }
+}
 
 
-00003f7a <putch>:
 void putch(char ch) {
 void putch(char ch) {
+    3f90:	98 2f       	mov	r25, r24
 #ifndef SOFT_UART
 #ifndef SOFT_UART
   while (!(UCSR0A & _BV(UDRE0)));
   while (!(UCSR0A & _BV(UDRE0)));
+    3f92:	80 91 c0 00 	lds	r24, 0x00C0
+    3f96:	85 ff       	sbrs	r24, 5
+    3f98:	fc cf       	rjmp	.-8      	; 0x3f92 <putch+0x2>
   UDR0 = ch;
   UDR0 = ch;
-#else
-  __asm__ __volatile__ (
-    3f7a:	2a e0       	ldi	r18, 0x0A	; 10
-    3f7c:	30 e0       	ldi	r19, 0x00	; 0
-    3f7e:	80 95       	com	r24
-    3f80:	08 94       	sec
-    3f82:	10 f4       	brcc	.+4      	; 0x3f88 <putch+0xe>
-    3f84:	59 98       	cbi	0x0b, 1	; 11
-    3f86:	02 c0       	rjmp	.+4      	; 0x3f8c <putch+0x12>
-    3f88:	59 9a       	sbi	0x0b, 1	; 11
-    3f8a:	00 00       	nop
-    3f8c:	15 d0       	rcall	.+42     	; 0x3fb8 <uartDelay>
-    3f8e:	14 d0       	rcall	.+40     	; 0x3fb8 <uartDelay>
-    3f90:	86 95       	lsr	r24
-    3f92:	2a 95       	dec	r18
-    3f94:	b1 f7       	brne	.-20     	; 0x3f82 <putch+0x8>
+    3f9a:	90 93 c6 00 	sts	0x00C6, r25
       [uartBit] "I" (UART_TX_BIT)
       [uartBit] "I" (UART_TX_BIT)
     :
     :
       "r25"
       "r25"
   );
   );
 #endif
 #endif
 }
 }
-    3f96:	08 95       	ret
+    3f9e:	08 95       	ret
 
 
-00003f98 <getch>:
+00003fa0 <getch>:
   return getch();
   return getch();
 }
 }
 
 
 // Watchdog functions. These are only safe with interrupts turned off.
 // Watchdog functions. These are only safe with interrupts turned off.
 void watchdogReset() {
 void watchdogReset() {
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3f98:	a8 95       	wdr
+    3fa0:	a8 95       	wdr
+      [uartBit] "I" (UART_RX_BIT)
+    :
+      "r25"
+);
+#else
+  while(!(UCSR0A & _BV(RXC0)));
+    3fa2:	80 91 c0 00 	lds	r24, 0x00C0
+    3fa6:	87 ff       	sbrs	r24, 7
+    3fa8:	fc cf       	rjmp	.-8      	; 0x3fa2 <getch+0x2>
+  ch = UDR0;
+    3faa:	80 91 c6 00 	lds	r24, 0x00C6
 #ifdef LED_DATA_FLASH
 #ifdef LED_DATA_FLASH
   LED_PIN |= _BV(LED);
   LED_PIN |= _BV(LED);
 #endif
 #endif
 
 
   return ch;
   return ch;
 }
 }
-    3f9a:	29 e0       	ldi	r18, 0x09	; 9
-    3f9c:	30 e0       	ldi	r19, 0x00	; 0
-    3f9e:	48 99       	sbic	0x09, 0	; 9
-    3fa0:	fe cf       	rjmp	.-4      	; 0x3f9e <getch+0x6>
-    3fa2:	0a d0       	rcall	.+20     	; 0x3fb8 <uartDelay>
-    3fa4:	09 d0       	rcall	.+18     	; 0x3fb8 <uartDelay>
-    3fa6:	08 d0       	rcall	.+16     	; 0x3fb8 <uartDelay>
-    3fa8:	88 94       	clc
-    3faa:	48 99       	sbic	0x09, 0	; 9
-    3fac:	08 94       	sec
-    3fae:	2a 95       	dec	r18
-    3fb0:	11 f0       	breq	.+4      	; 0x3fb6 <getch+0x1e>
-    3fb2:	87 95       	ror	r24
-    3fb4:	f7 cf       	rjmp	.-18     	; 0x3fa4 <getch+0xc>
-    3fb6:	08 95       	ret
-
-00003fb8 <uartDelay>:
-#if UART_B_VALUE > 255
-#error Baud rate too slow for soft UART
-#endif
-
-void uartDelay() {
-  __asm__ __volatile__ (
-    3fb8:	9b e0       	ldi	r25, 0x0B	; 11
-    3fba:	9a 95       	dec	r25
-    3fbc:	f1 f7       	brne	.-4      	; 0x3fba <uartDelay+0x2>
-    3fbe:	08 95       	ret
+    3fae:	08 95       	ret
 
 
-00003fc0 <getLen>:
+00003fb0 <getLen>:
   } while (--count);
   } while (--count);
 }
 }
 #endif
 #endif
 
 
 uint8_t getLen() {
 uint8_t getLen() {
   getch();
   getch();
-    3fc0:	eb df       	rcall	.-42     	; 0x3f98 <getch>
+    3fb0:	f7 df       	rcall	.-18     	; 0x3fa0 <getch>
   length = getch();
   length = getch();
-    3fc2:	ea df       	rcall	.-44     	; 0x3f98 <getch>
-    3fc4:	80 93 02 02 	sts	0x0202, r24
+    3fb2:	f6 df       	rcall	.-20     	; 0x3fa0 <getch>
+    3fb4:	80 93 02 02 	sts	0x0202, r24
   return getch();
   return getch();
 }
 }
-    3fc8:	e7 cf       	rjmp	.-50     	; 0x3f98 <getch>
+    3fb8:	f3 cf       	rjmp	.-26     	; 0x3fa0 <getch>
 
 
-00003fca <watchdogConfig>:
+00003fba <watchdogConfig>:
     "wdr\n"
     "wdr\n"
   );
   );
 }
 }
 
 
 void watchdogConfig(uint8_t x) {
 void watchdogConfig(uint8_t x) {
   WDTCSR = _BV(WDCE) | _BV(WDE);
   WDTCSR = _BV(WDCE) | _BV(WDE);
-    3fca:	e0 e6       	ldi	r30, 0x60	; 96
-    3fcc:	f0 e0       	ldi	r31, 0x00	; 0
-    3fce:	98 e1       	ldi	r25, 0x18	; 24
-    3fd0:	90 83       	st	Z, r25
+    3fba:	e0 e6       	ldi	r30, 0x60	; 96
+    3fbc:	f0 e0       	ldi	r31, 0x00	; 0
+    3fbe:	98 e1       	ldi	r25, 0x18	; 24
+    3fc0:	90 83       	st	Z, r25
   WDTCSR = x;
   WDTCSR = x;
-    3fd2:	80 83       	st	Z, r24
+    3fc2:	80 83       	st	Z, r24
 }
 }
-    3fd4:	08 95       	ret
+    3fc4:	08 95       	ret
 
 
-00003fd6 <appStart>:
+00003fc6 <appStart>:
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
-    3fd6:	80 e0       	ldi	r24, 0x00	; 0
-    3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
+  watchdogConfig(WATCHDOG_OFF);
+    3fc6:	80 e0       	ldi	r24, 0x00	; 0
+    3fc8:	f8 df       	rcall	.-16     	; 0x3fba <watchdogConfig>
   __asm__ __volatile__ (
   __asm__ __volatile__ (
-    3fda:	ee 27       	eor	r30, r30
-    3fdc:	ff 27       	eor	r31, r31
-    3fde:	09 94       	ijmp
+    3fca:	ee 27       	eor	r30, r30
+    3fcc:	ff 27       	eor	r31, r31
+    3fce:	09 94       	ijmp
 
 
-00003fe0 <verifySpace>:
+00003fd0 <verifySpace>:
   do getch(); while (--count);
   do getch(); while (--count);
   verifySpace();
   verifySpace();
 }
 }
 
 
 void verifySpace() {
 void verifySpace() {
   if (getch() != CRC_EOP) appStart();
   if (getch() != CRC_EOP) appStart();
-    3fe0:	db df       	rcall	.-74     	; 0x3f98 <getch>
-    3fe2:	80 32       	cpi	r24, 0x20	; 32
-    3fe4:	09 f0       	breq	.+2      	; 0x3fe8 <verifySpace+0x8>
-    3fe6:	f7 df       	rcall	.-18     	; 0x3fd6 <appStart>
+    3fd0:	e7 df       	rcall	.-50     	; 0x3fa0 <getch>
+    3fd2:	80 32       	cpi	r24, 0x20	; 32
+    3fd4:	09 f0       	breq	.+2      	; 0x3fd8 <verifySpace+0x8>
+    3fd6:	f7 df       	rcall	.-18     	; 0x3fc6 <appStart>
   putch(STK_INSYNC);
   putch(STK_INSYNC);
-    3fe8:	84 e1       	ldi	r24, 0x14	; 20
+    3fd8:	84 e1       	ldi	r24, 0x14	; 20
 }
 }
-    3fea:	c7 cf       	rjmp	.-114    	; 0x3f7a <putch>
+    3fda:	da cf       	rjmp	.-76     	; 0x3f90 <putch>
     ::[count] "M" (UART_B_VALUE)
     ::[count] "M" (UART_B_VALUE)
   );
   );
 }
 }
 #endif
 #endif
 
 
 void getNch(uint8_t count) {
 void getNch(uint8_t count) {
-    3fec:	1f 93       	push	r17
-    3fee:	18 2f       	mov	r17, r24
+    3fdc:	1f 93       	push	r17
+    3fde:	18 2f       	mov	r17, r24
 
 
-00003ff0 <getNch>:
+00003fe0 <getNch>:
   do getch(); while (--count);
   do getch(); while (--count);
-    3ff0:	d3 df       	rcall	.-90     	; 0x3f98 <getch>
-    3ff2:	11 50       	subi	r17, 0x01	; 1
-    3ff4:	e9 f7       	brne	.-6      	; 0x3ff0 <getNch>
+    3fe0:	df df       	rcall	.-66     	; 0x3fa0 <getch>
+    3fe2:	11 50       	subi	r17, 0x01	; 1
+    3fe4:	e9 f7       	brne	.-6      	; 0x3fe0 <getNch>
   verifySpace();
   verifySpace();
-    3ff6:	f4 df       	rcall	.-24     	; 0x3fe0 <verifySpace>
+    3fe6:	f4 df       	rcall	.-24     	; 0x3fd0 <verifySpace>
 }
 }
-    3ff8:	1f 91       	pop	r17
-    3ffa:	08 95       	ret
+    3fe8:	1f 91       	pop	r17
+    3fea:	08 95       	ret

+ 30 - 18
optiboot/bootloaders/optiboot/optiboot_pro_8MHz.lst

@@ -9,28 +9,28 @@ Idx Name          Size      VMA       LMA       File off  Algn
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
   2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
   2 .debug_pubnames 00000078  00000000  00000000  00000278  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  3 .debug_info   00000275  00000000  00000000  000002f0  2**0
+  3 .debug_info   00000277  00000000  00000000  000002f0  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  4 .debug_abbrev 000001a3  00000000  00000000  00000565  2**0
+  4 .debug_abbrev 00000194  00000000  00000000  00000567  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  5 .debug_line   000003b8  00000000  00000000  00000708  2**0
+  5 .debug_line   000003bb  00000000  00000000  000006fb  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  6 .debug_frame  000000a0  00000000  00000000  00000ac0  2**2
+  6 .debug_frame  000000a0  00000000  00000000  00000ab8  2**2
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  7 .debug_str    00000133  00000000  00000000  00000b60  2**0
+  7 .debug_str    0000013f  00000000  00000000  00000b58  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  8 .debug_loc    000001a0  00000000  00000000  00000c93  2**0
+  8 .debug_loc    000001a0  00000000  00000000  00000c97  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
-  9 .debug_ranges 00000070  00000000  00000000  00000e33  2**0
+  9 .debug_ranges 00000070  00000000  00000000  00000e37  2**0
                   CONTENTS, READONLY, DEBUGGING
                   CONTENTS, READONLY, DEBUGGING
 
 
 Disassembly of section .text:
 Disassembly of section .text:
 
 
 00003e00 <main>:
 00003e00 <main>:
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3e00:	85 e0       	ldi	r24, 0x05	; 5
     3e00:	85 e0       	ldi	r24, 0x05	; 5
@@ -49,7 +49,7 @@ int main(void) {
     3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
     3e0c:	e4 d0       	rcall	.+456    	; 0x3fd6 <appStart>
 
 
   // Set up watchdog to trigger after 500ms
   // Set up watchdog to trigger after 500ms
-  watchdogConfig(_BV(WDP2)|_BV(WDP0)|_BV(WDE));
+  watchdogConfig(WATCHDOG_500MS);
     3e0e:	8d e0       	ldi	r24, 0x0D	; 13
     3e0e:	8d e0       	ldi	r24, 0x0D	; 13
     3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
     3e10:	dc d0       	rcall	.+440    	; 0x3fca <watchdogConfig>
 
 
@@ -120,6 +120,7 @@ void watchdogReset() {
     3e3a:	ea 2e       	mov	r14, r26
     3e3a:	ea 2e       	mov	r14, r26
       boot_spm_busy_wait();
       boot_spm_busy_wait();
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
     3e3c:	f1 e1       	ldi	r31, 0x11	; 17
     3e3c:	f1 e1       	ldi	r31, 0x11	; 17
@@ -241,6 +242,8 @@ void watchdogReset() {
     3eca:	07 b6       	in	r0, 0x37	; 55
     3eca:	07 b6       	in	r0, 0x37	; 55
     3ecc:	00 fc       	sbrc	r0, 0
     3ecc:	00 fc       	sbrc	r0, 0
     3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
     3ece:	fd cf       	rjmp	.-6      	; 0x3eca <main+0xca>
+      }
+#endif
 
 
       // Copy buffer into programming buffer
       // Copy buffer into programming buffer
       bufPtr = buff;
       bufPtr = buff;
@@ -264,10 +267,10 @@ void watchdogReset() {
     3eea:	88 27       	eor	r24, r24
     3eea:	88 27       	eor	r24, r24
     3eec:	82 2b       	or	r24, r18
     3eec:	82 2b       	or	r24, r18
     3eee:	93 2b       	or	r25, r19
     3eee:	93 2b       	or	r25, r19
-#define buff    ((uint8_t*)(0x100))
-#define address (*(uint16_t*)(0x200))
-#define length  (*(uint8_t*)(0x202))
-
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(0x204))
+#define wdtVect (*(uint16_t*)(0x206))
+#endif
 /* main program starts here */
 /* main program starts here */
 int main(void) {
 int main(void) {
     3ef0:	12 96       	adiw	r26, 0x02	; 2
     3ef0:	12 96       	adiw	r26, 0x02	; 2
@@ -302,11 +305,14 @@ int main(void) {
     3f1a:	00 fc       	sbrc	r0, 0
     3f1a:	00 fc       	sbrc	r0, 0
     3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
     3f1c:	fd cf       	rjmp	.-6      	; 0x3f18 <main+0x118>
 
 
+#if defined(RWWSRE)
       // Reenable read access to flash
       // Reenable read access to flash
       boot_rww_enable();
       boot_rww_enable();
     3f1e:	f0 92 57 00 	sts	0x0057, r15
     3f1e:	f0 92 57 00 	sts	0x0057, r15
     3f22:	e8 95       	spm
     3f22:	e8 95       	spm
     3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
     3f24:	27 c0       	rjmp	.+78     	; 0x3f74 <main+0x174>
+#endif
+
     }
     }
     /* Read memory block mode, length is big endian.  */
     /* Read memory block mode, length is big endian.  */
     else if(ch == STK_READ_PAGE) {
     else if(ch == STK_READ_PAGE) {
@@ -317,6 +323,11 @@ int main(void) {
     3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
     3f2a:	4a d0       	rcall	.+148    	; 0x3fc0 <getLen>
       verifySpace();
       verifySpace();
     3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
     3f2c:	59 d0       	rcall	.+178    	; 0x3fe0 <verifySpace>
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
       do putch(pgm_read_byte_near(address++));
       do putch(pgm_read_byte_near(address++));
     3f2e:	e0 91 00 02 	lds	r30, 0x0200
     3f2e:	e0 91 00 02 	lds	r30, 0x0200
     3f32:	f0 91 01 02 	lds	r31, 0x0201
     3f32:	f0 91 01 02 	lds	r31, 0x0201
@@ -334,6 +345,7 @@ int main(void) {
     3f52:	88 23       	and	r24, r24
     3f52:	88 23       	and	r24, r24
     3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
     3f54:	61 f7       	brne	.-40     	; 0x3f2e <main+0x12e>
     3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
     3f56:	0e c0       	rjmp	.+28     	; 0x3f74 <main+0x174>
+#endif
     }
     }
 
 
     /* Get device signature bytes  */
     /* Get device signature bytes  */
@@ -357,7 +369,7 @@ int main(void) {
     3f6a:	81 35       	cpi	r24, 0x51	; 81
     3f6a:	81 35       	cpi	r24, 0x51	; 81
     3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
     3f6c:	11 f4       	brne	.+4      	; 0x3f72 <main+0x172>
       // Adaboot no-wait mod
       // Adaboot no-wait mod
-      watchdogConfig(_BV(WDE));
+      watchdogConfig(WATCHDOG_16MS);
     3f6e:	88 e0       	ldi	r24, 0x08	; 8
     3f6e:	88 e0       	ldi	r24, 0x08	; 8
     3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
     3f70:	2c d0       	rcall	.+88     	; 0x3fca <watchdogConfig>
       verifySpace();
       verifySpace();
@@ -477,7 +489,7 @@ void watchdogConfig(uint8_t x) {
 00003fd6 <appStart>:
 00003fd6 <appStart>:
 
 
 void appStart() {
 void appStart() {
-  watchdogConfig(0);
+  watchdogConfig(WATCHDOG_OFF);
     3fd6:	80 e0       	ldi	r24, 0x00	; 0
     3fd6:	80 e0       	ldi	r24, 0x00	; 0
     3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
     3fd8:	f8 df       	rcall	.-16     	; 0x3fca <watchdogConfig>
   __asm__ __volatile__ (
   __asm__ __volatile__ (