diff --git a/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/Makefile b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..742fd4b7986f0db998fd06aefb61887eac44fc18
--- /dev/null
+++ b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/Makefile
@@ -0,0 +1,470 @@
+# Makefile for ATmegaBOOT
+# E.Lins, 18.7.2005
+# $Id$
+#
+# Instructions
+#
+# To make bootloader .hex file:
+# make diecimila
+# make lilypad
+# make ng
+# etc...
+#
+# To burn bootloader .hex file:
+# make diecimila_isp
+# make lilypad_isp
+# make ng_isp
+# etc...
+
+# program name should not be changed...
+PROGRAM    = optiboot
+
+# The default behavior is to build using tools that are in the users
+# current path variables, but we can also build using an installed
+# Arduino user IDE setup, or the Arduino source tree.
+# Uncomment this next lines to build within the arduino environment,
+# using the arduino-included avrgcc toolset (mac and pc)
+# ENV ?= arduino
+# ENV ?= arduinodev
+# OS ?= macosx
+# OS ?= windows
+
+
+# enter the parameters for the avrdude isp tool
+ISPTOOL    = stk500v2
+ISPPORT    = usb
+ISPSPEED   = -b 115200
+
+MCU_TARGET = atmega168
+LDSECTIONS  = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
+
+# Build environments
+# Start of some ugly makefile-isms to allow optiboot to be built
+# in several different environments.  See the README.TXT file for
+# details.
+
+# default
+fixpath = $(1)
+
+ifeq ($(ENV), arduino)
+# For Arduino, we assume that we're connected to the optiboot directory
+# included with the arduino distribution, which means that the full set
+# of avr-tools are "right up there" in standard places.
+TOOLROOT = ../../../tools
+GCCROOT = $(TOOLROOT)/avr/bin/
+AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
+
+ifeq ($(OS), windows)
+# On windows, SOME of the tool paths will need to have backslashes instead
+# of forward slashes (because they use windows cmd.exe for execution instead
+# of a unix/mingw shell?)  We also have to ensure that a consistent shell
+# is used even if a unix shell is installed (ie as part of WINAVR)
+fixpath = $(subst /,\,$1)
+SHELL = cmd.exe
+endif
+
+else ifeq ($(ENV), arduinodev)
+# Arduino IDE source code environment.  Use the unpacked compilers created
+# by the build (you'll need to do "ant build" first.)
+ifeq ($(OS), macosx)
+TOOLROOT = ../../../../build/macosx/work/Arduino.app/Contents/Resources/Java/hardware/tools
+endif
+ifeq ($(OS), windows)
+TOOLROOT = ../../../../build/windows/work/hardware/tools
+endif
+
+GCCROOT = $(TOOLROOT)/avr/bin/
+AVRDUDE_CONF = -C$(TOOLROOT)/avr/etc/avrdude.conf
+
+else
+GCCROOT =
+AVRDUDE_CONF =
+endif
+#
+# End of build environment code.
+
+
+# the efuse should really be 0xf8; since, however, only the lower
+# three bits of that byte are used on the atmega168, avrdude gets
+# confused if you specify 1's for the higher bits, see:
+# http://tinker.it/now/2007/02/24/the-tale-of-avrdude-atmega168-and-extended-bits-fuses/
+#
+# similarly, the lock bits should be 0xff instead of 0x3f (to
+# unlock the bootloader section) and 0xcf instead of 0x2f (to
+# lock it), but since the high two bits of the lock byte are
+# unused, avrdude would get confused.
+
+ISPFUSES    = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
+              -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
+              -e -u -U lock:w:0x3f:m -U efuse:w:0x$(EFUSE):m \
+              -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
+ISPFLASH    = $(GCCROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
+              -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
+              -U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
+
+STK500 = "C:\Program Files\Atmel\AVR Tools\STK500\Stk500.exe"
+STK500-1 = $(STK500) -e -d$(MCU_TARGET) -pf -vf -if$(PROGRAM)_$(TARGET).hex \
+-lFF -LFF -f$(HFUSE)$(LFUSE) -EF8 -ms -q -cUSB -I200kHz -s -wt
+STK500-2 = $(STK500) -d$(MCU_TARGET) -ms -q -lCF -LCF -cUSB -I200kHz -s -wt
+
+OBJ        = $(PROGRAM).o
+OPTIMIZE = -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls
+
+DEFS       = 
+LIBS       =
+
+CC         = $(GCCROOT)avr-gcc
+
+# Override is only needed by avr-lib build system.
+
+override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
+override LDFLAGS       = $(LDSECTIONS) -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib
+
+OBJCOPY        = $(GCCROOT)avr-objcopy
+OBJDUMP        = $(call fixpath,$(GCCROOT)avr-objdump)
+
+SIZE           = $(GCCROOT)avr-size
+
+# Test platforms
+# Virtual boot block test
+virboot328: TARGET = atmega328
+virboot328: MCU_TARGET = atmega328p
+virboot328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DVIRTUAL_BOOT'
+virboot328: AVR_FREQ = 16000000L
+virboot328: LDSECTIONS  = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
+virboot328: $(PROGRAM)_atmega328.hex
+virboot328: $(PROGRAM)_atmega328.lst
+
+# 20MHz clocked platforms
+#
+# These are capable of 230400 baud, or 115200 baud on PC (Arduino Avrdude issue)
+#
+
+pro20: TARGET = pro_20mhz
+pro20: MCU_TARGET = atmega168
+pro20: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+pro20: AVR_FREQ = 20000000L
+pro20: $(PROGRAM)_pro_20mhz.hex
+pro20: $(PROGRAM)_pro_20mhz.lst
+
+pro20_isp: pro20
+pro20_isp: TARGET = pro_20mhz
+# 2.7V brownout
+pro20_isp: HFUSE = DD
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
+pro20_isp: LFUSE = C6
+# 512 byte boot
+pro20_isp: EFUSE = 04
+pro20_isp: isp
+
+# 16MHz clocked platforms
+#
+# These are capable of 230400 baud, or 115200 baud on PC (Arduino Avrdude issue)
+#
+
+pro16: TARGET = pro_16MHz
+pro16: MCU_TARGET = atmega168
+pro16: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+pro16: AVR_FREQ = 16000000L
+pro16: $(PROGRAM)_pro_16MHz.hex
+pro16: $(PROGRAM)_pro_16MHz.lst
+
+pro16_isp: pro16
+pro16_isp: TARGET = pro_16MHz
+# 2.7V brownout
+pro16_isp: HFUSE = DD
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
+pro16_isp: LFUSE = C6
+# 512 byte boot
+pro16_isp: EFUSE = 04
+pro16_isp: isp
+
+# Diecimila, Duemilanove with m168, and NG use identical bootloaders
+# Call it "atmega168" for generality and clarity, keep "diecimila" for
+# backward compatibility of makefile
+#
+atmega168: TARGET = atmega168
+atmega168: MCU_TARGET = atmega168
+atmega168: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+atmega168: AVR_FREQ = 16000000L 
+atmega168: $(PROGRAM)_atmega168.hex
+atmega168: $(PROGRAM)_atmega168.lst
+
+atmega168_isp: atmega168
+atmega168_isp: TARGET = atmega168
+# 2.7V brownout
+atmega168_isp: HFUSE = DD
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega168_isp: LFUSE = FF
+# 512 byte boot
+atmega168_isp: EFUSE = 04
+atmega168_isp: isp
+
+diecimila: TARGET = diecimila
+diecimila: MCU_TARGET = atmega168
+diecimila: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+diecimila: AVR_FREQ = 16000000L 
+diecimila: $(PROGRAM)_diecimila.hex
+diecimila: $(PROGRAM)_diecimila.lst
+
+diecimila_isp: diecimila
+diecimila_isp: TARGET = diecimila
+# 2.7V brownout
+diecimila_isp: HFUSE = DD
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+diecimila_isp: LFUSE = FF
+# 512 byte boot
+diecimila_isp: EFUSE = 04
+diecimila_isp: isp
+
+atmega328: TARGET = atmega328
+atmega328: MCU_TARGET = atmega328p
+atmega328: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+atmega328: AVR_FREQ = 16000000L
+atmega328: LDSECTIONS  = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
+atmega328: $(PROGRAM)_atmega328.hex
+atmega328: $(PROGRAM)_atmega328.lst
+
+atmega328_isp: atmega328
+atmega328_isp: TARGET = atmega328
+atmega328_isp: MCU_TARGET = atmega328p
+# 512 byte boot, SPIEN
+atmega328_isp: HFUSE = DE
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega328_isp: LFUSE = FF
+# 2.7V brownout
+atmega328_isp: EFUSE = 05
+atmega328_isp: isp
+
+atmega1284: TARGET = atmega1284p
+atmega1284: MCU_TARGET = atmega1284p
+atmega1284: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
+atmega1284: AVR_FREQ = 16000000L
+atmega1284: LDSECTIONS  = -Wl,--section-start=.text=0x1fc00
+atmega1284: $(PROGRAM)_atmega1284p.hex
+atmega1284: $(PROGRAM)_atmega1284p.lst
+
+atmega1284_isp: atmega1284
+atmega1284_isp: TARGET = atmega1284p
+atmega1284_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+atmega1284_isp: HFUSE = DE
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega1284_isp: LFUSE = FF
+# 2.7V brownout
+atmega1284_isp: EFUSE = FD
+atmega1284_isp: isp
+
+# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
+#
+sanguino: TARGET = atmega644p
+sanguino: MCU_TARGET = atmega644p
+sanguino: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
+sanguino: AVR_FREQ = 16000000L
+sanguino: LDSECTIONS  = -Wl,--section-start=.text=0xfc00
+sanguino: $(PROGRAM)_atmega644p.hex
+sanguino: $(PROGRAM)_atmega644p.lst
+
+sanguino_isp: sanguino
+sanguino_isp: TARGET = atmega644p
+sanguino_isp: MCU_TARGET = atmega644p
+# 1024 byte boot
+sanguino_isp: HFUSE = DE
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+sanguino_isp: LFUSE = FF
+# 2.7V brownout
+sanguino_isp: EFUSE = 05
+sanguino_isp: isp
+
+# Mega has a minimum boot size of 1024 bytes, so enable extra functions
+#mega: TARGET = atmega1280
+mega: MCU_TARGET = atmega1280
+mega: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' '-DBIGBOOT'
+mega: AVR_FREQ = 16000000L
+mega: LDSECTIONS  = -Wl,--section-start=.text=0x1fc00
+mega: $(PROGRAM)_atmega1280.hex
+mega: $(PROGRAM)_atmega1280.lst
+
+mega_isp: mega
+mega_isp: TARGET = atmega1280
+mega_isp: MCU_TARGET = atmega1280
+# 1024 byte boot
+mega_isp: HFUSE = DE
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+mega_isp: LFUSE = FF
+# 2.7V brownout
+mega_isp: EFUSE = 05
+mega_isp: isp
+
+# ATmega8
+#
+atmega8: TARGET = atmega8
+atmega8: MCU_TARGET = atmega8
+atmega8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+atmega8: AVR_FREQ = 16000000L 
+atmega8: LDSECTIONS  = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
+atmega8: $(PROGRAM)_atmega8.hex
+atmega8: $(PROGRAM)_atmega8.lst
+
+atmega8_isp: atmega8
+atmega8_isp: TARGET = atmega8
+atmega8_isp: MCU_TARGET = atmega8
+# SPIEN, CKOPT, Bootsize=512B
+atmega8_isp: HFUSE = CC
+# 2.7V brownout, Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega8_isp: LFUSE = BF
+atmega8_isp: isp
+
+# ATmega88
+#
+atmega88: TARGET = atmega88
+atmega88: MCU_TARGET = atmega88
+atmega88: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+atmega88: AVR_FREQ = 16000000L 
+atmega88: LDSECTIONS  = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe
+atmega88: $(PROGRAM)_atmega88.hex
+atmega88: $(PROGRAM)_atmega88.lst
+
+atmega88_isp: atmega88
+atmega88_isp: TARGET = atmega88
+atmega88_isp: MCU_TARGET = atmega88
+# 2.7V brownout
+atmega88_isp: HFUSE = DD
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atemga88_isp: LFUSE = FF
+# 512 byte boot
+atmega88_isp: EFUSE = 04
+atmega88_isp: isp
+
+
+# 8MHz clocked platforms
+#
+# These are capable of 115200 baud
+#
+
+lilypad: TARGET = lilypad
+lilypad: MCU_TARGET = atmega168
+lilypad: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+lilypad: AVR_FREQ = 8000000L
+lilypad: $(PROGRAM)_lilypad.hex
+lilypad: $(PROGRAM)_lilypad.lst
+
+lilypad_isp: lilypad
+lilypad_isp: TARGET = lilypad
+# 2.7V brownout
+lilypad_isp: HFUSE = DD
+# Internal 8MHz osc (8MHz) Slow rising power
+lilypad_isp: LFUSE = E2
+# 512 byte boot
+lilypad_isp: EFUSE = 04
+lilypad_isp: isp
+
+lilypad_resonator: TARGET = lilypad_resonator
+lilypad_resonator: MCU_TARGET = atmega168
+lilypad_resonator: CFLAGS += '-DLED_START_FLASHES=3' '-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
+# 2.7V brownout
+lilypad_resonator_isp: HFUSE = DD
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
+lilypad_resonator_isp: LFUSE = C6
+# 512 byte boot
+lilypad_resonator_isp: EFUSE = 04
+lilypad_resonator_isp: isp
+
+pro8: TARGET = pro_8MHz
+pro8: MCU_TARGET = atmega168
+pro8: CFLAGS += '-DLED_START_FLASHES=3' '-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
+# 2.7V brownout
+pro8_isp: HFUSE = DD
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
+pro8_isp: LFUSE = C6
+# 512 byte boot
+pro8_isp: EFUSE = 04
+pro8_isp: isp
+
+atmega328_pro8: TARGET = atmega328_pro_8MHz
+atmega328_pro8: MCU_TARGET = atmega328p
+atmega328_pro8: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
+atmega328_pro8: AVR_FREQ = 8000000L
+atmega328_pro8: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
+atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.hex
+atmega328_pro8: $(PROGRAM)_atmega328_pro_8MHz.lst
+
+atmega328_pro8_isp: atmega328_pro8
+atmega328_pro8_isp: TARGET = atmega328_pro_8MHz
+atmega328_pro8_isp: MCU_TARGET = atmega328p
+# 512 byte boot, SPIEN
+atmega328_pro8_isp: HFUSE = DE
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega328_pro8_isp: LFUSE = FF
+# 2.7V brownout
+atmega328_pro8_isp: EFUSE = 05
+atmega328_pro8_isp: isp
+
+# 1MHz clocked platforms
+#
+# These are capable of 9600 baud
+#
+
+luminet: TARGET = luminet
+luminet: MCU_TARGET = attiny84
+luminet: CFLAGS += '-DLED_START_FLASHES=3' '-DSOFT_UART' '-DBAUD_RATE=9600'
+luminet: CFLAGS += '-DVIRTUAL_BOOT_PARTITION'
+luminet: AVR_FREQ = 1000000L
+luminet: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1efe
+luminet: $(PROGRAM)_luminet.hex
+luminet: $(PROGRAM)_luminet.lst
+
+luminet_isp: luminet
+luminet_isp: TARGET = luminet
+luminet_isp: MCU_TARGET = attiny84
+# Brownout disabled
+luminet_isp: HFUSE = DF
+# 1MHz internal oscillator, slowly rising power
+luminet_isp: LFUSE = 62
+# Self-programming enable
+luminet_isp: EFUSE = FE
+luminet_isp: isp
+
+#
+# Generic build instructions
+#
+#
+
+isp: $(TARGET)
+        $(ISPFUSES)
+        $(ISPFLASH)
+
+isp-stk500: $(PROGRAM)_$(TARGET).hex
+        $(STK500-1)
+        $(STK500-2)
+
+%.elf: $(OBJ)
+        $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)
+        $(SIZE) $@
+
+clean:
+        rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex
+
+%.lst: %.elf
+        $(OBJDUMP) -h -S $< > $@
+
+%.hex: %.elf
+        $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@
+
+%.srec: %.elf
+        $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@
+
+%.bin: %.elf
+        $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@
\ No newline at end of file
diff --git a/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/boot.h b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/boot.h
new file mode 100644
index 0000000000000000000000000000000000000000..136273a23ba50444f58d7efb47e6b7bb6bb07bcf
--- /dev/null
+++ b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/boot.h
@@ -0,0 +1,848 @@
+/* Modified to use out for SPM access
+** Peter Knight, Optiboot project http://optiboot.googlecode.com
+**
+** Todo: Tidy up
+**
+** "_short" routines execute 1 cycle faster and use 1 less word of flash
+** by using "out" instruction instead of "sts".
+**
+** Additional elpm variants that trust the value of RAMPZ
+*/
+
+/* Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007  Eric B. Weddington
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id: boot.h,v 1.27.2.3 2008/09/30 13:58:48 arcanum Exp $ */
+
+#ifndef _AVR_BOOT_H_
+#define _AVR_BOOT_H_    1
+
+/** \file */
+/** \defgroup avr_boot <avr/boot.h>: Bootloader Support Utilities
+    \code
+    #include <avr/io.h>
+    #include <avr/boot.h>
+    \endcode
+
+    The macros in this module provide a C language interface to the
+    bootloader support functionality of certain AVR processors. These
+    macros are designed to work with all sizes of flash memory.
+
+    Global interrupts are not automatically disabled for these macros. It
+    is left up to the programmer to do this. See the code example below. 
+    Also see the processor datasheet for caveats on having global interrupts 
+    enabled during writing of the Flash.
+
+    \note Not all AVR processors provide bootloader support. See your
+    processor datasheet to see if it provides bootloader support.
+
+    \todo From email with Marek: On smaller devices (all except ATmega64/128),
+    __SPM_REG is in the I/O space, accessible with the shorter "in" and "out"
+    instructions - since the boot loader has a limited size, this could be an
+    important optimization.
+
+    \par API Usage Example
+    The following code shows typical usage of the boot API.
+
+    \code
+    #include <inttypes.h>
+    #include <avr/interrupt.h>
+    #include <avr/pgmspace.h>
+    
+    void boot_program_page (uint32_t page, uint8_t *buf)
+    {
+        uint16_t i;
+        uint8_t sreg;
+
+        // Disable interrupts.
+
+        sreg = SREG;
+        cli();
+    
+        eeprom_busy_wait ();
+
+        boot_page_erase (page);
+        boot_spm_busy_wait ();      // Wait until the memory is erased.
+
+        for (i=0; i<SPM_PAGESIZE; i+=2)
+        {
+            // Set up little-endian word.
+
+            uint16_t w = *buf++;
+            w += (*buf++) << 8;
+        
+            boot_page_fill (page + i, w);
+        }
+
+        boot_page_write (page);     // Store buffer in flash page.
+        boot_spm_busy_wait();       // Wait until the memory is written.
+
+        // Reenable RWW-section again. We need this if we want to jump back
+        // to the application after bootloading.
+
+        boot_rww_enable ();
+
+        // Re-enable interrupts (if they were ever enabled).
+
+        SREG = sreg;
+    }\endcode */
+
+#include <avr/eeprom.h>
+#include <avr/io.h>
+#include <inttypes.h>
+#include <limits.h>
+
+/* Check for SPM Control Register in processor. */
+#if defined (SPMCSR)
+#  define __SPM_REG    SPMCSR
+#elif defined (SPMCR)
+#  define __SPM_REG    SPMCR
+#else
+#  error AVR processor does not provide bootloader support!
+#endif
+
+
+/* Check for SPM Enable bit. */
+#if defined(SPMEN)
+#  define __SPM_ENABLE  SPMEN
+#elif defined(SELFPRGEN)
+#  define __SPM_ENABLE  SELFPRGEN
+#else
+#  error Cannot find SPM Enable bit definition!
+#endif
+
+/** \ingroup avr_boot
+    \def BOOTLOADER_SECTION
+
+    Used to declare a function or variable to be placed into a
+    new section called .bootloader. This section and its contents
+    can then be relocated to any address (such as the bootloader
+    NRWW area) at link-time. */
+
+#define BOOTLOADER_SECTION    __attribute__ ((section (".bootloader")))
+
+/* Create common bit definitions. */
+#ifdef ASB
+#define __COMMON_ASB    ASB
+#else
+#define __COMMON_ASB    RWWSB
+#endif
+
+#ifdef ASRE
+#define __COMMON_ASRE   ASRE
+#else
+#define __COMMON_ASRE   RWWSRE
+#endif
+
+/* Define the bit positions of the Boot Lock Bits. */
+
+#define BLB12           5
+#define BLB11           4
+#define BLB02           3
+#define BLB01           2
+
+/** \ingroup avr_boot
+    \def boot_spm_interrupt_enable()
+    Enable the SPM interrupt. */
+
+#define boot_spm_interrupt_enable()   (__SPM_REG |= (uint8_t)_BV(SPMIE))
+
+/** \ingroup avr_boot
+    \def boot_spm_interrupt_disable()
+    Disable the SPM interrupt. */
+
+#define boot_spm_interrupt_disable()  (__SPM_REG &= (uint8_t)~_BV(SPMIE))
+
+/** \ingroup avr_boot
+    \def boot_is_spm_interrupt()
+    Check if the SPM interrupt is enabled. */
+
+#define boot_is_spm_interrupt()       (__SPM_REG & (uint8_t)_BV(SPMIE))
+
+/** \ingroup avr_boot
+    \def boot_rww_busy()
+    Check if the RWW section is busy. */
+
+#define boot_rww_busy()          (__SPM_REG & (uint8_t)_BV(__COMMON_ASB))
+
+/** \ingroup avr_boot
+    \def boot_spm_busy()
+    Check if the SPM instruction is busy. */
+
+#define boot_spm_busy()               (__SPM_REG & (uint8_t)_BV(__SPM_ENABLE))
+
+/** \ingroup avr_boot
+    \def boot_spm_busy_wait()
+    Wait while the SPM instruction is busy. */
+
+#define boot_spm_busy_wait()          do{}while(boot_spm_busy())
+
+#define __BOOT_PAGE_ERASE         (_BV(__SPM_ENABLE) | _BV(PGERS))
+#define __BOOT_PAGE_WRITE         (_BV(__SPM_ENABLE) | _BV(PGWRT))
+#define __BOOT_PAGE_FILL          _BV(__SPM_ENABLE)
+#define __BOOT_RWW_ENABLE         (_BV(__SPM_ENABLE) | _BV(__COMMON_ASRE))
+#define __BOOT_LOCK_BITS_SET      (_BV(__SPM_ENABLE) | _BV(BLBSET))
+
+#define __boot_page_fill_short(address, data)   \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw  r0, %3\n\t"                       \
+        "out %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        "clr  r1\n\t"                            \
+        :                                        \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
+          "z" ((uint16_t)address),               \
+          "r" ((uint16_t)data)                   \
+        : "r0"                                   \
+    );                                           \
+}))
+
+#define __boot_page_fill_normal(address, data)   \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw  r0, %3\n\t"                       \
+        "sts %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        "clr  r1\n\t"                            \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
+          "z" ((uint16_t)address),               \
+          "r" ((uint16_t)data)                   \
+        : "r0"                                   \
+    );                                           \
+}))
+
+#define __boot_page_fill_alternate(address, data)\
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw  r0, %3\n\t"                       \
+        "sts %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        ".word 0xffff\n\t"                       \
+        "nop\n\t"                                \
+        "clr  r1\n\t"                            \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
+          "z" ((uint16_t)address),               \
+          "r" ((uint16_t)data)                   \
+        : "r0"                                   \
+    );                                           \
+}))
+
+#define __boot_page_fill_extended(address, data) \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw  r0, %4\n\t"                       \
+        "movw r30, %A3\n\t"                      \
+        "sts %1, %C3\n\t"                        \
+        "sts %0, %2\n\t"                         \
+        "spm\n\t"                                \
+        "clr  r1\n\t"                            \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "i" (_SFR_MEM_ADDR(RAMPZ)),            \
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
+          "r" ((uint32_t)address),               \
+          "r" ((uint16_t)data)                   \
+        : "r0", "r30", "r31"                     \
+    );                                           \
+}))
+
+#define __boot_page_fill_extended_short(address, data) \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw  r0, %4\n\t"                       \
+        "movw r30, %A3\n\t"                      \
+        "out %1, %C3\n\t"                        \
+        "out %0, %2\n\t"                         \
+        "spm\n\t"                                \
+        "clr  r1\n\t"                            \
+        :                                        \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
+          "i" (_SFR_IO_ADDR(RAMPZ)),            \
+          "r" ((uint8_t)__BOOT_PAGE_FILL),       \
+          "r" ((uint32_t)address),               \
+          "r" ((uint16_t)data)                   \
+        : "r0", "r30", "r31"                     \
+    );                                           \
+}))
+
+#define __boot_page_erase_short(address)        \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "out %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
+          "z" ((uint16_t)address)                \
+    );                                           \
+}))
+
+
+#define __boot_page_erase_normal(address)        \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "sts %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
+          "z" ((uint16_t)address)                \
+    );                                           \
+}))
+
+#define __boot_page_erase_alternate(address)     \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "sts %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        ".word 0xffff\n\t"                       \
+        "nop\n\t"                                \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
+          "z" ((uint16_t)address)                \
+    );                                           \
+}))
+
+#define __boot_page_erase_extended(address)      \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw r30, %A3\n\t"                      \
+        "sts  %1, %C3\n\t"                       \
+        "sts %0, %2\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "i" (_SFR_MEM_ADDR(RAMPZ)),            \
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
+          "r" ((uint32_t)address)                \
+        : "r30", "r31"                           \
+    );                                           \
+}))
+#define __boot_page_erase_extended_short(address)      \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw r30, %A3\n\t"                      \
+        "out  %1, %C3\n\t"                       \
+        "out %0, %2\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
+          "i" (_SFR_IO_ADDR(RAMPZ)),            \
+          "r" ((uint8_t)__BOOT_PAGE_ERASE),      \
+          "r" ((uint32_t)address)                \
+        : "r30", "r31"                           \
+    );                                           \
+}))
+
+#define __boot_page_write_short(address)        \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "out %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
+          "z" ((uint16_t)address)                \
+    );                                           \
+}))
+
+#define __boot_page_write_normal(address)        \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "sts %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
+          "z" ((uint16_t)address)                \
+    );                                           \
+}))
+
+#define __boot_page_write_alternate(address)     \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "sts %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        ".word 0xffff\n\t"                       \
+        "nop\n\t"                                \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
+          "z" ((uint16_t)address)                \
+    );                                           \
+}))
+
+#define __boot_page_write_extended(address)      \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw r30, %A3\n\t"                      \
+        "sts %1, %C3\n\t"                        \
+        "sts %0, %2\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "i" (_SFR_MEM_ADDR(RAMPZ)),            \
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
+          "r" ((uint32_t)address)                \
+        : "r30", "r31"                           \
+    );                                           \
+}))
+#define __boot_page_write_extended_short(address)      \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "movw r30, %A3\n\t"                      \
+        "out %1, %C3\n\t"                        \
+        "out %0, %2\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
+          "i" (_SFR_IO_ADDR(RAMPZ)),            \
+          "r" ((uint8_t)__BOOT_PAGE_WRITE),      \
+          "r" ((uint32_t)address)                \
+        : "r30", "r31"                           \
+    );                                           \
+}))
+
+#define __boot_rww_enable_short()                      \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "out %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_RWW_ENABLE)       \
+    );                                           \
+}))
+
+#define __boot_rww_enable()                      \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "sts %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_RWW_ENABLE)       \
+    );                                           \
+}))
+
+#define __boot_rww_enable_alternate()            \
+(__extension__({                                 \
+    __asm__ __volatile__                         \
+    (                                            \
+        "sts %0, %1\n\t"                         \
+        "spm\n\t"                                \
+        ".word 0xffff\n\t"                       \
+        "nop\n\t"                                \
+        :                                        \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t)__BOOT_RWW_ENABLE)       \
+    );                                           \
+}))
+
+/* From the mega16/mega128 data sheets (maybe others):
+
+     Bits by SPM To set the Boot Loader Lock bits, write the desired data to
+     R0, write "X0001001" to SPMCR and execute SPM within four clock cycles
+     after writing SPMCR. The only accessible Lock bits are the Boot Lock bits
+     that may prevent the Application and Boot Loader section from any
+     software update by the MCU.
+
+     If bits 5..2 in R0 are cleared (zero), the corresponding Boot Lock bit
+     will be programmed if an SPM instruction is executed within four cycles
+     after BLBSET and SPMEN (or SELFPRGEN) are set in SPMCR. The Z-pointer is 
+     don't care during this operation, but for future compatibility it is 
+     recommended to load the Z-pointer with $0001 (same as used for reading the 
+     Lock bits). For future compatibility It is also recommended to set bits 7, 
+     6, 1, and 0 in R0 to 1 when writing the Lock bits. When programming the 
+     Lock bits the entire Flash can be read during the operation. */
+
+#define __boot_lock_bits_set_short(lock_bits)                    \
+(__extension__({                                           \
+    uint8_t value = (uint8_t)(~(lock_bits));               \
+    __asm__ __volatile__                                   \
+    (                                                      \
+        "ldi r30, 1\n\t"                                   \
+        "ldi r31, 0\n\t"                                   \
+        "mov r0, %2\n\t"                                   \
+        "out %0, %1\n\t"                                   \
+        "spm\n\t"                                          \
+        :                                                  \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),                  \
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
+          "r" (value)                                      \
+        : "r0", "r30", "r31"                               \
+    );                                                     \
+}))
+
+#define __boot_lock_bits_set(lock_bits)                    \
+(__extension__({                                           \
+    uint8_t value = (uint8_t)(~(lock_bits));               \
+    __asm__ __volatile__                                   \
+    (                                                      \
+        "ldi r30, 1\n\t"                                   \
+        "ldi r31, 0\n\t"                                   \
+        "mov r0, %2\n\t"                                   \
+        "sts %0, %1\n\t"                                   \
+        "spm\n\t"                                          \
+        :                                                  \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
+          "r" (value)                                      \
+        : "r0", "r30", "r31"                               \
+    );                                                     \
+}))
+
+#define __boot_lock_bits_set_alternate(lock_bits)          \
+(__extension__({                                           \
+    uint8_t value = (uint8_t)(~(lock_bits));               \
+    __asm__ __volatile__                                   \
+    (                                                      \
+        "ldi r30, 1\n\t"                                   \
+        "ldi r31, 0\n\t"                                   \
+        "mov r0, %2\n\t"                                   \
+        "sts %0, %1\n\t"                                   \
+        "spm\n\t"                                          \
+        ".word 0xffff\n\t"                                 \
+        "nop\n\t"                                          \
+        :                                                  \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
+          "r" (value)                                      \
+        : "r0", "r30", "r31"                               \
+    );                                                     \
+}))
+
+/*
+   Reading lock and fuse bits:
+
+     Similarly to writing the lock bits above, set BLBSET and SPMEN (or 
+     SELFPRGEN) bits in __SPMREG, and then (within four clock cycles) issue an 
+     LPM instruction.
+
+     Z address:       contents:
+     0x0000           low fuse bits
+     0x0001           lock bits
+     0x0002           extended fuse bits
+     0x0003           high fuse bits
+
+     Sounds confusing, doesn't it?
+
+     Unlike the macros in pgmspace.h, no need to care for non-enhanced
+     cores here as these old cores do not provide SPM support anyway.
+ */
+
+/** \ingroup avr_boot
+    \def GET_LOW_FUSE_BITS
+    address to read the low fuse bits, using boot_lock_fuse_bits_get
+ */
+#define GET_LOW_FUSE_BITS           (0x0000)
+/** \ingroup avr_boot
+    \def GET_LOCK_BITS
+    address to read the lock bits, using boot_lock_fuse_bits_get
+ */
+#define GET_LOCK_BITS               (0x0001)
+/** \ingroup avr_boot
+    \def GET_EXTENDED_FUSE_BITS
+    address to read the extended fuse bits, using boot_lock_fuse_bits_get
+ */
+#define GET_EXTENDED_FUSE_BITS      (0x0002)
+/** \ingroup avr_boot
+    \def GET_HIGH_FUSE_BITS
+    address to read the high fuse bits, using boot_lock_fuse_bits_get
+ */
+#define GET_HIGH_FUSE_BITS          (0x0003)
+
+/** \ingroup avr_boot
+    \def boot_lock_fuse_bits_get(address)
+
+    Read the lock or fuse bits at \c address.
+
+    Parameter \c address can be any of GET_LOW_FUSE_BITS,
+    GET_LOCK_BITS, GET_EXTENDED_FUSE_BITS, or GET_HIGH_FUSE_BITS.
+
+    \note The lock and fuse bits returned are the physical values,
+    i.e. a bit returned as 0 means the corresponding fuse or lock bit
+    is programmed.
+ */
+#define boot_lock_fuse_bits_get_short(address)                   \
+(__extension__({                                           \
+    uint8_t __result;                                      \
+    __asm__ __volatile__                                   \
+    (                                                      \
+        "ldi r30, %3\n\t"                                  \
+        "ldi r31, 0\n\t"                                   \
+        "out %1, %2\n\t"                                   \
+        "lpm %0, Z\n\t"                                    \
+        : "=r" (__result)                                  \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),                  \
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
+          "M" (address)                                    \
+        : "r0", "r30", "r31"                               \
+    );                                                     \
+    __result;                                              \
+}))
+
+#define boot_lock_fuse_bits_get(address)                   \
+(__extension__({                                           \
+    uint8_t __result;                                      \
+    __asm__ __volatile__                                   \
+    (                                                      \
+        "ldi r30, %3\n\t"                                  \
+        "ldi r31, 0\n\t"                                   \
+        "sts %1, %2\n\t"                                   \
+        "lpm %0, Z\n\t"                                    \
+        : "=r" (__result)                                  \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),                  \
+          "r" ((uint8_t)__BOOT_LOCK_BITS_SET),             \
+          "M" (address)                                    \
+        : "r0", "r30", "r31"                               \
+    );                                                     \
+    __result;                                              \
+}))
+
+/** \ingroup avr_boot
+    \def boot_signature_byte_get(address)
+
+    Read the Signature Row byte at \c address.  For some MCU types,
+    this function can also retrieve the factory-stored oscillator
+    calibration bytes.
+
+    Parameter \c address can be 0-0x1f as documented by the datasheet.
+    \note The values are MCU type dependent.
+*/
+
+#define __BOOT_SIGROW_READ (_BV(__SPM_ENABLE) | _BV(SIGRD))
+
+#define boot_signature_byte_get_short(addr) \
+(__extension__({                      \
+      uint16_t __addr16 = (uint16_t)(addr);     \
+      uint8_t __result;                         \
+      __asm__ __volatile__                      \
+      (                                         \
+        "out %1, %2\n\t"                        \
+        "lpm %0, Z" "\n\t"                      \
+        : "=r" (__result)                       \
+        : "i" (_SFR_IO_ADDR(__SPM_REG)),        \
+          "r" ((uint8_t) __BOOT_SIGROW_READ),   \
+          "z" (__addr16)                        \
+      );                                        \
+      __result;                                 \
+}))
+
+#define boot_signature_byte_get(addr) \
+(__extension__({                      \
+      uint16_t __addr16 = (uint16_t)(addr);     \
+      uint8_t __result;                         \
+      __asm__ __volatile__                      \
+      (                                         \
+        "sts %1, %2\n\t"                        \
+        "lpm %0, Z" "\n\t"                      \
+        : "=r" (__result)                       \
+        : "i" (_SFR_MEM_ADDR(__SPM_REG)),       \
+          "r" ((uint8_t) __BOOT_SIGROW_READ),   \
+          "z" (__addr16)                        \
+      );                                        \
+      __result;                                 \
+}))
+
+/** \ingroup avr_boot
+    \def boot_page_fill(address, data)
+
+    Fill the bootloader temporary page buffer for flash 
+    address with data word. 
+
+    \note The address is a byte address. The data is a word. The AVR 
+    writes data to the buffer a word at a time, but addresses the buffer
+    per byte! So, increment your address by 2 between calls, and send 2
+    data bytes in a word format! The LSB of the data is written to the lower 
+    address; the MSB of the data is written to the higher address.*/
+
+/** \ingroup avr_boot
+    \def boot_page_erase(address)
+
+    Erase the flash page that contains address.
+
+    \note address is a byte address in flash, not a word address. */
+
+/** \ingroup avr_boot
+    \def boot_page_write(address)
+
+    Write the bootloader temporary page buffer 
+    to flash page that contains address.
+    
+    \note address is a byte address in flash, not a word address. */
+
+/** \ingroup avr_boot
+    \def boot_rww_enable()
+
+    Enable the Read-While-Write memory section. */
+
+/** \ingroup avr_boot
+    \def boot_lock_bits_set(lock_bits)
+
+    Set the bootloader lock bits.
+
+    \param lock_bits A mask of which Boot Loader Lock Bits to set.
+
+    \note In this context, a 'set bit' will be written to a zero value.
+    Note also that only BLBxx bits can be programmed by this command.
+
+    For example, to disallow the SPM instruction from writing to the Boot
+    Loader memory section of flash, you would use this macro as such:
+
+    \code
+    boot_lock_bits_set (_BV (BLB11));
+    \endcode
+
+    \note Like any lock bits, the Boot Loader Lock Bits, once set,
+    cannot be cleared again except by a chip erase which will in turn
+    also erase the boot loader itself. */
+
+/* Normal versions of the macros use 16-bit addresses.
+   Extended versions of the macros use 32-bit addresses.
+   Alternate versions of the macros use 16-bit addresses and require special
+   instruction sequences after LPM.
+
+   FLASHEND is defined in the ioXXXX.h file.
+   USHRT_MAX is defined in <limits.h>. */ 
+
+#if defined(__AVR_ATmega161__) || defined(__AVR_ATmega163__) \
+    || defined(__AVR_ATmega323__)
+
+/* Alternate: ATmega161/163/323 and 16 bit address */
+#define boot_page_fill(address, data) __boot_page_fill_alternate(address, data)
+#define boot_page_erase(address)      __boot_page_erase_alternate(address)
+#define boot_page_write(address)      __boot_page_write_alternate(address)
+#define boot_rww_enable()             __boot_rww_enable_alternate()
+#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_alternate(lock_bits)
+
+#elif (FLASHEND > USHRT_MAX)
+
+/* Extended: >16 bit address */
+#define boot_page_fill(address, data) __boot_page_fill_extended_short(address, data)
+#define boot_page_erase(address)      __boot_page_erase_extended_short(address)
+#define boot_page_write(address)      __boot_page_write_extended_short(address)
+#define boot_rww_enable()             __boot_rww_enable_short()
+#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits)
+
+#else
+
+/* Normal: 16 bit address */
+#define boot_page_fill(address, data) __boot_page_fill_short(address, data)
+#define boot_page_erase(address)      __boot_page_erase_short(address)
+#define boot_page_write(address)      __boot_page_write_short(address)
+#define boot_rww_enable()             __boot_rww_enable_short()
+#define boot_lock_bits_set(lock_bits) __boot_lock_bits_set_short(lock_bits)
+
+#endif
+
+/** \ingroup avr_boot
+
+    Same as boot_page_fill() except it waits for eeprom and spm operations to
+    complete before filling the page. */
+
+#define boot_page_fill_safe(address, data) \
+do { \
+    boot_spm_busy_wait();                       \
+    eeprom_busy_wait();                         \
+    boot_page_fill(address, data);              \
+} while (0)
+
+/** \ingroup avr_boot
+
+    Same as boot_page_erase() except it waits for eeprom and spm operations to
+    complete before erasing the page. */
+
+#define boot_page_erase_safe(address) \
+do { \
+    boot_spm_busy_wait();                       \
+    eeprom_busy_wait();                         \
+    boot_page_erase (address);                  \
+} while (0)
+
+/** \ingroup avr_boot
+
+    Same as boot_page_write() except it waits for eeprom and spm operations to
+    complete before writing the page. */
+
+#define boot_page_write_safe(address) \
+do { \
+    boot_spm_busy_wait();                       \
+    eeprom_busy_wait();                         \
+    boot_page_write (address);                  \
+} while (0)
+
+/** \ingroup avr_boot
+
+    Same as boot_rww_enable() except waits for eeprom and spm operations to
+    complete before enabling the RWW mameory. */
+
+#define boot_rww_enable_safe() \
+do { \
+    boot_spm_busy_wait();                       \
+    eeprom_busy_wait();                         \
+    boot_rww_enable();                          \
+} while (0)
+
+/** \ingroup avr_boot
+
+    Same as boot_lock_bits_set() except waits for eeprom and spm operations to
+    complete before setting the lock bits. */
+
+#define boot_lock_bits_set_safe(lock_bits) \
+do { \
+    boot_spm_busy_wait();                       \
+    eeprom_busy_wait();                         \
+    boot_lock_bits_set (lock_bits);             \
+} while (0)
+
+#endif /* _AVR_BOOT_H_ */
\ No newline at end of file
diff --git a/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/optiboot.c b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/optiboot.c
new file mode 100644
index 0000000000000000000000000000000000000000..031869612fe241321485ebd85447f837c8faa660
--- /dev/null
+++ b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/optiboot.c
@@ -0,0 +1,724 @@
+/**********************************************************/
+/* -Wl,-section-start=bootloader=0x1fc00 */
+/* Optiboot bootloader for Arduino                        */
+/*                                                        */
+/* http://optiboot.googlecode.com                         */
+/*                                                        */
+/* Arduino-maintained version : See README.TXT            */
+/* http://code.google.com/p/arduino/                      */
+/*                                                        */
+/* Heavily optimised bootloader that is faster and        */
+/* smaller than the Arduino standard bootloader           */
+/*                                                        */
+/* Enhancements:                                          */
+/*   Fits in 512 bytes, saving 1.5K of code space         */
+/*   Background page erasing speeds up programming        */
+/*   Higher baud rate speeds up programming               */
+/*   Written almost entirely in C                         */
+/*   Customisable timeout with accurate timeconstant      */
+/*   Optional virtual UART. No hardware UART required.    */
+/*   Optional virtual boot partition for devices without. */
+/*                                                        */
+/* What you lose:                                         */
+/*   Implements a skeleton STK500 protocol which is       */
+/*     missing several features including EEPROM          */
+/*     programming and non-page-aligned writes            */
+/*   High baud rate breaks compatibility with standard    */
+/*     Arduino flash settings                             */
+/*                                                        */
+/* Fully supported:                                       */
+/*   ATmega168 based devices  (Diecimila etc)             */
+/*   ATmega328P based devices (Duemilanove etc)           */
+/*                                                        */
+/* Alpha test                                             */
+/*   ATmega1280 based devices (Arduino Mega)              */
+/*                                                        */
+/* Work in progress:                                      */
+/*   ATmega644P based devices (Sanguino)                  */
+/*   ATtiny84 based devices (Luminet)                     */
+/*                                                        */
+/* Does not support:                                      */
+/*   USB based devices (eg. Teensy)                       */
+/*                                                        */
+/* Assumptions:                                           */
+/*   The code makes several assumptions that reduce the   */
+/*   code size. They are all true after a hardware reset, */
+/*   but may not be true if the bootloader is called by   */
+/*   other means or on other hardware.                    */
+/*     No interrupts can occur                            */
+/*     UART and Timer 1 are set to their reset state      */
+/*     SP points to RAMEND                                */
+/*                                                        */
+/* Code builds on code, libraries and optimisations from: */
+/*   stk500boot.c          by Jason P. Kyle               */
+/*   Arduino bootloader    http://arduino.cc              */
+/*   Spiff's 1K bootloader http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml */
+/*   avr-libc project      http://nongnu.org/avr-libc     */
+/*   Adaboot               http://www.ladyada.net/library/arduino/bootloader.html */
+/*   AVR305                Atmel Application Note         */
+/*                                                        */
+/* This program is free software; you can redistribute it */
+/* and/or modify it under the terms of the GNU General    */
+/* Public License as published by the Free Software       */
+/* Foundation; either version 2 of the License, or        */
+/* (at your option) any later version.                    */
+/*                                                        */
+/* This program is distributed in the hope that it will   */
+/* be useful, but WITHOUT ANY WARRANTY; without even the  */
+/* implied warranty of MERCHANTABILITY or FITNESS FOR A   */
+/* PARTICULAR PURPOSE.  See the GNU General Public        */
+/* License for more details.                              */
+/*                                                        */
+/* You should have received a copy of the GNU General     */
+/* Public License along with this program; if not, write  */
+/* to the Free Software Foundation, Inc.,                 */
+/* 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA */
+/*                                                        */
+/* Licence can be viewed at                               */
+/* http://www.fsf.org/licenses/gpl.txt                    */
+/*                                                        */
+/**********************************************************/
+
+
+/**********************************************************/
+/*                                                        */
+/* Optional defines:                                      */
+/*                                                        */
+/**********************************************************/
+/*                                                        */
+/* BIG_BOOT:                                              */
+/* Build a 1k bootloader, not 512 bytes. This turns on    */
+/* extra functionality.                                   */
+/*                                                        */
+/* BAUD_RATE:                                             */
+/* Set bootloader baud rate.                              */
+/*                                                        */
+/* LUDICROUS_SPEED:                                       */
+/* 230400 baud :-)                                        */
+/*                                                        */
+/* SOFT_UART:                                             */
+/* Use AVR305 soft-UART instead of hardware UART.         */
+/*                                                        */
+/* LED_START_FLASHES:                                     */
+/* Number of LED flashes on bootup.                       */
+/*                                                        */
+/* LED_DATA_FLASH:                                        */
+/* Flash LED when transferring data. For boards without   */
+/* TX or RX LEDs, or for people who like blinky lights.   */
+/*                                                        */
+/* SUPPORT_EEPROM:                                        */
+/* Support reading and writing from EEPROM. This is not   */
+/* used by Arduino, so off by default.                    */
+/*                                                        */
+/* TIMEOUT_MS:                                            */
+/* Bootloader timeout period, in milliseconds.            */
+/* 500,1000,2000,4000,8000 supported.                     */
+/*                                                        */
+/**********************************************************/
+
+/**********************************************************/
+/* Version Numbers!                                       */
+/*                                                        */
+/* Arduino Optiboot now includes this Version number in   */
+/* the source and object code.                            */
+/*                                                        */
+/* Version 3 was released as zip from the optiboot        */
+/*  repository and was distributed with Arduino 0022.     */
+/* Version 4 starts with the arduino repository commit    */
+/*  that brought the arduino repository up-to-date with   */
+/* the optiboot source tree changes since v3.             */
+/*                                                        */
+/**********************************************************/
+
+/**********************************************************/
+/* Edit History:                                          */
+/*                                                        */
+/* Jan 2012:                                              */
+/* 4.5 WestfW: fix NRWW value for m1284.                  */
+/* 4.4 WestfW: use attribute OS_main instead of naked for */
+/*             main().  This allows optimizations that we */
+/*             count on, which are prohibited in naked    */
+/*             functions due to PR42240.  (keeps us less  */
+/*             than 512 bytes when compiler is gcc4.5     */
+/*             (code from 4.3.2 remains the same.)        */
+/* 4.4 WestfW and Maniacbug:  Add m1284 support.  This    */
+/*             does not change the 328 binary, so the     */
+/*             version number didn't change either. (?)   */
+/* June 2011:                                             */
+/* 4.4 WestfW: remove automatic soft_uart detect (didn't  */
+/*             know what it was doing or why.)  Added a   */
+/*             check of the calculated BRG value instead. */
+/*             Version stays 4.4; existing binaries are   */
+/*             not changed.                               */
+/* 4.4 WestfW: add initialization of address to keep      */
+/*             the compiler happy.  Change SC'ed targets. */
+/*             Return the SW version via READ PARAM       */
+/* 4.3 WestfW: catch framing errors in getch(), so that   */
+/*             AVRISP works without HW kludges.           */
+/*  http://code.google.com/p/arduino/issues/detail?id=368n*/
+/* 4.2 WestfW: reduce code size, fix timeouts, change     */
+/*             verifySpace to use WDT instead of appstart */
+/* 4.1 WestfW: put version number in binary.              */
+/**********************************************************/
+
+#define OPTIBOOT_MAJVER 4
+#define OPTIBOOT_MINVER 5
+
+#define MAKESTR(a) #a
+#define MAKEVER(a, b) MAKESTR(a*256+b)
+
+asm("  .section .version\n"
+    "optiboot_version:  .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
+    "  .section .text\n");
+
+#include <inttypes.h>
+#include <avr/io.h>
+#include <avr/pgmspace.h>
+
+// <avr/boot.h> uses sts instructions, but this version uses out instructions
+// This saves cycles and program memory.
+#include "boot.h"
+
+
+// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.
+
+#include "pin_defs.h"
+#include "stk500.h"
+
+#ifndef LED_START_FLASHES
+#define LED_START_FLASHES 0
+#endif
+
+#ifdef LUDICROUS_SPEED
+#define BAUD_RATE 230400L
+#endif
+
+/* set the UART baud rate defaults */
+#ifndef BAUD_RATE
+#if F_CPU >= 8000000L
+#define BAUD_RATE   115200L // Highest rate Avrdude win32 will support
+#elsif F_CPU >= 1000000L
+#define BAUD_RATE   9600L   // 19200 also supported, but with significant error
+#elsif F_CPU >= 128000L
+#define BAUD_RATE   4800L   // Good for 128kHz internal RC
+#else
+#define BAUD_RATE 1200L     // Good even at 32768Hz
+#endif
+#endif
+
+#if 0
+/* Switch in soft UART for hard baud rates */
+/*
+ * I don't understand what this was supposed to accomplish, where the
+ * constant "280" came from, or why automatically (and perhaps unexpectedly)
+ * switching to a soft uart is a good thing, so I'm undoing this in favor
+ * of a range check using the same calc used to config the BRG...
+ */
+#if (F_CPU/BAUD_RATE) > 280 // > 57600 for 16MHz
+#ifndef SOFT_UART
+#define SOFT_UART
+#endif
+#endif
+#else // 0
+#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 > 250
+#error Unachievable baud rate (too slow) BAUD_RATE 
+#endif // baud rate slow check
+#if (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 < 3
+#error Unachievable baud rate (too fast) BAUD_RATE 
+#endif // baud rate fastn check
+#endif
+
+/* 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))
+#ifndef __AVR_ATmega8__
+#define WATCHDOG_4S     (_BV(WDP3) | _BV(WDE))
+#define WATCHDOG_8S     (_BV(WDP3) | _BV(WDP0) | _BV(WDE))
+#endif
+
+/* Function Prototypes */
+/* 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    */
+/* generate any entry or exit code itself. */
+int main(void) __attribute__ ((OS_main)) __attribute__ ((section (".init9")));
+void putch(char);
+uint8_t getch(void);
+static inline void getNch(uint8_t); /* "static inline" is a compiler hint to reduce code size */
+void verifySpace();
+static inline void flash_led(uint8_t);
+uint8_t getLen();
+static inline void watchdogReset();
+void watchdogConfig(uint8_t x);
+#ifdef SOFT_UART
+void uartDelay() __attribute__ ((naked));
+#endif
+void appStart() __attribute__ ((naked));
+
+/*
+ * NRWW memory
+ * Addresses below NRWW (Non-Read-While-Write) can be programmed while
+ * continuing to run code from flash, slightly speeding up programming
+ * time.  Beware that Atmel data sheets specify this as a WORD address,
+ * while optiboot will be comparing against a 16-bit byte address.  This
+ * means that on a part with 128kB of memory, the upper part of the lower
+ * 64k will get NRWW processing as well, even though it doesn't need it.
+ * That's OK.  In fact, you can disable the overlapping processing for
+ * a part entirely by setting NRWWSTART to zero.  This reduces code
+ * space a bit, at the expense of being slightly slower, overall.
+ *
+ * RAMSTART should be self-explanatory.  It's bigger on parts with a
+ * lot of peripheral registers.
+ */
+#if defined(__AVR_ATmega168__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0x3800)
+#elif defined(__AVR_ATmega328P__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0x7000)
+#elif defined (__AVR_ATmega644P__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0xE000)
+#elif defined (__AVR_ATmega1284P__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0xE000)
+#elif defined(__AVR_ATtiny84__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0x0000)
+#elif defined(__AVR_ATmega1280__)
+#define RAMSTART (0x200)
+#define NRWWSTART (0xE000)
+#elif defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
+#define RAMSTART (0x100)
+#define NRWWSTART (0x1800)
+#endif
+
+/* C zero initialises all global variables. However, that requires */
+/* These definitions are NOT zero initialised, but that doesn't matter */
+/* This allows us to drop the zero init code, saving us memory */
+#define buff    ((uint8_t*)(RAMSTART))
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
+#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+#endif
+
+/* main program starts here */
+int main(void) {
+  uint8_t ch;
+
+  /*
+   * Making these local and in registers prevents the need for initializing
+   * them, and also saves space because code no longer stores to memory.
+   * (initializing address keeps the compiler happy, but isn't really
+   *  necessary, and uses 4 bytes of flash.)
+   */
+  register uint16_t address = 0;
+  register uint8_t  length;
+
+  // After the zero init loop, this is the first code to run.
+  //
+  // This code makes the following assumptions:
+  //  No interrupts will execute
+  //  SP points to RAMEND
+  //  r1 contains zero
+  //
+  // If not, uncomment the following instructions:
+  // cli();
+  asm volatile ("clr __zero_reg__");
+#ifdef __AVR_ATmega8__
+  SP=RAMEND;  // This is done by hardware reset
+#endif
+
+  // Adaboot no-wait mod
+  ch = MCUSR;
+  MCUSR = 0;
+  if (!(ch & _BV(EXTRF))) appStart();
+
+#if LED_START_FLASHES > 0
+  // Set up Timer 1 for timeout counter
+  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+#endif
+#ifndef SOFT_UART
+#ifdef __AVR_ATmega8__
+  UCSRA = _BV(U2X); //Double speed mode USART
+  UCSRB = _BV(RXEN) | _BV(TXEN);  // enable Rx & Tx
+  UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);  // config USART; 8N1
+  UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+#else
+  UCSR0A = _BV(U2X0); //Double speed mode USART0
+  UCSR0B = _BV(RXEN0) | _BV(TXEN0);
+  UCSR0C = _BV(UCSZ00) | _BV(UCSZ01);
+  UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+#endif
+#endif
+
+  // Set up watchdog to trigger after 500ms
+  watchdogConfig(WATCHDOG_1S);
+
+  /* Set LED pin as output */
+  LED_DDR |= _BV(LED);
+
+#ifdef SOFT_UART
+  /* Set TX pin as output */
+  UART_DDR |= _BV(UART_TX_BIT);
+#endif
+
+#if LED_START_FLASHES > 0
+  /* Flash onboard LED to signal entering of bootloader */
+  flash_led(LED_START_FLASHES * 2);
+#endif
+
+  /* Forever loop */
+  for (;;) {
+    /* get character from UART */
+    ch = getch();
+
+    if(ch == STK_GET_PARAMETER) {
+      unsigned char which = getch();
+      verifySpace();
+      if (which == 0x82) {
+        /*
+         * Send optiboot version as "minor SW version"
+         */
+        putch(OPTIBOOT_MINVER);
+      } else if (which == 0x81) {
+          putch(OPTIBOOT_MAJVER);
+      } else {
+        /*
+         * GET PARAMETER returns a generic 0x03 reply for
+         * other parameters - enough to keep Avrdude happy
+         */
+        putch(0x03);
+      }
+    }
+    else if(ch == STK_SET_DEVICE) {
+      // SET DEVICE is ignored
+      getNch(20);
+    }
+    else if(ch == STK_SET_DEVICE_EXT) {
+      // SET DEVICE EXT is ignored
+      getNch(5);
+    }
+    else if(ch == STK_LOAD_ADDRESS) {
+      // LOAD ADDRESS
+      uint16_t newAddress;
+      newAddress = getch();
+      newAddress = (newAddress & 0xff) | (getch() << 8);
+#ifdef RAMPZ
+      // Transfer top bit to RAMPZ
+      RAMPZ = (newAddress & 0x8000) ? 1 : 0;
+#endif
+      newAddress += newAddress; // Convert from word address to byte address
+      address = newAddress;
+      verifySpace();
+    }
+    else if(ch == STK_UNIVERSAL) {
+      // UNIVERSAL command is ignored
+      getNch(4);
+      putch(0x00);
+    }
+    /* Write memory, length is big endian and is in bytes */
+    else if(ch == STK_PROG_PAGE) {
+      // PROGRAM PAGE - we support flash programming only, not EEPROM
+      uint8_t *bufPtr;
+      uint16_t addrPtr;
+
+      getch();                  /* getlen() */
+      length = getch();
+      getch();
+
+      // If we are in RWW section, immediately start page erase
+      if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
+
+      // While that is going on, read in page contents
+      bufPtr = buff;
+      do *bufPtr++ = getch();
+      while (--length);
+
+      // If we are in NRWW section, page erase has to be delayed until now.
+      // Todo: Take RAMPZ into account
+      if (address >= NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
+
+      // Read command terminator, start reply
+      verifySpace();
+
+      // If only a partial page is to be programmed, the erase might not be complete.
+      // So check that here
+      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[8] | (buff[9]<<8);
+        vect -= 4; // Instruction is a relative jump (rjmp), so recalculate.
+        buff[8] = vect & 0xff;
+        buff[9] = vect >> 8;
+
+        // Add jump to bootloader at RESET vector
+        buff[0] = 0x7f;
+        buff[1] = 0xce; // rjmp 0x1d00 instruction
+      }
+#endif
+
+      // Copy buffer into programming buffer
+      bufPtr = buff;
+      addrPtr = (uint16_t)(void*)address;
+      ch = SPM_PAGESIZE / 2;
+      do {
+        uint16_t a;
+        a = *bufPtr++;
+        a |= (*bufPtr++) << 8;
+        __boot_page_fill_short((uint16_t)(void*)addrPtr,a);
+        addrPtr += 2;
+      } while (--ch);
+
+      // Write from programming buffer
+      __boot_page_write_short((uint16_t)(void*)address);
+      boot_spm_busy_wait();
+
+#if defined(RWWSRE)
+      // Reenable read access to flash
+      boot_rww_enable();
+#endif
+
+    }
+    /* Read memory block mode, length is big endian.  */
+    else if(ch == STK_READ_PAGE) {
+      // READ PAGE - we only read flash
+      getch();                  /* getlen() */
+      length = getch();
+      getch();
+
+      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 == 8)  ch=wdtVect & 0xff;
+        else if (address == 9) ch=wdtVect >> 8;
+        else ch = pgm_read_byte_near(address);
+        address++;
+        putch(ch);
+      } while (--length);
+#else
+#ifdef RAMPZ
+// Since RAMPZ should already be set, we need to use EPLM directly.
+//      do putch(pgm_read_byte_near(address++));
+//      while (--length);
+      do {
+        uint8_t result;
+        __asm__ ("elpm %0,Z\n":"=r"(result):"z"(address));
+        putch(result);
+        address++;
+      }
+      while (--length);
+#else
+      do putch(pgm_read_byte_near(address++));
+      while (--length);
+#endif
+#endif
+    }
+
+    /* Get device signature bytes  */
+    else if(ch == STK_READ_SIGN) {
+      // READ SIGN - return what Avrdude wants to hear
+      verifySpace();
+      putch(SIGNATURE_0);
+      putch(SIGNATURE_1);
+      putch(SIGNATURE_2);
+    }
+    else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+      // Adaboot no-wait mod
+      watchdogConfig(WATCHDOG_16MS);
+      verifySpace();
+    }
+    else {
+      // This covers the response to commands like STK_ENTER_PROGMODE
+      verifySpace();
+    }
+    putch(STK_OK);
+  }
+}
+
+void putch(char ch) {
+#ifndef SOFT_UART
+  while (!(UCSR0A & _BV(UDRE0)));
+  UDR0 = ch;
+#else
+  __asm__ __volatile__ (
+    "   com %[ch]\n" // ones complement, carry set
+    "   sec\n"
+    "1: brcc 2f\n"
+    "   cbi %[uartPort],%[uartBit]\n"
+    "   rjmp 3f\n"
+    "2: sbi %[uartPort],%[uartBit]\n"
+    "   nop\n"
+    "3: rcall uartDelay\n"
+    "   rcall uartDelay\n"
+    "   lsr %[ch]\n"
+    "   dec %[bitcnt]\n"
+    "   brne 1b\n"
+    :
+    :
+      [bitcnt] "d" (10),
+      [ch] "r" (ch),
+      [uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
+      [uartBit] "I" (UART_TX_BIT)
+    :
+      "r25"
+  );
+#endif
+}
+
+uint8_t getch(void) {
+  uint8_t ch;
+
+#ifdef LED_DATA_FLASH
+#ifdef __AVR_ATmega8__
+  LED_PORT ^= _BV(LED);
+#else
+  LED_PIN |= _BV(LED);
+#endif
+#endif
+
+#ifdef SOFT_UART
+  __asm__ __volatile__ (
+    "1: sbic  %[uartPin],%[uartBit]\n"  // Wait for start edge
+    "   rjmp  1b\n"
+    "   rcall uartDelay\n"          // Get to middle of start bit
+    "2: rcall uartDelay\n"              // Wait 1 bit period
+    "   rcall uartDelay\n"              // Wait 1 bit period
+    "   clc\n"
+    "   sbic  %[uartPin],%[uartBit]\n"
+    "   sec\n"
+    "   dec   %[bitCnt]\n"
+    "   breq  3f\n"
+    "   ror   %[ch]\n"
+    "   rjmp  2b\n"
+    "3:\n"
+    :
+      [ch] "=r" (ch)
+    :
+      [bitCnt] "d" (9),
+      [uartPin] "I" (_SFR_IO_ADDR(UART_PIN)),
+      [uartBit] "I" (UART_RX_BIT)
+    :
+      "r25"
+);
+#else
+  while(!(UCSR0A & _BV(RXC0)))
+    ;
+  if (!(UCSR0A & _BV(FE0))) {
+      /*
+       * A Framing Error indicates (probably) that something is talking
+       * to us at the wrong bit rate.  Assume that this is because it
+       * expects to be talking to the application, and DON'T reset the
+       * watchdog.  This should cause the bootloader to abort and run
+       * the application "soon", if it keeps happening.  (Note that we
+       * don't care that an invalid char is returned...)
+       */
+    watchdogReset();
+  }
+  
+  ch = UDR0;
+#endif
+
+#ifdef LED_DATA_FLASH
+#ifdef __AVR_ATmega8__
+  LED_PORT ^= _BV(LED);
+#else
+  LED_PIN |= _BV(LED);
+#endif
+#endif
+
+  return ch;
+}
+
+#ifdef SOFT_UART
+// AVR305 equation: #define UART_B_VALUE (((F_CPU/BAUD_RATE)-23)/6)
+// Adding 3 to numerator simulates nearest rounding for more accurate baud rates
+#define UART_B_VALUE (((F_CPU/BAUD_RATE)-20)/6)
+#if UART_B_VALUE > 255
+#error Baud rate too slow for soft UART
+#endif
+
+void uartDelay() {
+  __asm__ __volatile__ (
+    "ldi r25,%[count]\n"
+    "1:dec r25\n"
+    "brne 1b\n"
+    "ret\n"
+    ::[count] "M" (UART_B_VALUE)
+  );
+}
+#endif
+
+void getNch(uint8_t count) {
+  do getch(); while (--count);
+  verifySpace();
+}
+
+void verifySpace() {
+  if (getch() != CRC_EOP) {
+    watchdogConfig(WATCHDOG_16MS);    // shorten WD timeout
+    while (1)                         // and busy-loop so that WD causes
+      ;                               //  a reset and app start.
+  }
+  putch(STK_INSYNC);
+}
+
+#if LED_START_FLASHES > 0
+void flash_led(uint8_t count) {
+  do {
+    TCNT1 = -(F_CPU/(1024*16));
+    TIFR1 = _BV(TOV1);
+    while(!(TIFR1 & _BV(TOV1)));
+#ifdef __AVR_ATmega8__
+    LED_PORT ^= _BV(LED);
+#else
+    LED_PIN |= _BV(LED);
+#endif
+    watchdogReset();
+  } while (--count);
+}
+#endif
+
+// Watchdog functions. These are only safe with interrupts turned off.
+void watchdogReset() {
+  __asm__ __volatile__ (
+    "wdr\n"
+  );
+}
+
+void watchdogConfig(uint8_t x) {
+  WDTCSR = _BV(WDCE) | _BV(WDE);
+  WDTCSR = x;
+}
+
+void appStart() {
+  watchdogConfig(WATCHDOG_OFF);
+  __asm__ __volatile__ (
+#ifdef VIRTUAL_BOOT_PARTITION
+    // Jump to WDT vector
+    "ldi r30,4\n"
+    "clr r31\n"
+#else
+    // Jump to RST vector
+    "clr r30\n"
+    "clr r31\n"
+#endif
+    "ijmp\n"
+  );
+}
diff --git a/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/optiboot_1284P_20MHz_57k6_baud.hex b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/optiboot_1284P_20MHz_57k6_baud.hex
new file mode 100644
index 0000000000000000000000000000000000000000..98d96ea557826afc291acdc267dd4adf33f66b41
--- /dev/null
+++ b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/optiboot_1284P_20MHz_57k6_baud.hex
@@ -0,0 +1,33 @@
+:020000021000EC
+:10FE00000F92CDB7DEB7112484B714BE81FFDFD0C7
+:10FE100082E08093C00088E18093C10086E08093F7
+:10FE2000C2008AE28093C4008EE0BBD0209A00E03A
+:10FE300010E0EE24E394E1E1DE2EF3E0FF2EA5D006
+:10FE4000813471F4A2D08983B2D08981823809F4D7
+:10FE50008BC0813811F484E001C083E08FD08BC067
+:10FE6000823411F484E103C0853419F485E0A7D00D
+:10FE700082C0853591F489D0A82EBB2486D0082F66
+:10FE800010E0102F00270A291B29812F881F88279F
+:10FE9000881F8BBF000F111F6DC0863521F484E0D1
+:10FEA0008ED080E0DBCF843609F040C06ED06DD0BC
+:10FEB000C82E6BD080EE0030180718F4F801F7BE9A
+:10FEC000E895A12C51E0B52E60D0F50181935F013A
+:10FED000CE16D1F7F0EE00301F0718F0F801F7BE8C
+:10FEE000E89565D007B600FCFDCFF801A0E0B1E0D1
+:10FEF0002C9130E011968C91119790E0982F8827E3
+:10FF0000822B932B12960C01E7BEE89511243296B2
+:10FF100082E0A030B80761F785E0F80187BFE89577
+:10FF200007B600FCFDCFD7BEE89525C08437A9F4FD
+:10FF30002CD02BD0B82E29D03AD0CB2C4801F401AC
+:10FF400086911CD00894811C911CCA94C1F70F5F44
+:10FF50001F4FBA940B0D111D0EC0853739F427D0F1
+:10FF60008EE10CD087E90AD085E078CF813511F495
+:10FF700088E017D01CD080E101D061CF9091C00003
+:10FF800095FFFCCF8093C60008958091C00087FF45
+:10FF9000FCCF8091C00084FD01C0A8958091C6006F
+:10FFA0000895E0E6F0E098E1908380830895EDDF26
+:10FFB000803219F088E0F5DFFFCF84E1DFCFCF9307
+:10FFC000C82FE3DFC150E9F7F2DFCF91089580E059
+:08FFD000E8DFEE27FF2709948A
+:040000031000FE00EB
+:00000001FF
diff --git a/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/pin_defs.h b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/pin_defs.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a8a4ca99c38d93475bf80898c4be73bcbd929fa
--- /dev/null
+++ b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/pin_defs.h
@@ -0,0 +1,81 @@
+#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
+/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */
+#define LED_DDR     DDRB
+#define LED_PORT    PORTB
+#define LED_PIN     PINB
+#define LED         PINB5
+
+/* Ports for soft UART */
+#ifdef SOFT_UART
+#define UART_PORT   PORTD
+#define UART_PIN    PIND
+#define UART_DDR    DDRD
+#define UART_TX_BIT 1
+#define UART_RX_BIT 0
+#endif
+#endif
+
+#if defined(__AVR_ATmega8__)
+  //Name conversion R.Wiersma
+  #define UCSR0A        UCSRA
+  #define UDR0          UDR
+  #define UDRE0         UDRE
+  #define RXC0          RXC
+  #define FE0           FE
+  #define TIFR1         TIFR
+  #define WDTCSR        WDTCR
+#endif
+
+/* Luminet support */
+#if defined(__AVR_ATtiny84__)
+/* Red LED is connected to pin PA4 */
+#define LED_DDR     DDRA
+#define LED_PORT    PORTA
+#define LED_PIN     PINA
+#define LED         PINA4
+/* Ports for soft UART - left port only for now. TX/RX on PA2/PA3 */
+#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
+
+/* Sanguino support */
+#if defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
+/* Onboard LED is connected to pin PB0 on Sanguino */
+#define LED_DDR     DDRB
+#define LED_PORT    PORTB
+#define LED_PIN     PINB
+#define LED         PINB0
+
+/* Ports for soft UART */
+#ifdef SOFT_UART
+#define UART_PORT   PORTD
+#define UART_PIN    PIND
+#define UART_DDR    DDRD
+#define UART_TX_BIT 1
+#define UART_RX_BIT 0
+#endif
+#endif
+
+/* Mega support */
+#if defined(__AVR_ATmega1280__)
+/* Onboard LED is connected to pin PB7 on Arduino Mega */
+#define LED_DDR     DDRB
+#define LED_PORT    PORTB
+#define LED_PIN     PINB
+#define LED         PINB7
+
+/* Ports for soft UART */
+#ifdef SOFT_UART
+#define UART_PORT   PORTE
+#define UART_PIN    PINE
+#define UART_DDR    DDRE
+#define UART_TX_BIT 1
+#define UART_RX_BIT 0
+#endif
+#endif
+
diff --git a/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/stk500.h b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/stk500.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca0dd91dfeef1e4d260ce9ca16e93308c7380aae
--- /dev/null
+++ b/ArduinoAddons/Arduino_0.xx/Sanguino/bootloaders/atmega1284p/stk500.h
@@ -0,0 +1,39 @@
+/* STK500 constants list, from AVRDUDE */
+#define STK_OK              0x10
+#define STK_FAILED          0x11  // Not used
+#define STK_UNKNOWN         0x12  // Not used
+#define STK_NODEVICE        0x13  // Not used
+#define STK_INSYNC          0x14  // ' '
+#define STK_NOSYNC          0x15  // Not used
+#define ADC_CHANNEL_ERROR   0x16  // Not used
+#define ADC_MEASURE_OK      0x17  // Not used
+#define PWM_CHANNEL_ERROR   0x18  // Not used
+#define PWM_ADJUST_OK       0x19  // Not used
+#define CRC_EOP             0x20  // 'SPACE'
+#define STK_GET_SYNC        0x30  // '0'
+#define STK_GET_SIGN_ON     0x31  // '1'
+#define STK_SET_PARAMETER   0x40  // '@'
+#define STK_GET_PARAMETER   0x41  // 'A'
+#define STK_SET_DEVICE      0x42  // 'B'
+#define STK_SET_DEVICE_EXT  0x45  // 'E'
+#define STK_ENTER_PROGMODE  0x50  // 'P'
+#define STK_LEAVE_PROGMODE  0x51  // 'Q'
+#define STK_CHIP_ERASE      0x52  // 'R'
+#define STK_CHECK_AUTOINC   0x53  // 'S'
+#define STK_LOAD_ADDRESS    0x55  // 'U'
+#define STK_UNIVERSAL       0x56  // 'V'
+#define STK_PROG_FLASH      0x60  // '`'
+#define STK_PROG_DATA       0x61  // 'a'
+#define STK_PROG_FUSE       0x62  // 'b'
+#define STK_PROG_LOCK       0x63  // 'c'
+#define STK_PROG_PAGE       0x64  // 'd'
+#define STK_PROG_FUSE_EXT   0x65  // 'e'
+#define STK_READ_FLASH      0x70  // 'p'
+#define STK_READ_DATA       0x71  // 'q'
+#define STK_READ_FUSE       0x72  // 'r'
+#define STK_READ_LOCK       0x73  // 's'
+#define STK_READ_PAGE       0x74  // 't'
+#define STK_READ_SIGN       0x75  // 'u'
+#define STK_READ_OSCCAL     0x76  // 'v'
+#define STK_READ_FUSE_EXT   0x77  // 'w'
+#define STK_READ_OSCCAL_EXT 0x78  // 'x'