diff --git a/ActualOptiboot/README.md b/ActualOptiboot/README.md
new file mode 100644
index 0000000..3ef7aa9
--- /dev/null
+++ b/ActualOptiboot/README.md
@@ -0,0 +1,54 @@
+## Optiboot Bootloader for Arduino and Atmel AVR ##
+
+![docs/optiboot.png](docs/optiboot.png)
+
+Optiboot is an easy to install upgrade to the Arduino bootloader within Arduino boards. It provides the following features:
+
+ * Allows larger sketches. Optiboot is a quarter of the size of the default bootloader, freeing 1.5k of extra space.
+ * Makes your sketches upload faster. Optiboot operates at higher baud rates and has streamlined programming.
+ * Adaboot performance improvements. Optiboot runs your sketches sooner, with no watchdog issues.
+ * Compatible with 168 and 328 Arduinos including Lilypad, Pro, Nano
+ * Believed to work with ATmega1280 ("Mega"), ATmega644 ("Sanguino"), and ATmega1284 ("Mighty")
+ * Supports several additional AVR chips (ATmega88, ATmega32)
+
+Optiboot is now installed by default on the Arduino Uno. It can be installed on all older mega8, 168 or 328 based Arduinos.
+
+## Additional Documentation
+More detailed documentation is being added (slowly) to the [repository wiki](https://github.com/Optiboot/optiboot/wiki).
+
+## Notes on IDE Version compatability
+Optiboot is "compatible", in a loose sense, with all versions of the Arduino IDE. It was originally written at about the same time as v1.0, and has some "quirks" that date back to that timeframe. Most significantly, install procedures and locations change between releases, and the ability to compile Optiboot using only the tools installed with the IDE broke in the v1.5 timeframe.
+
+## To install into the Arduino software ##
+You do NOT need to "install" Optiboot if you are trying to update an installed platform that already uses some form of Optiboot. In that case, you should probably just find and replace the existing .hex files from the platform support directories. Using the Optiboot "install" procedure does not install any cores or variants, so it is only useful for CPUs that are already supported by the standard Arduino core (or, if all you want to do is install bootloaders.)
+
+The following instructions are based on using the Arduino "Board Manager", present in IDE versions 1.6.5 and later.
+
+ 1. Find the desired Optiboot release on the [Optiboot Release page] (https://github.com/Optiboot/optiboot/releases).
+ 2. Use the "Copy link address" feature of your browser to copy the URL of the associated **.json** file.
+ 3. Paste this url into the "Additional Boards Manager URLs" field in the Arduino IDE "Preferences" pane. (Separate it from other URLs that might be present with a comma or click the icon to the right of the field to insert it on a new line.)
+ 4. After closing the Preferences window, the **Tools/Boards/Boards Manager** menu should include an entry for that version of Optiboot. Select that entry and click the **Install** button.
+
+For additional installation information, see the [Optiboot AddingOptibootChipsToIde Wiki page] (https://github.com/Optiboot/optiboot/wiki/AddingOptibootChipsToIde)
+
+
+
+
+## To burn Optiboot onto an Arduino board ##
+ 1. Select the appropriate Optiboot board type (or non-Optiboot if you want to change back)
+ 1. Connect your Arduino to an ISP programmer [[Installing]]
+ 1. Use the 'Burn Bootloader' item in Arduino.
+ 1. You can then upload sketches as normal, using the Optiboot board type.
+
+----
+
+> Although it has evolved considerably, Optiboot builds on the original work of Jason P. Kyle (stk500boot.c), [Arduino group (bootloader)](http://arduino.cc), [Spiff (1K bootloader)](http://spiffie.org/know/arduino_1k_bootloader/bootloader.shtml), [AVR-Libc group](http://nongnu.org/avr-libc) and [Ladyada (Adaboot)](http://www.ladyada.net/library/arduino/bootloader.html).
+
+> _Optiboot is the work of Peter Knight (aka Cathedrow). Despite some misattributions, it is not sponsored or supported by any organisation or company including Tinker London, Tinker.it! and Arduino._
+> Maintenance of optiboot was taken over by Bill Westfield (aka WestfW) in 2011.
diff --git a/ActualOptiboot/docs/arduino-gcc-versions.md b/ActualOptiboot/docs/arduino-gcc-versions.md
new file mode 100644
index 0000000..2ba6ca7
--- /dev/null
+++ b/ActualOptiboot/docs/arduino-gcc-versions.md
@@ -0,0 +1,42 @@
+Arduino ships also avr-gcc. This is matrix of versions and changes
+based on Linux versions.
+
+
+| Arduino | avr-gcc | differences | test? |
+|---------|---------|-------------|-------|
+|<=1.0 |none? | | |
+|1.0.1 |4.3.2 |new| |
+|1.0.2 |4.3.2 |same as 1.0.1| |
+|1.0.3 |4.3.2 |same as 1.0.1| |
+|1.0.4 |4.3.2 |same as 1.0.1| |
+|1.0.5 |4.3.2 |same as 1.0.1| |
+|1.0.6 |4.3.2 |same as 1.0.1| yes |
+|1.5 |4.3.2 |same as 1.0.1| |
+|1.5.1 |4.3.2 |same as 1.0.1| |
+|1.5.2 |4.3.2 |same as 1.0.1| |
+|1.5.3 |4.3.2 |same as 1.0.1| |
+|1.5.4 |4.3.2 |same as 1.0.1| |
+|1.5.5 |4.3.2 |same as 1.0.1| |
+|1.5.6-r2 |4.3.2 |same as 1.0.1| |
+|1.5.7 |4.8.1 |toolchains upgrade, avrdude 6.0.1avrdude| |
+|1.5.8 |4.8.1 |same as 1.5.7| |
+|1.6.0 |4.8.1 |same as 1.5.7| |
+|1.6.1 |4.8.1 |toolchains upgrade, added ATmega48/88/168PB, ATA5702M322, ATA5782; added RAMSTART to io*.h| |
+|1.6.2 |packed | | |
+|1.6.3 |4.8.1 |toolchains upgrade, cleaned| |
+|1.6.4 |4.8.1 |almost the same as 1.6.1| |
+|1.6.5-r5 |4.8.1 |same as 1.6.4| |
+|1.6.6 |4.8.1 |same as 1.6.4| |
+|1.6.7 |4.8.1 |same as 1.6.4| |
+|1.6.8 |4.8.1 |same as 1.6.4| |
+|1.6.9 |4.8.1 |same as 1.6.4| yes |
+|1.6.10 |4.9.2 |toolchains upgrade, , avrdude 6.3 | |
+|1.6.11 |4.9.2 |same as 1.6.10, back to avrdude 6.0.1| |
+|1.6.12 |4.9.2 |same as 1.6.10, patched avrdude 6.3| |
+|1.6.13 |4.9.2 |same as 1.6.12| yes |
+|1.8.0 |4.9.2 |same as 1.6.12, another patch for avrdude 6.3 | |
+|1.8.1 |4.9.2 |same as 1.8.0| |
+|1.8.2 |4.9.2 |recompiled, new toolchains, lot of changes| |
+|1.8.3 |4.9.2 |same as 1.8.2| |
+|1.8.4 |4.9.2 |same as 1.8.2| |
+|1.8.5 |4.9.2 |same as 1.8.2| yes |
diff --git a/ActualOptiboot/docs/optiboot.png b/ActualOptiboot/docs/optiboot.png
new file mode 100644
index 0000000..e91daa0
Binary files /dev/null and b/ActualOptiboot/docs/optiboot.png differ
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.atsln b/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.atsln
new file mode 100644
index 0000000..8e80123
--- /dev/null
+++ b/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.atsln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Atmel Studio Solution File, Format Version 11.00
+Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "xplained168pb", "xplained168pb.cproj", "{02F0BC88-77BD-42CC-A94C-4CC452F0F909}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|AVR = Debug|AVR
+ Release|AVR = Release|AVR
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Debug|AVR.ActiveCfg = Debug|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Debug|AVR.Build.0 = Debug|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Release|AVR.ActiveCfg = Release|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Release|AVR.Build.0 = Release|AVR
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.atsuo b/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.atsuo
new file mode 100644
index 0000000..91b32c4
Binary files /dev/null and b/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.atsuo differ
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.cproj b/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.cproj
new file mode 100644
index 0000000..d8968bc
--- /dev/null
+++ b/ActualOptiboot/optiboot/AtmelStudio/xplained168pb.cproj
@@ -0,0 +1,168 @@
+
+
+
+ 2.0
+ 6.2
+ com.Atmel.AVRGCC8.C
+ {02f0bc88-77bd-42cc-a94c-4cc452f0f909}
+ ATmega168PB
+ none
+ Executable
+ C
+ $(MSBuildProjectName)
+ .elf
+ $(MSBuildProjectDirectory)\$(Configuration)
+ optitest
+ xplained168pb
+ optitest
+ Native
+ true
+ false
+ true
+ true
+ 0x20000000
+
+ true
+ exception_table
+ 2
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+ com.atmel.avrdbg.tool.medbg
+
+
+
+
+ ISP
+
+ com.atmel.avrdbg.tool.medbg
+ ATML2222050200008424
+ mEDBG
+
+
+
+
+
+
+
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ NDEBUG
+
+
+ Optimize for size (-Os)
+ True
+ True
+ True
+
+
+ True
+ xplained168pb
+ clean
+ ..\bootloaders\optiboot\makefile
+ copy optiboot_xplained168pb.* ..\..\AtmelStudio
+
+ ..\bootloaders\optiboot
+
+
+
+
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ DEBUG
+
+
+ Optimize (-O1)
+ True
+ True
+ Default (-g2)
+ True
+ Default (-Wa,-g)
+
+
+ True
+ xplained168pb
+ clean
+ ..\bootloaders\optiboot\makefile
+ optiboot_xplained168pb
+ .hex
+ copy optiboot_xplained168pb.* ..\..\AtmelStudio
+
+ ..\bootloaders\optiboot
+
+
+
+ compile
+ Makefile
+
+
+ compile
+ Makefile.1284
+
+
+ compile
+ Makefile.atmel
+
+
+ compile
+ Makefile.custom
+
+
+ compile
+ Makefile.extras
+
+
+ compile
+ Makefile.isp
+
+
+ compile
+
+
+ compile
+
+
+
+
+ compile
+ baudcheck.c
+
+
+ compile
+ optiboot.c
+
+
+ compile
+ pin_defs.h
+
+
+ compile
+ stk500.h
+
+
+
+
\ No newline at end of file
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained328p.atsln b/ActualOptiboot/optiboot/AtmelStudio/xplained328p.atsln
new file mode 100644
index 0000000..86449e7
--- /dev/null
+++ b/ActualOptiboot/optiboot/AtmelStudio/xplained328p.atsln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Atmel Studio Solution File, Format Version 11.00
+Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "xplained328p", "xplained328p.cproj", "{02F0BC88-77BD-42CC-A94C-4CC452F0F909}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|AVR = Debug|AVR
+ Release|AVR = Release|AVR
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Debug|AVR.ActiveCfg = Debug|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Debug|AVR.Build.0 = Debug|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Release|AVR.ActiveCfg = Release|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Release|AVR.Build.0 = Release|AVR
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained328p.atsuo b/ActualOptiboot/optiboot/AtmelStudio/xplained328p.atsuo
new file mode 100644
index 0000000..f77e2ca
Binary files /dev/null and b/ActualOptiboot/optiboot/AtmelStudio/xplained328p.atsuo differ
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained328p.cproj b/ActualOptiboot/optiboot/AtmelStudio/xplained328p.cproj
new file mode 100644
index 0000000..eb99088
--- /dev/null
+++ b/ActualOptiboot/optiboot/AtmelStudio/xplained328p.cproj
@@ -0,0 +1,179 @@
+
+
+
+ 2.0
+ 6.2
+ com.Atmel.AVRGCC8.C
+ {02f0bc88-77bd-42cc-a94c-4cc452f0f909}
+ ATmega328P
+ none
+ Executable
+ C
+ $(MSBuildProjectName)
+ .elf
+ $(MSBuildProjectDirectory)\$(Configuration)
+ optitest
+ optitest
+ optitest
+ Native
+ true
+ false
+ true
+ true
+ 0x20000000
+
+ true
+ exception_table
+ 2
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ISP
+
+ com.atmel.avrdbg.tool.medbg
+ ATML2222050200008424
+ mEDBG
+
+ ISP
+
+
+
+
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ NDEBUG
+
+
+ Optimize for size (-Os)
+ True
+ True
+ True
+
+
+ libm
+
+
+
+
+ True
+ ..\bootloaders\optiboot
+ xplained328p
+ clean
+ ..\bootloaders\optiboot\Makefile
+ copy optiboot_xplained328p.* ..\..\AtmelStudio
+
+
+
+
+
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ DEBUG
+
+
+ Optimize (-O1)
+ True
+ True
+ Default (-g2)
+ True
+
+
+ libm
+
+
+ Default (-Wa,-g)
+
+
+ True
+ xplained328p
+ clean
+ ..\bootloaders\optiboot\Makefile
+ optiboot_xplained328p
+ .hex
+ ..\bootloaders\optiboot
+ copy optiboot_xplained328p.* ..\..\AtmelStudio
+
+
+
+
+
+
+
+ compile
+ Makefile
+
+
+ compile
+ Makefile.1284
+
+
+ compile
+ Makefile.atmel
+
+
+ compile
+ Makefile.custom
+
+
+ compile
+ Makefile.extras
+
+
+ compile
+ Makefile.isp
+
+
+
+
+ compile
+ baudcheck.c
+
+
+ compile
+ boot.h
+
+
+ compile
+ optiboot.c
+
+
+ compile
+ pin_defs.h
+
+
+ compile
+ stk500.h
+
+
+
+
\ No newline at end of file
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.atsln b/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.atsln
new file mode 100644
index 0000000..f19eaa4
--- /dev/null
+++ b/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.atsln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Atmel Studio Solution File, Format Version 11.00
+Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "xplained328pb", "xplained328pb.cproj", "{02F0BC88-77BD-42CC-A94C-4CC452F0F909}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|AVR = Debug|AVR
+ Release|AVR = Release|AVR
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Debug|AVR.ActiveCfg = Release|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Debug|AVR.Build.0 = Release|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Release|AVR.ActiveCfg = Release|AVR
+ {02F0BC88-77BD-42CC-A94C-4CC452F0F909}.Release|AVR.Build.0 = Release|AVR
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.atsuo b/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.atsuo
new file mode 100644
index 0000000..3ef452b
Binary files /dev/null and b/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.atsuo differ
diff --git a/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.cproj b/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.cproj
new file mode 100644
index 0000000..b1a3f86
--- /dev/null
+++ b/ActualOptiboot/optiboot/AtmelStudio/xplained328pb.cproj
@@ -0,0 +1,179 @@
+
+
+
+ 2.0
+ 6.2
+ com.Atmel.AVRGCC8.C
+ {02f0bc88-77bd-42cc-a94c-4cc452f0f909}
+ ATmega328PB
+ none
+ Executable
+ C
+ $(MSBuildProjectName)
+ .elf
+ $(MSBuildProjectDirectory)\$(Configuration)
+ optitest
+ optitest
+ optitest
+ Native
+ true
+ false
+ true
+ true
+ 0x20000000
+
+ true
+ exception_table
+ 2
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+ com.atmel.avrdbg.tool.medbg
+
+
+
+
+ ISP
+
+ com.atmel.avrdbg.tool.medbg
+ ATML2222050200008424
+ mEDBG
+
+ ISP
+
+
+
+
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ NDEBUG
+
+
+ Optimize for size (-Os)
+ True
+ True
+ True
+
+
+ libm
+
+
+
+
+ True
+ ..\bootloaders\optiboot
+ xplained328pb
+ clean
+ ..\bootloaders\optiboot\Makefile
+ copy optiboot_xplained328pb.* ..\..\AtmelStudio
+
+
+
+
+ True
+ True
+ True
+ True
+ False
+ True
+ True
+
+
+ DEBUG
+
+
+ Optimize (-O1)
+ True
+ True
+ Default (-g2)
+ True
+
+
+ libm
+
+
+ Default (-Wa,-g)
+
+
+ True
+ xplained328pb
+ clean
+ ..\bootloaders\optiboot\Makefile
+ optiboot_xplained328pb
+ .hex
+ ..\bootloaders\optiboot
+ copy optiboot_xplained328pb.* ..\..\AtmelStudio
+
+
+
+ compile
+ Makefile
+
+
+ compile
+ Makefile.1284
+
+
+ compile
+ Makefile.atmel
+
+
+ compile
+ Makefile.custom
+
+
+ compile
+ Makefile.extras
+
+
+ compile
+ Makefile.isp
+
+
+ compile
+
+
+ compile
+
+
+
+
+ compile
+ baudcheck.c
+
+
+ compile
+ boot.h
+
+
+ compile
+ optiboot.c
+
+
+ compile
+ pin_defs.h
+
+
+ compile
+ stk500.h
+
+
+
+
\ No newline at end of file
diff --git a/ActualOptiboot/optiboot/boards-1.6.txt b/ActualOptiboot/optiboot/boards-1.6.txt
new file mode 100644
index 0000000..cd9b293
--- /dev/null
+++ b/ActualOptiboot/optiboot/boards-1.6.txt
@@ -0,0 +1,461 @@
+#
+# Boards.txt file for Optiboot platforms, in format for Arduino 1.5.x and later.
+#
+# See: http://github.com/Arduino/arduino/
+
+name=[Optiboot]
+version=6.2
+
+##############################################################
+## Optiboot on 28-pin processors (atmega8/88/168/328/etc)
+
+menu.cpu=Processor
+menu.mhz=CPU Speed
+
+optiboot28.name=Optiboot on 28-pin cpus
+
+optiboot28.upload.tool=arduino:avrdude
+optiboot28.upload.protocol=arduino
+optiboot28.upload.speed=115200
+
+optiboot28.bootloader.tool=arduino:avrdude
+optiboot28.bootloader.low_fuses=0xF7
+optiboot28.bootloader.unlock_bits=0x3F
+optiboot28.bootloader.lock_bits=0x2F
+optiboot28.build.f_cpu=16000000L
+
+
+#
+# Other Clock speeds.
+# For 8MHz using the internal RC Oscillator, we adjust fuses, use the same
+# bootloader binary, and halve the upload rate.
+#
+optiboot28.menu.mhz.16MHz=16MHz
+optiboot28.menu.mhz.16MHz.upload.speed=115200
+optiboot28.menu.mhz.8MHz=8MHz (int)
+optiboot28.menu.mhz.8MHz.build.f_cpu=8000000L
+optiboot28.menu.mhz.8MHz.bootloader.low_fuses=0xE2
+optiboot28.menu.mhz.8MHz.upload.speed=57600
+optiboot28.menu.mhz.1MHz=1MHz (int)
+optiboot28.menu.mhz.1MHz.build.f_cpu=1000000L
+optiboot28.menu.mhz.1MHz.bootloader.low_fuses=0x62
+optiboot28.menu.mhz.1MHz.upload.speed=9600
+
+# optiboot platforms should be UNO-like more than anything else.
+optiboot28.build.board=AVR_UNO
+optiboot28.build.core=arduino:arduino
+optiboot28.build.variant=arduino:standard
+
+
+## Optiboot for ATmega328p
+## ---------------------------------------------
+optiboot28.menu.cpu.atmega328p=ATmega328p
+optiboot28.menu.cpu.atmega328p.upload.maximum_size=32256
+optiboot28.menu.cpu.atmega328p.upload.maximum_data_size=2048
+
+optiboot28.menu.cpu.atmega328p.bootloader.high_fuses=0xDE
+optiboot28.menu.cpu.atmega328p.bootloader.extended_fuses=0x05
+optiboot28.menu.cpu.atmega328p.bootloader.file=optiboot/optiboot_atmega328.hex
+
+optiboot28.menu.cpu.atmega328p.build.mcu=atmega328p
+
+## Optiboot for ATmega328
+## ---------------------------------------------
+optiboot28.menu.cpu.atmega328=ATmega328
+optiboot28.menu.cpu.atmega328.upload.maximum_size=32256
+optiboot28.menu.cpu.atmega328.upload.maximum_data_size=2048
+
+optiboot28.menu.cpu.atmega328.bootloader.high_fuses=0xDE
+optiboot28.menu.cpu.atmega328.bootloader.extended_fuses=0x05
+optiboot28.menu.cpu.atmega328.bootloader.file=optiboot/optiboot_atmega328.hex
+# lie! Arduino wise, these are compatible
+optiboot28.menu.cpu.atmega328.build.mcu=atmega328p
+
+
+## Optiboot ATmega168
+## ---------------------------------------------
+optiboot28.menu.cpu.atmega168=ATmega168
+
+optiboot28.menu.cpu.atmega168.upload.maximum_size=15872
+optiboot28.menu.cpu.atmega168.upload.maximum_data_size=1024
+
+optiboot28.menu.cpu.atmega168.bootloader.high_fuses=0xDD
+optiboot28.menu.cpu.atmega168.bootloader.extended_fuses=0xFC
+optiboot28.menu.cpu.atmega168.bootloader.file=optiboot/optiboot_atmega168.hex
+
+optiboot28.menu.cpu.atmega168.build.mcu=atmega168
+
+## ---------------------------------------------
+optiboot28.menu.cpu.atmega168p=ATmega168p
+
+optiboot28.menu.cpu.atmega168p.upload.maximum_size=15872
+optiboot28.menu.cpu.atmega168p.upload.maximum_data_size=1024
+
+optiboot28.menu.cpu.atmega168p.bootloader.high_fuses=0xDD
+optiboot28.menu.cpu.atmega168p.bootloader.extended_fuses=0xFC
+optiboot28.menu.cpu.atmega168p.bootloader.file=optiboot/optiboot_atmega168.hex
+
+optiboot28.menu.cpu.atmega168p.build.mcu=atmega168p
+
+
+## optiboot for ATmega8
+## ---------------------------------------------
+optiboot28.menu.cpu.atmega8=ATmega8
+
+optiboot28.menu.cpu.atmega8.upload.maximum_size=7680
+optiboot28.menu.cpu.atmega8.upload.maximum_data_size=1024
+
+optiboot28.menu.cpu.atmega8.bootloader.high_fuses=0xCC
+optiboot28.menu.cpu.atmega8.bootloader.low_fuses=0xBF
+# optiboot28.menu.cpu.atmega8.bootloader.extended_fuses=0x00
+optiboot28.menu.cpu.atmega8.bootloader.file=optiboot/optiboot_atmega8.hex
+
+optiboot28.menu.cpu.atmega8.build.mcu=atmega8
+
+## Atmega88
+## ---------------------------------------------
+optiboot28.menu.cpu.atmega88=ATmega88
+
+optiboot28.menu.cpu.atmega88.upload.maximum_size=7680
+optiboot28.menu.cpu.atmega88.upload.maximum_data_size=1024
+
+optiboot28.menu.cpu.atmega88.bootloader.high_fuses=0xDD
+optiboot28.menu.cpu.atmega88.bootloader.extended_fuses=0xFC
+optiboot28.menu.cpu.atmega88.bootloader.file=optiboot/optiboot_atmega88.hex
+
+optiboot28.menu.cpu.atmega88.build.mcu=atmega88p
+
+
+##############################################################
+## Optiboot on 32pin (SMT) CPUs (Nano, Pro Micro, etc.)
+##############################################################
+
+optiboot32.name=Optiboot on 32-pin cpus
+
+optiboot32.upload.tool=arduino:avrdude
+optiboot32.upload.protocol=arduino
+optiboot32.upload.speed=115200
+
+optiboot32.bootloader.tool=arduino:avrdude
+optiboot32.bootloader.low_fuses=0xF7
+optiboot32.bootloader.unlock_bits=0x3F
+optiboot32.bootloader.lock_bits=0x2F
+optiboot32.build.f_cpu=16000000L
+
+#
+# Other Clock speeds.
+# For 8MHz using the internal RC Oscillator, we adjust fuses, use the same
+# bootloader binary, and halve the upload rate.
+#
+optiboot32.menu.mhz.16MHz=16MHz
+optiboot32.menu.mhz.16MHz.upload.speed=115200
+optiboot32.menu.mhz.8MHz=8MHz (int)
+optiboot32.menu.mhz.8MHz.build.f_cpu=8000000L
+optiboot32.menu.mhz.8MHz.bootloader.low_fuses=0xE2
+optiboot32.menu.mhz.8MHz.upload.speed=57600
+optiboot32.menu.mhz.1MHz=1MHz (int)
+optiboot32.menu.mhz.1MHz.build.f_cpu=1000000L
+optiboot32.menu.mhz.1MHz.bootloader.low_fuses=0x62
+optiboot32.menu.mhz.1MHz.upload.speed=9600
+
+# optiboot platforms should be UNO-like more than anything else.
+optiboot32.build.board=AVR_UNO
+optiboot32.build.core=arduino:arduino
+optiboot32.build.variant=arduino:eightanaloginputs
+
+
+## Optiboot for ATmega328p
+## ---------------------------------------------
+optiboot32.menu.cpu.atmega328p=ATmega328p
+optiboot32.menu.cpu.atmega328p.upload.maximum_size=32256
+optiboot32.menu.cpu.atmega328p.upload.maximum_data_size=2048
+
+optiboot32.menu.cpu.atmega328p.bootloader.high_fuses=0xDE
+optiboot32.menu.cpu.atmega328p.bootloader.extended_fuses=0x05
+optiboot32.menu.cpu.atmega328p.bootloader.file=optiboot/optiboot_atmega328.hex
+
+optiboot32.menu.cpu.atmega328p.build.mcu=atmega328p
+
+## Optiboot for ATmega328
+## ---------------------------------------------
+optiboot32.menu.cpu.atmega328=ATmega328
+optiboot32.menu.cpu.atmega328.upload.maximum_size=32256
+optiboot32.menu.cpu.atmega328.upload.maximum_data_size=2048
+
+optiboot32.menu.cpu.atmega328.bootloader.high_fuses=0xDE
+optiboot32.menu.cpu.atmega328.bootloader.extended_fuses=0x05
+optiboot32.menu.cpu.atmega328.bootloader.file=optiboot/optiboot_atmega328.hex
+# lie! Arduino wise, these are compatible
+optiboot32.menu.cpu.atmega328.build.mcu=atmega328p
+
+
+## Optiboot ATmega168
+## ---------------------------------------------
+optiboot32.menu.cpu.atmega168=ATmega168
+
+optiboot32.menu.cpu.atmega168.upload.maximum_size=15872
+optiboot32.menu.cpu.atmega168.upload.maximum_data_size=1024
+
+optiboot32.menu.cpu.atmega168.bootloader.high_fuses=0xDD
+optiboot32.menu.cpu.atmega168.bootloader.extended_fuses=0xFC
+optiboot32.menu.cpu.atmega168.bootloader.file=optiboot/optiboot_atmega168.hex
+
+optiboot32.menu.cpu.atmega168.build.mcu=atmega168
+
+## ---------------------------------------------
+optiboot32.menu.cpu.atmega168p=ATmega168p
+
+optiboot32.menu.cpu.atmega168p.upload.maximum_size=15872
+optiboot32.menu.cpu.atmega168p.upload.maximum_data_size=1024
+
+optiboot32.menu.cpu.atmega168p.bootloader.high_fuses=0xDD
+optiboot32.menu.cpu.atmega168p.bootloader.extended_fuses=0xFC
+optiboot32.menu.cpu.atmega168p.bootloader.file=optiboot/optiboot_atmega168.hex
+
+optiboot32.menu.cpu.atmega168p.build.mcu=atmega168p
+
+
+
+##############################################################
+## Other optiboot platforms
+##############################################################
+
+optiboot1280.name=Optiboot on Mega1280
+
+optiboot1280.upload.tool=arduino:avrdude
+optiboot1280.upload.protocol=arduino
+optiboot1280.upload.speed=115200
+
+optiboot1280.bootloader.tool=arduino:avrdude
+optiboot1280.bootloader.unlock_bits=0x3F
+optiboot1280.bootloader.lock_bits=0x2F
+
+optiboot1280.build.f_cpu=16000000L
+
+optiboot1280.build.board=AVR_MEGA
+optiboot1280.build.core=arduino:arduino
+optiboot1280.build.variant=arduino:mega
+
+optiboot1280.upload.maximum_size=130048
+optiboot1280.upload.maximum_data_size=8192
+
+optiboot1280.bootloader.low_fuses=0xFF
+optiboot1280.bootloader.high_fuses=0xDE
+optiboot1280.bootloader.extended_fuses=0x05
+optiboot1280.bootloader.file=optiboot/optiboot_atmega1280.hex
+
+optiboot1280.build.mcu=atmega1280
+
+##############################################################
+
+
+optiboot1284.name=Optiboot on (generic) Mega1284
+
+optiboot1284.upload.tool=arduino:avrdude
+optiboot1284.upload.protocol=arduino
+optiboot1284.upload.speed=115200
+
+optiboot1284.bootloader.tool=arduino:avrdude
+optiboot1284.bootloader.unlock_bits=0x3F
+optiboot1284.bootloader.lock_bits=0x2F
+
+optiboot1284.build.f_cpu=16000000L
+
+optiboot1284.build.board=AVR_M1284
+optiboot1284.build.core=arduino:arduino
+optiboot1284.build.variant=arduino:standard
+
+optiboot1284.upload.maximum_size=130048
+optiboot1284.upload.maximum_data_size=16384
+
+# Select full swing crystal oscillator (F7 rather than FF)
+optiboot1284.bootloader.low_fuses=0xF7
+optiboot1284.bootloader.high_fuses=0xDE
+optiboot1284.bootloader.extended_fuses=0x05
+optiboot1284.bootloader.file=optiboot/optiboot_atmega1284p.hex
+
+optiboot1284.build.mcu=atmega1284p
+
+##############################################################
+
+
+optibootm32.name=Optiboot on Mega32
+
+optibootm32.upload.tool=arduino:avrdude
+optibootm32.upload.protocol=arduino
+optibootm32.upload.speed=115200
+
+optibootm32.bootloader.tool=arduino:avrdude
+optibootm32.bootloader.unlock_bits=0x3F
+optibootm32.bootloader.lock_bits=0x2F
+
+optibootm32.build.f_cpu=16000000L
+
+optibootm32.build.board=AVR_M32
+optibootm32.build.core=arduino:arduino
+optibootm32.build.variant=arduino:standard
+
+optibootm32.upload.maximum_size=130048
+optibootm32.upload.maximum_data_size=8192
+
+optibootm32.bootloader.low_fuses=0xBF
+optibootm32.bootloader.high_fuses=0xCE
+optibootm32.bootloader.extended_fuses=0xFF
+optibootm32.bootloader.file=optiboot/optiboot_atmega32.hex
+
+optibootm32.build.mcu=atmega32
+
+
+##############################################################
+
+optiboott84.name=Optiboot on Tiny84
+
+optiboott84.menu.mhz.8MHz=8MHz (int)
+optiboott84.menu.mhz.8MHz.build.f_cpu=8000000L
+optiboott84.menu.mhz.8MHz.upload.speed=57600
+optiboott84.menu.mhz.8MHz.bootloader.file=optiboot/optiboot_attiny84_8mhz.hex
+optiboott84.menu.mhz.8MHz.bootloader.low_fuses=0xE2
+optiboott84.menu.mhz.8MHz.bootloader.high_fuses=0xDE
+optiboott84.menu.mhz.8MHz.bootloader.extended_fuses=0xFE
+
+optiboott84.menu.mhz.1MHz=1MHz (int)
+optiboott84.menu.mhz.1MHz.build.f_cpu=1000000L
+optiboott84.menu.mhz.1MHz.upload.speed=9600
+optiboott84.menu.mhz.1MHz.bootloader.file=optiboot/optiboot_attiny84.hex
+optiboott84.menu.mhz.1MHz.bootloader.low_fuses=0x62
+optiboott84.menu.mhz.1MHz.bootloader.high_fuses=0xDE
+optiboott84.menu.mhz.1MHz.bootloader.extended_fuses=0xFE
+
+optiboott84.upload.tool=arduino:avrdude
+optiboott84.upload.protocol=arduino
+optiboott84.upload.speed=9600
+
+optiboott84.bootloader.tool=arduino:avrdude
+optiboott84.bootloader.unlock_bits=0x3F
+optiboott84.bootloader.lock_bits=0x2F
+
+optiboott84.build.f_cpu=1000000L
+
+optiboott84.build.board=AVR_TINY
+optiboott84.build.core=tiny:tiny
+optiboott84.build.variant=tiny:tiny
+
+optiboott84.upload.maximum_size=7600
+optiboott84.upload.maximum_data_size=512
+
+optiboott84.build.mcu=attiny84
+
+##############################################################
+
+optiboot2560.name=Optiboot on Mega2560
+
+optiboot2560.upload.tool=arduino:avrdude
+optiboot2560.upload.protocol=arduino
+optiboot2560.upload.speed=115200
+
+optiboot2560.bootloader.tool=arduino:avrdude
+optiboot2560.bootloader.unlock_bits=0x3F
+optiboot2560.bootloader.lock_bits=0x2F
+
+optiboot2560.build.f_cpu=16000000L
+
+optiboot2560.build.board=AVR_MEGA
+optiboot2560.build.core=arduino:arduino
+optiboot2560.build.variant=arduino:mega
+
+optiboot2560.upload.maximum_size=261120
+optiboot2560.upload.maximum_data_size=8192
+
+optiboot2560.bootloader.low_fuses=0xF7
+optiboot2560.bootloader.high_fuses=0xDE
+optiboot2560.bootloader.extended_fuses=0xFD
+optiboot2560.bootloader.file=optiboot/optiboot_atmega2560.hex
+
+optiboot2560.build.mcu=atmega2560
+
+##############################################################
+
+
+optibootxmini168b.name=Optiboot Xplained Mini 168pb
+
+optibootxmini168b.upload.tool=arduino:avrdude
+optibootxmini168b.upload.protocol=arduino
+optibootxmini168b.upload.speed=57600
+
+optibootxmini168b.bootloader.tool=arduino:avrdude
+optibootxmini168b.bootloader.unlock_bits=0x3F
+optibootxmini168b.bootloader.lock_bits=0x2F
+
+optibootxmini168b.build.f_cpu=16000000L
+
+optibootxmini168b.build.board=AVR_UNO
+optibootxmini168b.build.core=arduino:arduino
+optibootxmini168b.build.variant=arduino:standard
+
+optibootxmini168b.upload.maximum_size=15872
+optibootxmini168b.upload.maximum_data_size=1024
+
+optibootxmini168b.bootloader.low_fuses=0xBF
+optibootxmini168b.bootloader.high_fuses=0xCE
+optibootxmini168b.bootloader.extended_fuses=0xFF
+optibootxmini168b.bootloader.file=optiboot/optiboot_xplained168b.hex
+
+optibootxmini168b.build.mcu=atmega168
+
+#############################
+
+
+optibootxmini328pb.name=Optiboot Xplained Mini 328pb
+
+optibootxmini328pb.upload.tool=arduino:avrdude
+optibootxmini328pb.upload.protocol=arduino
+optibootxmini328pb.upload.speed=57600
+
+optibootxmini328pb.bootloader.tool=arduino:avrdude
+optibootxmini328pb.bootloader.unlock_bits=0x3F
+optibootxmini328pb.bootloader.lock_bits=0x2F
+
+optibootxmini328pb.build.f_cpu=16000000L
+
+optibootxmini328pb.build.board=AVR_UNO
+optibootxmini328pb.build.core=arduino:arduino
+optibootxmini328pb.build.variant=arduino:standard
+
+optibootxmini328pb.upload.maximum_size=32128
+optibootxmini328pb.upload.maximum_data_size=1024
+
+optibootxmini328pb.bootloader.low_fuses=0xBF
+optibootxmini328pb.bootloader.high_fuses=0xCE
+optibootxmini328pb.bootloader.extended_fuses=0xFF
+optibootxmini328pb.bootloader.file=optiboot/optiboot_xplained328pb.hex
+
+optibootxmini328pb.build.mcu=atmega328p
+
+#############################
+
+
+optibootxmini328p.name=Optiboot Xplained Mini 328p
+
+optibootxmini328p.upload.tool=arduino:avrdude
+optibootxmini328p.upload.protocol=arduino
+optibootxmini328p.upload.speed=57600
+
+optibootxmini328p.bootloader.tool=arduino:avrdude
+optibootxmini328p.bootloader.unlock_bits=0x3F
+optibootxmini328p.bootloader.lock_bits=0x2F
+
+optibootxmini328p.build.f_cpu=16000000L
+
+optibootxmini328p.build.board=AVR_UNO
+optibootxmini328p.build.core=arduino:arduino
+optibootxmini328p.build.variant=arduino:standard
+
+optibootxmini328p.upload.maximum_size=32128
+optibootxmini328p.upload.maximum_data_size=1024
+
+optibootxmini328p.bootloader.low_fuses=0xBF
+optibootxmini328p.bootloader.high_fuses=0xCE
+optibootxmini328p.bootloader.extended_fuses=0xFF
+optibootxmini328p.bootloader.file=optiboot/optiboot_xplained328p.hex
+
+optibootxmini328p.build.mcu=atmega328p
diff --git a/ActualOptiboot/optiboot/boards.txt b/ActualOptiboot/optiboot/boards.txt
new file mode 100644
index 0000000..5b4f2f6
--- /dev/null
+++ b/ActualOptiboot/optiboot/boards.txt
@@ -0,0 +1,351 @@
+# Optiboot Arduino support
+# http://optiboot.googlecode.com
+# Peter Knight, 2010
+# Bill Westfield, 2013 - now includes build.variant for 1.0.2 and later
+
+##############################################################
+
+atmega328o.name=[Optiboot] Arduino Duemilanove or Nano w/ ATmega328
+atmega328o.upload.protocol=arduino
+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:arduino
+atmega328o.build.variant=arduino:standard
+
+##############################################################
+
+diecimilao.name=[Optiboot] Arduino Diecimila, Duemilanove, Nano, NG w/ ATmega168
+diecimilao.upload.protocol=arduino
+diecimilao.upload.maximum_size=15872
+diecimilao.upload.speed=115200
+diecimilao.bootloader.low_fuses=0xff
+diecimilao.bootloader.high_fuses=0xdd
+diecimilao.bootloader.extended_fuses=0x04
+diecimilao.bootloader.path=optiboot
+diecimilao.bootloader.file=optiboot_diecimila.hex
+diecimilao.bootloader.unlock_bits=0x3F
+diecimilao.bootloader.lock_bits=0x0F
+diecimilao.build.mcu=atmega168
+diecimilao.build.f_cpu=16000000L
+diecimilao.build.core=arduino:arduino
+diecimilao.build.variant=arduino:standard
+
+##############################################################
+
+minio.name=[Optiboot] Arduino Mini
+minio.upload.protocol=arduino
+minio.upload.maximum_size=15872
+minio.upload.speed=115200
+minio.bootloader.low_fuses=0xff
+minio.bootloader.high_fuses=0xdd
+minio.bootloader.extended_fuses=0x02
+minio.bootloader.path=optiboot
+minio.bootloader.file=optiboot_ng.hex
+minio.bootloader.unlock_bits=0x3F
+minio.bootloader.lock_bits=0x0F
+minio.build.mcu=atmega168
+minio.build.f_cpu=16000000L
+minio.build.core=arduino:arduino
+minio.build.variant=arduino:eightanaloginputs
+
+##############################################################
+
+lilypad328o.name=[Optiboot] LilyPad Arduino w/ ATmega328
+lilypad328o.upload.protocol=arduino
+lilypad328o.upload.maximum_size=32256
+lilypad328o.upload.speed=115200
+lilypad328o.bootloader.low_fuses=0xff
+lilypad328o.bootloader.high_fuses=0xdc
+lilypad328o.bootloader.extended_fuses=0x05
+lilypad328o.bootloader.path=optiboot
+lilypad328o.bootloader.file=optiboot_atmega328_pro_8MHz.hex
+lilypad328o.bootloader.unlock_bits=0x3F
+lilypad328o.bootloader.lock_bits=0x0F
+lilypad328o.build.mcu=atmega328p
+lilypad328o.build.f_cpu=8000000L
+lilypad328o.build.core=arduino:arduino
+lilypad328o.build.variant=arduino:standard
+
+##############################################################
+
+lilypado.name=[Optiboot] LilyPad Arduino w/ ATmega168
+lilypado.upload.protocol=arduino
+lilypado.upload.maximum_size=15872
+lilypado.upload.speed=115200
+lilypado.bootloader.low_fuses=0xe2
+lilypado.bootloader.high_fuses=0xdd
+lilypado.bootloader.extended_fuses=0x02
+lilypado.bootloader.path=lilypad
+lilypado.bootloader.file=optiboot_lilypad.hex
+lilypado.bootloader.unlock_bits=0x3F
+lilypado.bootloader.lock_bits=0x0F
+lilypado.build.mcu=atmega168
+lilypado.build.f_cpu=8000000L
+lilypado.build.core=arduino:arduino
+lilypado.build.variant=arduino:standard
+
+##############################################################
+
+pro328o.name=[Optiboot] Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega328
+pro328o.upload.protocol=arduino
+pro328o.upload.maximum_size=32256
+pro328o.upload.speed=115200
+pro328o.bootloader.low_fuses=0xff
+pro328o.bootloader.high_fuses=0xdc
+pro328o.bootloader.extended_fuses=0x05
+pro328o.bootloader.path=optiboot
+pro328o.bootloader.file=optiboot_atmega328_pro_8MHz.hex
+pro328o.bootloader.unlock_bits=0x3F
+pro328o.bootloader.lock_bits=0x0F
+pro328o.build.mcu=atmega328p
+pro328o.build.f_cpu=8000000L
+pro328o.build.core=arduino:arduino
+pro328o.build.variant=arduino:standard
+
+##############################################################
+
+proo.name=[Optiboot] Arduino Pro or Pro Mini (3.3V, 8 MHz) w/ ATmega168
+proo.upload.protocol=arduino
+proo.upload.maximum_size=15872
+proo.upload.speed=115200
+proo.bootloader.low_fuses=0xc6
+proo.bootloader.high_fuses=0xdd
+proo.bootloader.extended_fuses=0x02
+proo.bootloader.path=optiboot
+proo.bootloader.file=optiboot_pro_8MHz.hex
+proo.bootloader.unlock_bits=0x3F
+proo.bootloader.lock_bits=0x0F
+proo.build.mcu=atmega168
+proo.build.f_cpu=8000000L
+proo.build.core=arduino:arduino
+proo.build.variant=arduino:standard
+
+##############################################################
+
+megao.name=[Optiboot] Arduino Mega1280
+megao.upload.protocol=arduino
+megao.upload.maximum_size=130048
+megao.upload.speed=115200
+megao.bootloader.low_fuses=0xff
+megao.bootloader.high_fuses=0xde
+megao.bootloader.extended_fuses=0xf5
+megao.bootloader.path=optiboot
+megao.bootloader.file=optiboot_atmega1280.hex
+megao.bootloader.unlock_bits=0x3F
+megao.bootloader.lock_bits=0x0F
+megao.build.mcu=atmega1280
+megao.build.f_cpu=16000000L
+megao.build.core=arduino:arduino
+megao.build.variant=arduino:mega
+
+atmega8o.name=[Optiboot] Arduino NG or older w/ ATmega8
+atmega8o.upload.protocol=arduino
+atmega8o.upload.maximum_size=7680
+atmega8o.upload.speed=115200
+atmega8o.bootloader.low_fuses=0xbf
+atmega8o.bootloader.high_fuses=0xdc
+atmega8o.bootloader.path=optiboot
+atmega8o.bootloader.file=optiboot_atmega8.hex
+atmega8o.bootloader.unlock_bits=0x3F
+atmega8o.bootloader.lock_bits=0x0F
+atmega8o.build.mcu=atmega8
+atmega8o.build.f_cpu=16000000L
+atmega8o.build.core=arduino:arduino
+atmega8o.build.variant=arduino:standard
+
+atmega88o.name=[Optiboot] Arduino NG or older w/ ATmega88
+atmega88o.upload.protocol=arduino
+atmega88o.upload.maximum_size=7680
+atmega88o.upload.speed=115200
+atmega88o.bootloader.low_fuses=0xff
+atmega88o.bootloader.high_fuses=0xdd
+atmega88o.bootloader.extended_fuses=0x04
+atmega88o.bootloader.path=optiboot
+atmega88o.bootloader.file=optiboot_atmega88.hex
+atmega88o.bootloader.unlock_bits=0x3F
+atmega88o.bootloader.lock_bits=0x0F
+atmega88o.build.mcu=atmega88
+atmega88o.build.f_cpu=16000000L
+atmega88o.build.core=arduino:arduino
+atmega88o.build.variant=arduino:standard
+
+##############################################################
+#
+# sanguinoo.name=[Optiboot] Sanguino (work in progress)
+# sanguinoo.upload.protocol=arduino
+# sanguinoo.upload.maximum_size=63488
+# sanguinoo.upload.speed=115200
+# sanguinoo.bootloader.low_fuses=0xff
+# sanguinoo.bootloader.high_fuses=0xdc
+# sanguinoo.bootloader.extended_fuses=0xfd
+# sanguinoo.bootloader.path=optiboot
+# sanguinoo.bootloader.file=optiboot_atmega644p.hex
+# sanguinoo.bootloader.unlock_bits=0x3F
+# sanguinoo.bootloader.lock_bits=0x0F
+# sanguinoo.build.mcu=atmega644p
+# sanguinoo.build.f_cpu=16000000L
+# sanguinoo.build.core=sanguino:sanguino
+# sanguinoo.build.variant=sanguino:sanguino
+
+##############################################################
+#
+# lumineto.name=[Optiboot] Luminet (work in progress)
+# lumineto.upload.protocol=arduino
+# 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=luminet:luminet
+
+##############################################################
+
+atmega32o.name=[Optiboot] ATmega32 based board
+atmega32o.upload.protocol=arduino
+atmega32o.upload.maximum_size=32256
+atmega32o.upload.speed=115200
+atmega32o.bootloader.low_fuses=0xff
+atmega32o.bootloader.high_fuses=0xde
+atmega32o.bootloader.path=optiboot
+atmega32o.bootloader.file=optiboot_atmega32.hex
+atmega32o.bootloader.unlock_bits=0x3F
+atmega32o.bootloader.lock_bits=0x0F
+atmega32o.build.mcu=atmega32
+atmega32o.build.f_cpu=16000000L
+atmega32o.build.core=arduino:arduino
+atmega32o.build.variant=arduino:standard
+
+##############################################################
+
+atmega1284o.name=[Optiboot] ATmega1284p
+atmega1284o.upload.protocol=arduino
+atmega1284o.upload.maximum_size=130048
+atmega1284o.upload.speed=115200
+atmega1284o.bootloader.low_fuses=0xf7
+atmega1284o.bootloader.high_fuses=0xde
+atmega1284o.bootloader.extended_fuses=0x05
+atmega1284o.bootloader.path=optiboot
+atmega1284o.bootloader.file=optiboot_atmega1284p.hex
+atmega1284o.bootloader.unlock_bits=0x3F
+atmega1284o.bootloader.lock_bits=0x0F
+atmega1284o.build.mcu=atmega1284p
+atmega1284o.build.f_cpu=16000000L
+atmega1284o.build.core=arduino:arduino
+atmega1284o.build.variant=arduino:standard
+
+##############################################################
+
+mega2560o.name=[Optiboot] Arduino Mega2560
+mega2560o.upload.protocol=arduino
+mega2560o.upload.maximum_size=261120
+mega2560o.upload.speed=115200
+mega2560o.bootloader.low_fuses=0xf7
+mega2560o.bootloader.high_fuses=0xde
+mega2560o.bootloader.extended_fuses=0xfd
+mega2560o.bootloader.path=optiboot
+mega2560o.bootloader.file=optiboot_atmega2560.hex
+mega2560o.bootloader.unlock_bits=0x3F
+mega2560o.bootloader.lock_bits=0x0F
+mega2560o.build.mcu=atmega2560
+mega2560o.build.f_cpu=16000000L
+mega2560o.build.core=arduino:arduino
+mega2560o.build.variant=arduino:mega
+
+##############################################################
+
+optibootxmini168b.name=Optiboot Xplained Mini 168pb
+
+optibootxmini168b.upload.tool=arduino:avrdude
+optibootxmini168b.upload.protocol=arduino
+optibootxmini168b.upload.speed=57600
+
+optibootxmini168b.bootloader.tool=arduino:avrdude
+optibootxmini168b.bootloader.unlock_bits=0x3F
+optibootxmini168b.bootloader.lock_bits=0x2F
+
+optibootxmini168b.build.f_cpu=16000000L
+
+optibootxmini168b.build.board=AVR_UNO
+optibootxmini168b.build.core=arduino:arduino
+optibootxmini168b.build.variant=arduino:standard
+
+optibootxmini168b.upload.maximum_size=15872
+optibootxmini168b.upload.maximum_data_size=1024
+
+optibootxmini168b.bootloader.low_fuses=0xBF
+optibootxmini168b.bootloader.high_fuses=0xCE
+optibootxmini168b.bootloader.extended_fuses=0xFF
+optibootxmini168b.bootloader.file=optiboot/optiboot_xplained168b.hex
+
+optibootxmini168b.build.mcu=atmega168
+
+#############################
+
+
+optibootxmini328pb.name=Optiboot Xplained Mini 328pb
+
+optibootxmini328pb.upload.tool=arduino:avrdude
+optibootxmini328pb.upload.protocol=arduino
+optibootxmini328pb.upload.speed=57600
+
+optibootxmini328pb.bootloader.tool=arduino:avrdude
+optibootxmini328pb.bootloader.unlock_bits=0x3F
+optibootxmini328pb.bootloader.lock_bits=0x2F
+
+optibootxmini328pb.build.f_cpu=16000000L
+
+optibootxmini328pb.build.board=AVR_UNO
+optibootxmini328pb.build.core=arduino:arduino
+optibootxmini328pb.build.variant=arduino:standard
+
+optibootxmini328pb.upload.maximum_size=32128
+optibootxmini328pb.upload.maximum_data_size=1024
+
+optibootxmini328pb.bootloader.low_fuses=0xBF
+optibootxmini328pb.bootloader.high_fuses=0xCE
+optibootxmini328pb.bootloader.extended_fuses=0xFF
+optibootxmini328pb.bootloader.file=optiboot/optiboot_xplained328pb.hex
+
+optibootxmini328pb.build.mcu=atmega328p
+
+#############################
+
+
+optibootxmini328p.name=Optiboot Xplained Mini 328p
+
+optibootxmini328p.upload.tool=arduino:avrdude
+optibootxmini328p.upload.protocol=arduino
+optibootxmini328p.upload.speed=57600
+
+optibootxmini328p.bootloader.tool=arduino:avrdude
+optibootxmini328p.bootloader.unlock_bits=0x3F
+optibootxmini328p.bootloader.lock_bits=0x2F
+
+optibootxmini328p.build.f_cpu=16000000L
+
+optibootxmini328p.build.board=AVR_UNO
+optibootxmini328p.build.core=arduino:arduino
+optibootxmini328p.build.variant=arduino:standard
+
+optibootxmini328p.upload.maximum_size=32128
+optibootxmini328p.upload.maximum_data_size=1024
+
+optibootxmini328p.bootloader.low_fuses=0xBF
+optibootxmini328p.bootloader.high_fuses=0xCE
+optibootxmini328p.bootloader.extended_fuses=0xFF
+optibootxmini328p.bootloader.file=optiboot/optiboot_xplained328p.hex
+
+optibootxmini328p.build.mcu=atmega328p
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile
new file mode 100644
index 0000000..5b0341f
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile
@@ -0,0 +1,616 @@
+# 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...
+#
+# Edit History
+# 201406xx: WestfW: More Makefile restructuring.
+# Split off Makefile.1284, Makefile.extras, Makefile.custom
+# So that in theory, the main Makefile contains only the
+# official platforms, and does not need to be modified to
+# add "less supported" chips and boards.
+# 201303xx: WestfW: Major Makefile restructuring.
+# Allows options on Make command line "make xx LED=B3"
+# (see also pin_defs.h)
+# Divide into "chip" targets and "board" targets.
+# Most boards are (recursive) board targets with options.
+# Move isp target to separate makefile (fixes m8 EFUSE)
+# Some (many) targets will now be rebuilt when not
+# strictly necessary, so that options will be included.
+# (any "make" with options will always compile.)
+# Set many variables with ?= so they can be overridden
+# Use arduinoISP settings as default for ISP targets
+#
+#
+# * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
+# * This software is licensed under version 2 of the Gnu Public Licence.
+# * See optiboot.c for details.
+
+HELPTEXT = ""
+#----------------------------------------------------------------------
+#
+# 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
+
+# export symbols to recursive makes (for ISP)
+export
+
+# defaults
+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)
+SH := bash
+
+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.
+# (except that in 1.5.x, there's an additional level of "up")
+TESTDIR := $(firstword $(wildcard ../../../tools/*))
+ifeq (,$(TESTDIR))
+# Arduino 1.5.x tool location compared to optiboot dir
+ TOOLROOT = ../../../../tools
+else
+# Arduino 1.0 (and earlier) tool location
+ TOOLROOT = ../../../tools
+endif
+GCCROOT = $(TOOLROOT)/avr/bin/
+
+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
+SH = sh
+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
+
+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
+#
+# End of build environment code.
+
+
+OBJ = $(PROGRAM).o
+OPTIMIZE = -Os -fno-split-wide-types -mrelax
+
+DEFS =
+
+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 -nostartfiles
+
+OBJCOPY = $(GCCROOT)avr-objcopy
+OBJDUMP = $(call fixpath,$(GCCROOT)avr-objdump)
+
+SIZE = $(GCCROOT)avr-size
+
+#
+# Make command-line Options.
+# Permit commands like "make atmega328 LED_START_FLASHES=10" to pass the
+# appropriate parameters ("-DLED_START_FLASHES=10") to gcc
+#
+
+HELPTEXT += "Option BAUD_RATE=nnnn - set the bit rate for communications\n"
+ifdef BAUD_RATE
+BAUD_RATE_CMD = -DBAUD_RATE=$(BAUD_RATE)
+dummy = FORCE
+else
+BAUD_RATE_CMD = -DBAUD_RATE=115200
+endif
+
+HELPTEXT += "Option LED=B3 - set LED pin to particular port/bit\n"
+ifdef LED
+LED_CMD = -DLED=$(LED)
+dummy = FORCE
+endif
+
+HELPTEXT += "Option LED_START_FLASHES=n - set number of LED flashes when bootloader starts\n"
+ifdef LED_START_FLASHES
+LED_START_FLASHES_CMD = -DLED_START_FLASHES=$(LED_START_FLASHES)
+dummy = FORCE
+else
+LED_START_FLASHES_CMD = -DLED_START_FLASHES=3
+endif
+
+HELPTEXT += "Option LED_DATA_FLASH=1 - flash the LED each time data is received.\n"
+ifdef LED_DATA_FLASH
+ifneq ($(LED_DATA_FLASH), 0)
+LED_DATA_FLASH_CMD = -DLED_DATA_FLASH=1
+dummy = FORCE
+endif
+endif
+
+HELPTEXT += "Option LED_START_ON=1 - Turn the LED on at bootload start\n"
+ifdef LED_START_ON
+ifneq ($(LED_START_ON), 0)
+LED_START_ON_CMD = -DLED_START_ON=1
+endif
+dummy = FORCE
+endif
+
+HELPTEXT += "Option BIGBOOT=1 - enable extra features up to 1kbytes\n"
+# BIGBOOT: Include extra features, up to 1K.
+ifdef BIGBOOT
+ifneq ($(BIGBOOT), 0)
+BIGBOOT_CMD = -DBIGBOOT=1
+dummy = FORCE
+endif
+endif
+
+HELPTEXT += "Option SUPPORT_EEPROM=1 - Include code to read/write EEPROM\n"
+ifdef SUPPORT_EEPROM
+ifneq ($(SUPPORT_EEPROM), 0)
+SUPPORT_EEPROM_CMD = -DSUPPORT_EEPROM
+dummy = FORCE
+endif
+endif
+
+
+HELPTEXT += "Option SOFT_UART=1 - use a software (bit-banged) UART\n"
+ifdef SOFT_UART
+ifneq ($(SOFT_UART), 0)
+SOFT_UART_CMD = -DSOFT_UART=1
+dummy = FORCE
+endif
+endif
+
+ifdef SINGLESPEED
+ifneq ($(SINGLESPEED), 0)
+SS_CMD = -DSINGLESPEED=1
+endif
+endif
+
+COMMON_OPTIONS = $(BAUD_RATE_CMD) $(LED_START_FLASHES_CMD) $(BIGBOOT_CMD)
+COMMON_OPTIONS += $(SOFT_UART_CMD) $(LED_DATA_FLASH_CMD) $(LED_CMD) $(SS_CMD)
+COMMON_OPTIONS += $(SUPPORT_EEPROM_CMD) $(LED_START_ON_CMD)
+
+#UART is handled separately and only passed for devices with more than one.
+HELPTEXT += "Option UART=n - use UARTn for communications\n"
+ifdef UART
+UART_CMD = -DUART=$(UART)
+endif
+
+
+# Not supported yet
+# ifdef TIMEOUT_MS
+# TIMEOUT_MS_CMD = -DTIMEOUT_MS=$(TIMEOUT_MS)
+# dummy = FORCE
+# endif
+#
+
+#.PRECIOUS: %.elf
+
+#---------------------------------------------------------------------------
+# "Chip-level Platform" targets.
+# A "Chip-level Platform" compiles for a particular chip, but probably does
+# not have "standard" values for things like clock speed, LED pin, etc.
+# Makes for chip-level platforms should usually explicitly define their
+# options like: "make atmega1285 AVR_FREQ=16000000L LED=D0"
+#---------------------------------------------------------------------------
+#
+# Note about fuses:
+# 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.
+#---------------------------------------------------------------------------
+#
+
+HELPTEXT += "\n-------------\n\n"
+
+# Test platforms
+# Virtual boot block test
+HELPTEXT += "target virboot8 - ATmega8 with virtual boot partition\n"
+virboot8: TARGET = atmega8
+virboot8: MCU_TARGET = atmega8
+virboot8: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION' '-Dsave_vect_num=EE_RDY_vect_num'
+virboot8: AVR_FREQ ?= 16000000L
+# Start address of 1D80 allows for size up to 640 bytes, app up to 7552
+virboot8: LDSECTIONS = -Wl,--section-start=.text=0x1d80 -Wl,--section-start=.version=0x1ffe
+virboot8: $(PROGRAM)_virboot8.hex
+virboot8: $(PROGRAM)_virboot8.lst
+
+
+HELPTEXT += "target virboot328p - ATmega328 with virtual boot partition\n"
+virboot328: TARGET = atmega328
+virboot328: MCU_TARGET = atmega328p
+virboot328: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION'
+virboot328: AVR_FREQ ?= 16000000L
+virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7d80 -Wl,--section-start=.version=0x7ffe
+virboot328: $(PROGRAM)_virboot328.hex
+virboot328: $(PROGRAM)_virboot328.lst
+
+virboot328_isp: virboot328
+virboot328_isp: TARGET = virboot328
+virboot328_isp: MCU_TARGET = atmega328p
+# no boot section, SPIEN
+virboot328_isp: HFUSE ?= DF
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+virboot328_isp: LFUSE ?= FF
+# 2.7V brownout
+virboot328_isp: EFUSE ?= FD
+virboot328_isp: isp
+
+virboot8_isp: virboot8
+virboot8_isp: TARGET = virboot8
+virboot8_isp: MCU_TARGET = atmega8
+# SPIEN, CKOPT (for full swing xtal), boot section 1k
+# Note that we need boot section to include our SPM instructions,
+# even though we do not enable BOOTRST
+virboot8_isp: HFUSE ?= CB
+# 2.7V brownout, 16MHz Xtal, 16KCK/14CK+65ms
+virboot8_isp: LFUSE ?= BF
+virboot8_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
+
+# ATmega8
+#
+HELPTEXT += "target atmega8 - ATmega8, ATmega8A, ATmega8L\n"
+atmega8: TARGET = atmega8
+atmega8: MCU_TARGET = atmega8
+atmega8: CFLAGS += $(COMMON_OPTIONS)
+atmega8: AVR_FREQ ?= 16000000L
+ifndef BIGBOOT
+atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe -Wl,--gc-sections -Wl,--undefined=optiboot_version
+else
+atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1c00 -Wl,--section-start=.version=0x1ffe -Wl,--gc-sections -Wl,--undefined=optiboot_version
+endif
+atmega8: $(PROGRAM)_atmega8.hex
+atmega8: $(PROGRAM)_atmega8.lst
+
+atmega8_isp: atmega8
+atmega8_isp: TARGET = atmega8
+atmega8_isp: MCU_TARGET = atmega8
+ifndef BIGBOOT
+# SPIEN, CKOPT (for full swing xtal), Bootsize=512B
+atmega8_isp: HFUSE ?= CC
+else
+# SPIEN, CKOPT (for full swing xtal), Bootsize=1024B
+atmega8_isp: HFUSE ?= CA
+endif
+# 2.7V brownout, 16MHz Xtal, 16KCK/14CK+65ms
+atmega8_isp: LFUSE ?= BF
+atmega8_isp: isp
+
+HELPTEXT += "target atmega168 - ATmega168, ATmega168A\n"
+atmega168: TARGET = atmega168
+atmega168: MCU_TARGET = atmega168
+atmega168: CFLAGS += $(COMMON_OPTIONS)
+atmega168: AVR_FREQ ?= 16000000L
+ifndef BIGBOOT
+atmega168: LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe
+else
+atmeg168: LDSECTIONS = -Wl,--section-start=.text=0x3c00 -Wl,--section-start=.version=0x3ffe
+endif
+atmega168: $(PROGRAM)_atmega168.hex
+atmega168: $(PROGRAM)_atmega168.lst
+
+atmega168_isp: atmega168
+atmega168_isp: TARGET = atmega168
+# 2.7V brownout
+atmega168_isp: HFUSE ?= DD
+# Full swing (16MHz) 16KCK/14CK+65ms
+atmega168_isp: LFUSE ?= F7
+ifndef BIGBOOT
+# 512 byte boot
+atmega168_isp: EFUSE ?= 04
+else
+# 1024byte boot
+atmega168_isp: EFUSE ?= FA
+endif
+atmega168_isp: isp
+
+HELPTEXT += "target atmega328 - ATmega328p\n"
+atmega328: TARGET = atmega328
+atmega328: MCU_TARGET = atmega328p
+atmega328: CFLAGS += $(COMMON_OPTIONS)
+atmega328: AVR_FREQ ?= 16000000L
+ifndef BIGBOOT
+atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
+else
+# bigboot version is 1k long; starts earlier
+atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7c00 -Wl,--section-start=.version=0x7ffe
+endif
+atmega328: $(PROGRAM)_atmega328.hex
+atmega328: $(PROGRAM)_atmega328.lst
+
+atmega328_isp: atmega328
+atmega328_isp: TARGET = atmega328
+atmega328_isp: MCU_TARGET = atmega328p
+ifndef BIGBOOT
+# 512 byte boot, SPIEN
+atmega328_isp: HFUSE ?= DE
+else
+# 1k byte boot, SPIEN
+atmega328_isp: HFUSE ?= DC
+endif
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega328_isp: LFUSE ?= FF
+# 2.7V brownout
+atmega328_isp: EFUSE ?= FD
+atmega328_isp: isp
+
+#Atmega1280
+HELPTEXT += "target atmega1280 - ATmega1280 (100pin, 128k)\n"
+atmega1280: MCU_TARGET = atmega1280
+atmega1280: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT $(UART_CMD)
+atmega1280: AVR_FREQ ?= 16000000L
+atmega1280: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
+atmega1280: $(PROGRAM)_atmega1280.hex
+atmega1280: $(PROGRAM)_atmega1280.lst
+
+
+
+#---------------------------------------------------------------------------
+# "Board-level Platform" targets.
+# A "Board-level Platform" implies a manufactured platform with a particular
+# AVR_FREQ, LED, and so on. Parameters are not particularly changable from
+# the "make" command line.
+# Most of the board-level platform builds should envoke make recursively
+# appropriate specific options
+#---------------------------------------------------------------------------
+# 20MHz clocked platforms
+#
+# These are capable of 230400 baud, or 115200 baud on PC (Arduino Avrdude issue)
+#
+
+pro20: TARGET = pro_20mhz
+pro20: CHIP = atmega168
+pro20:
+ "$(MAKE)" atmega168 AVR_FREQ=20000000L LED_START_FLASHES=3
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+pro20_isp: pro20
+pro20_isp: TARGET = pro_20mhz
+# 4.3V brownout (for max speed!)
+pro20_isp: HFUSE ?= DC
+# Full swing xtal (20MHz) 258CK/14CK+4.1ms
+pro20_isp: LFUSE ?= F7
+# 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: CHIP = atmega168
+pro16:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L LED_START_FLASHES=3
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).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 ?= F7
+# 512 byte boot
+pro16_isp: EFUSE ?= 04
+pro16_isp: isp
+
+diecimila: TARGET = diecimila
+diecimila: CHIP = atmega168
+diecimila:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L LED_START_FLASHES=3
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).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 ?= F7
+# 512 byte boot
+diecimila_isp: EFUSE ?= 04
+diecimila_isp: isp
+
+# MEGA1280 Board (this is different from the atmega1280 chip platform)
+# Mega has a minimum boot size of 1024 bytes, so enable extra functions
+# Note that optiboot does not (can not) work on the MEGA2560
+#mega: TARGET = atmega1280
+mega1280: atmega1280
+
+mega1280_isp: mega1280
+mega1280_isp: TARGET = atmega1280
+mega1280_isp: MCU_TARGET = atmega1280
+# 1024 byte boot
+mega1280_isp: HFUSE ?= DE
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+mega1280_isp: LFUSE ?= FF
+# 2.7V brownout; wants F5 for some reason...
+mega1280_isp: EFUSE ?= F5
+mega1280_isp: isp
+
+# 8MHz clocked platforms
+#
+# These are capable of 115200 baud
+# Note that "new" Arduinos with an AVR as USB/Serial converter will NOT work
+# with an 8MHz target Arduino. The bitrate errors are in opposite directions,
+# and total too large a number.
+#
+
+lilypad: TARGET = $@
+lilypad: CHIP = atmega168
+lilypad:
+ "$(MAKE)" $(CHIP) AVR_FREQ=8000000L LED_START_FLASHES=3
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).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 is the same as a 8MHz lilypad, except for fuses.
+lilypad_resonator: lilypad
+
+lilypad_resonator_isp: lilypad
+lilypad_resonator_isp: TARGET = lilypad
+# 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: CHIP = atmega168
+pro8:
+ "$(MAKE)" $(CHIP) AVR_FREQ=8000000L LED_START_FLASHES=3
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).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: CHIP = atmega328
+atmega328_pro8:
+ "$(MAKE)" $(CHIP) AVR_FREQ=8000000L LED_START_FLASHES=3
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).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
+
+#
+# Include additional platforms
+include Makefile.atmel
+include Makefile.extras
+include Makefile.1284
+include Makefile.custom
+include Makefile.2560
+
+
+#---------------------------------------------------------------------------
+#
+# Generic build instructions
+#
+
+FORCE:
+
+baudcheck: FORCE
+ - @$(CC) --version
+ - @$(CC) $(CFLAGS) -E baudcheck.c -o baudcheck.tmp.sh
+ - @$(SH) baudcheck.tmp.sh
+
+isp: $(TARGET)
+ "$(MAKE)" -f Makefile.isp isp TARGET=$(TARGET)
+
+isp-stk500: $(PROGRAM)_$(TARGET).hex
+ $(STK500-1)
+ $(STK500-2)
+
+%.elf: $(OBJ) baudcheck $(dummy)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
+ $(SIZE) $@
+
+clean:
+ rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex *.tmp.sh
+
+%.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 $< $@
+
+help:
+ @echo $(HELPTEXT)
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.1284 b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.1284
new file mode 100644
index 0000000..a7485ee
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.1284
@@ -0,0 +1,146 @@
+#
+# Makefile for 40-pin AVR chips, including ATmega644 and ATmega1284
+#
+# * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
+# * This software is licensed under version 2 of the Gnu Public Licence.
+# * See optiboot.c for details.
+
+# Chip level targets
+#
+HELPTEXT += "target atmega644p - ATmega644p\n"
+atmega644p: TARGET = atmega644p
+atmega644p: MCU_TARGET = atmega644p
+atmega644p: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT
+atmega644p: AVR_FREQ ?= 16000000L
+atmega644p: LDSECTIONS = -Wl,--section-start=.text=0xfc00 -Wl,--section-start=.version=0xfffe
+atmega644p: CFLAGS += $(UART_CMD)
+atmega644p: $(PROGRAM)_atmega644p.hex
+atmega644p: $(PROGRAM)_atmega644p.lst
+
+HELPTEXT += "target atmega1284 - ATmega1284p (40 pin, 128k)\n"
+atmega1284: TARGET = atmega1284p
+atmega1284: MCU_TARGET = atmega1284p
+atmega1284: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT
+atmega1284: AVR_FREQ ?= 16000000L
+atmega1284: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe
+atmega1284: CFLAGS += $(UART_CMD)
+atmega1284: $(PROGRAM)_atmega1284p.hex
+atmega1284: $(PROGRAM)_atmega1284p.lst
+
+atmega1284p: atmega1284
+
+atmega1284_isp: atmega1284
+atmega1284_isp: TARGET = atmega1284p
+atmega1284_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+atmega1284_isp: HFUSE ?= DE
+# Full Swing xtal (16MHz) 16KCK/14CK+65ms
+atmega1284_isp: LFUSE ?= F7
+# 2.7V brownout
+atmega1284_isp: EFUSE ?= FD
+atmega1284_isp: isp
+
+#
+# Board-level targets
+#
+
+# Sanguino has a minimum boot size of 1024 bytes, so enable extra functions
+#
+HELPTEXT += "target sanguino - ATmega644p board\n"
+sanguino: TARGET = $@
+sanguino: CHIP = atmega644p
+sanguino:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L LED=B0
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+sanguino_isp: sanguino
+sanguino_isp: TARGET = sanguino
+sanguino_isp: MCU_TARGET = atmega644p
+# 1024 byte boot
+sanguino_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+sanguino_isp: LFUSE ?= F7
+# 2.7V brownout
+sanguino_isp: EFUSE ?= FD
+sanguino_isp: isp
+
+HELPTEXT += "target mighty1284 - ManiacBug Mighty1284 board\n"
+mighty1284: TARGET = $@
+mighty1284: CHIP = atmega1284p
+mighty1284:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L LED=B7
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+mighty1284_isp: mighty1284
+mighty1284_isp: TARGET = mighty1284
+mighty1284_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+mighty1284_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+mighty1284_isp: LFUSE ?= F7
+# 2.7V brownout
+mighty1284_isp: EFUSE ?= FD
+mighty1284_isp: isp
+
+HELPTEXT += "target bobuino - Crossroads 1284 board\n"
+bobuino: TARGET = $@
+bobuino: CHIP = atmega1284p
+bobuino:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L LED=B7
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+bobuino_isp: bobuino
+bobuino_isp: TARGET = bobuino
+bobuino_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+bobuino_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+bobuino_isp: LFUSE ?= F7
+# 2.7V brownout
+bobuino_isp: EFUSE ?= FD
+bobuino_isp: isp
+
+#
+# Wicked Devices "Wildfire" boards (1284 with wireless!)
+#
+
+HELPTEXT += "target wildfirev2 - Wicked Devices board\n"
+wildfirev2: TARGET = $@
+wildfirev2: CHIP = atmega1284p
+wildfirev2:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L LED=B7 BAUD_RATE=1000000
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+wildfirev2_isp: wildfirev2
+wildfirev2_isp: TARGET = wildfirev2
+wildfirev2_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+wildfirev2_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+wildfirev2_isp: LFUSE ?= F7
+# 2.7V brownout
+wildfirev2_isp: EFUSE ?= FD
+wildfirev2_isp: isp
+
+HELPTEXT += "target wildfirev3 - Wicked Devices board\n"
+wildfirev3: TARGET = $@
+wildfirev3: CHIP = atmega1284p
+wildfirev3:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L LED=B5
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+wildfirev3_isp: wildfirev3
+wildfirev3_isp: TARGET = wildfirev3
+wildfirev3_isp: MCU_TARGET = atmega1284p
+# 1024 byte boot
+wildfirev3_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+wildfirev3_isp: LFUSE ?= F7
+# 2.7V brownout
+wildfirev3_isp: EFUSE ?= FD
+wildfirev3_isp: isp
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.2560 b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.2560
new file mode 100644
index 0000000..a0df373
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.2560
@@ -0,0 +1,56 @@
+#
+# Makefile for 2560 AVR chips
+#
+# * Copyright 2013-2015 by Bill Westfield, Marek Wodzinski. Part of Optiboot.
+# * This software is licensed under version 2 of the Gnu Public Licence.
+# * See optiboot.c for details.
+
+# Chip level targets
+#
+HELPTEXT += "target atmega2560 - ATmega2560p (100pin, 256k)\n"
+atmega2560: TARGET = atmega2560
+atmega2560: MCU_TARGET = atmega2560
+atmega2560: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT
+atmega2560: AVR_FREQ ?= 16000000L
+atmega2560: LDSECTIONS = -Wl,--section-start=.text=0x3fc00 -Wl,--section-start=.version=0x3fffe
+atmega2560: CFLAGS += $(UART_CMD)
+atmega2560: $(PROGRAM)_atmega2560.hex
+atmega2560: $(PROGRAM)_atmega2560.lst
+
+
+atmega2560_isp: atmega2560
+atmega2560_isp: TARGET = atmega2560
+atmega2560_isp: MCU_TARGET = atmega2560
+# 1024 byte boot, JTAG disabled
+atmega2560_isp: HFUSE ?= DE
+# Full Swing xtal (16MHz) 16KCK/14CK+65ms
+atmega2560_isp: LFUSE ?= F7
+# 2.7V brownout
+atmega2560_isp: EFUSE ?= FD
+atmega2560_isp: isp
+
+#
+# Board-level targets
+#
+
+# Arduino/Geniuno MEGA 256 has a minimum boot size of 1024 bytes, so enable extra functions
+#
+HELPTEXT += "target mega2560 - Arduino MEGA2560 board, 2560ADK\n"
+mega2560: TARGET = $@
+mega2560: CHIP = atmega2560
+mega2560:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+mega2560_isp: mega256
+mega2560_isp: TARGET = mega2560
+mega2560_isp: MCU_TARGET = atmega2560
+# 1024 byte boot, JTAG disabled
+mega2560_isp: HFUSE ?= DE
+# Full swing xtal (16MHz) 16KCK/14CK+65ms
+mega2560_isp: LFUSE ?= F7
+# 2.7V brownout
+mega2560_isp: EFUSE ?= FD
+mega2560_isp: isp
+
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.atmel b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.atmel
new file mode 100644
index 0000000..8c45bc2
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.atmel
@@ -0,0 +1,37 @@
+#
+# Support for the Atmel Xplained mini eval boards that are mostly
+# compatible with Arduino. (168pb, 328p, and 328pb chips.)
+#
+# Currently these all masquerade as 168 or 328p, because the IDE
+# does not yet have compiler support for the -pb variants.
+#
+# These boards have an mEDBG debug chip that:
+# 1) means that optiboot can only be programmed via Atmel Studio
+# 2) prevents optiboot from working at 115200bps.
+# 3) provides 16MHz (at 5V) via Xin on the chip.
+#
+#
+#
+HELPTEXT += "target xplained168pb - Atmel Xplained Mini 168pb Eval board\n"
+xplained168pb: TARGET = $@
+xplained168pb: CHIP = atmega168
+xplained168pb:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L BAUD_RATE=57600
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+HELPTEXT += "target xplained328pb - Atmel Xplained Mini 328pb Eval board\n"
+xplained328pb: TARGET = $@
+xplained328pb: CHIP = atmega328
+xplained328pb:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L BAUD_RATE=57600
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
+HELPTEXT += "target xplained328p - Atmel Xplained Mini 328p Eval board\n"
+xplained328p: TARGET = $@
+xplained328p: CHIP = atmega328
+xplained328p:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L BAUD_RATE=57600
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.custom b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.custom
new file mode 100644
index 0000000..aa970ab
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.custom
@@ -0,0 +1,16 @@
+#
+# Makefile for "custom" platforms. Add your board here.
+#
+# * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
+# * This software is licensed under version 2 of the Gnu Public Licence.
+# * See optiboot.c for details.
+
+
+HELPTEXT += "target wildfire - Wicked Devices Wildfire v1 board\n"
+wildfire: TARGET = $@
+wildfire: CHIP = atmega1284p
+wildfire:
+ "$(MAKE)" $(CHIP) AVR_FREQ=16000000L LED=B5
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).lst
+
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.extras b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.extras
new file mode 100644
index 0000000..996a740
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.extras
@@ -0,0 +1,135 @@
+#
+# Makefile for "other" implemented platforms.
+#
+# * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
+# * This software is licensed under version 2 of the Gnu Public Licence.
+# * See optiboot.c for details.
+#
+
+#
+# Extra chips (maybe) supported by optiboot
+# Note that these are usually only minimally tested.
+#
+
+#
+# ATmega88
+#
+HELPTEXT += "target atmega88 - ATmega88 or ATmega88p (28pin, 8k)\n"
+atmega88: TARGET = atmega88
+atmega88: MCU_TARGET = atmega88
+atmega88: CFLAGS += $(COMMON_OPTIONS)
+atmega88: AVR_FREQ ?= 16000000L
+atmega88: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe -Wl,--gc-sections -Wl,--undefined=optiboot_version
+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
+atmega88_isp: LFUSE ?= FF
+# 512 byte boot
+atmega88_isp: EFUSE ?= 04
+atmega88_isp: isp
+
+atmega88p_isp: atmega88
+atmega88p_isp: TARGET = atmega88
+atmega88p_isp: MCU_TARGET = atmega88p
+# 2.7V brownout
+atmega88p_isp: HFUSE ?= DD
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega88p_isp: LFUSE ?= FF
+# 512 byte boot
+atmega88p_isp: EFUSE ?= 04
+atmega88p_isp: isp
+
+#
+# ATmega168p [QFN32]
+#
+HELPTEXT += "target atmega168p - ATmega168p\n"
+atmega168p: TARGET = atmega168p
+atmega168p: MCU_TARGET = atmega168p
+atmega168p: CFLAGS += $(COMMON_OPTIONS)
+atmega168p: AVR_FREQ ?= 16000000L
+atmega168p: $(PROGRAM)_atmega168p_16MHz.hex
+atmega168p: $(PROGRAM)_atmega168p_16MHz.lst
+
+atmega168p_isp: atmega168p
+atmega168p_isp: TARGET = atmega168p
+# 2.7V brownout
+atmega168p_isp: HFUSE ?= DD
+# Low power xtal (16MHz) 16KCK/14CK+65ms
+atmega168p_isp: LFUSE ?= FF
+# 512 byte boot
+atmega168p_isp: EFUSE ?= 04
+atmega168p_isp: isp
+
+HELPTEXT += "target atmega16 - ATmega16 (40pin, 16k)\n"
+atmega16: TARGET = atmega16
+atmega16: MCU_TARGET = atmega16
+atmega16: CFLAGS += $(COMMON_OPTIONS)
+atmega16: AVR_FREQ ?= 16000000L
+atmega16: $(PROGRAM)_atmega16.hex
+atmega16: $(PROGRAM)_atmega16.lst
+
+#
+# ATmega32
+#
+HELPTEXT += "target atmega32 - ATmega32 (40pin, 32k)\n"
+atmega32: TARGET = atmega32
+atmega32: MCU_TARGET = atmega32
+atmega32: CFLAGS += $(COMMON_OPTIONS)
+atmega32: AVR_FREQ ?= 11059200L
+atmega32: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe
+atmega32: $(PROGRAM)_atmega32.hex
+atmega32: $(PROGRAM)_atmega32.lst
+
+atmega32_isp: atmega32
+atmega32_isp: TARGET = atmega32
+atmega32_isp: MCU_TARGET = atmega32
+# No OCD or JTAG, SPIEN, CKOPT (for full swing xtal), Bootsize=512B
+atmega32_isp: HFUSE ?= CE
+# 2.7V brownout, 16MHz Xtal, 16KCK/14CK+65ms
+atmega32_isp: LFUSE ?= BF
+atmega32_isp: isp
+
+
+
+#
+# ATtiny84
+#
+attiny84: TARGET = attiny84
+attiny84: MCU_TARGET = attiny84
+attiny84: CFLAGS += $(COMMON_OPTIONS) -DSOFT_UART -DVIRTUAL_BOOT_PARTITION -Dsave_vect_num=4
+attiny84: LDSECTIONS = -Wl,--section-start=.text=0x1d00 -Wl,--section-start=.version=0x1ffe -Wl,--gc-sections -Wl,--undefined=optiboot_version
+attiny84: $(PROGRAM)_attiny84.hex
+attiny84: $(PROGRAM)_attiny84.lst
+
+
+
+# 1MHz clocked platforms/boards
+#
+# These are capable of 9600 baud
+#
+
+luminet: TARGET = $@
+luminet: CHIP = attiny84
+luminet:
+ "$(MAKE)" $(CHIP) AVR_FREQ=1000000L LED_START_FLASHES=0 BAUD_RATE=9600
+ mv $(PROGRAM)_$(CHIP).hex $(PROGRAM)_$(TARGET).hex
+ mv $(PROGRAM)_$(CHIP).lst $(PROGRAM)_$(TARGET).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
+
+
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.isp b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.isp
new file mode 100644
index 0000000..745729f
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/Makefile.isp
@@ -0,0 +1,90 @@
+# Makefile.isp for Optiboot
+# Bill Westfield (WestfW@yahoo.com) March, 2013
+# $Id$
+#
+# Instructions:
+#
+# This is a "daughter" Makefile that burns the bootloader using a ISP
+# device programmer. It is designed to inherit assorted variables from
+# the parent optiboot "Makefile"... Using a daughter makefile makes
+# certain variable manipulations more obvious.
+#
+# To burn bootloader .hex file, invoke the main Makefile using:
+# make diecimila_isp
+# make lilypad_isp
+# make ng_isp
+# etc...
+#
+#
+# Note: inherit paths/etc from parent Makefile.
+#
+#---------------------------------------------------------------------------
+#
+# * Copyright 2013-2015 by Bill Westfield. Part of Optiboot.
+# * This software is licensed under version 2 of the Gnu Public Licence.
+# * See optiboot.c for details.
+#
+#---------------------------------------------------------------------------
+
+# enter the parameters for the avrdude isp tool -b19200
+#
+
+# Inherit avrdude paths from top-level makefile
+AVRDUDE_ROOT ?= $(GCCROOT)
+AVRDUDE_CONF ?= -C$(TOOLROOT)/avr/etc/avrdude.conf
+
+# These are the parameters for a usb-based STK500v2 programmer.
+# Exact type unknown. (historical Makefile values.)
+#ISPTOOL = stk500v2
+#ISPPORT = usb
+#ISPSPEED = -b 115200
+#
+#
+# These are parameters for using an Arduino with the ArduinoISP sketch
+# as the programmer. On a mac, for a particular Uno as programmer.
+ISPTOOL ?= stk500v1
+ISPPORT ?= /dev/tty.usbserial-FTD61T6Q
+ISPSPEED ?= -b19200
+
+
+
+# Not all chips have EFUSE.
+
+ifdef EFUSE
+EFUSE_CMD= -U efuse:w:0x$(EFUSE):m
+endif
+
+#
+# avrdude commands to erase chip, unlock memory, and program fuses.
+#
+ISPFUSES = -e -u -U lock:w:0x3f:m $(EFUSE_CMD) \
+ -U hfuse:w:0x$(HFUSE):m -U lfuse:w:0x$(LFUSE):m
+
+
+#
+# avrdude commands to program the new bootloader, and protect the bootloader
+# space from accidental SPM writes. Note: "2f" allows boot section to be read
+# by the application, which is different than the arduino default.
+#
+ISPFLASH = -U flash:w:$(PROGRAM)_$(TARGET).hex -U lock:w:0x2f:m
+
+# There are certain complicated caused by the fact that the default state
+# of a fuse is a "1" rather than a "0", especially with respect to fuse bits
+# that have not been implemented. Those would normally not be included, but
+# unimplemented fuses still default to being "1"
+#
+# 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.
+
+isp: $(PROGRAM)_$(TARGET).hex
+ $(AVRDUDE_ROOT)avrdude $(AVRDUDE_CONF) -c $(ISPTOOL) \
+ -p $(MCU_TARGET) -P $(ISPPORT) $(ISPSPEED) \
+ $(ISPFUSES) \
+ $(ISPFLASH)
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/README.TXT b/ActualOptiboot/optiboot/bootloaders/optiboot/README.TXT
new file mode 100644
index 0000000..b4db4c9
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/README.TXT
@@ -0,0 +1,99 @@
+This directory contains the Optiboot small bootloader for AVR
+microcontrollers, somewhat modified specifically for the Arduino
+environment.
+
+Optiboot is more fully described here: http://github.com/Optiboot/optiboot
+and is the work of Peter Knight (aka Cathedrow), building on work of Jason P
+Kyle, Spiff, and Ladyada. More recent maintenance and modifications are by
+Bill Westfield (aka WestfW)
+
+Arduino-specific issues are tracked as part of the Arduino project
+at http://github.com/arduino/Arduino
+
+
+Most of the information in this file is superceeded by the wiki content at
+https://github.com/Optiboot/optiboot/wiki
+
+It's till here "just in case."
+
+------------------------------------------------------------
+
+Building optiboot for Arduino.
+
+Production builds of optiboot for Arduino are done on a Mac in "unix mode"
+using CrossPack-AVR-20100115. CrossPack tracks WINAVR (for windows), which
+is just a package of avr-gcc and related utilities, so similar builds should
+work on Windows or Linux systems.
+
+One of the Arduino-specific changes is modifications to the makefile to
+allow building optiboot using only the tools installed as part of the
+Arduino environment, or the Arduino source development tree. All three
+build procedures should yield identical binaries (.hex files) (although
+this may change if compiler versions drift apart between CrossPack and
+the Arduino IDE.)
+
+
+Building Optiboot in the Arduino IDE Install.
+
+Work in the .../hardware/arduino/bootloaders/optiboot/ and use the
+"omake " command, which just generates a command that uses
+the arduino-included "make" utility with a command like:
+ make OS=windows ENV=arduino
+or make OS=macosx ENV=arduino
+On windows, this assumes you're using the windows command shell. If
+you're using a cygwin or mingw shell, or have one of those in your
+path, the build will probably break due to slash vs backslash issues.
+On a Mac, if you have the developer tools installed, you can use the
+Apple-supplied version of make.
+The makefile uses relative paths ("../../../tools/" and such) to find
+the programs it needs, so you need to work in the existing optiboot
+directory (or something created at the same "level") for it to work.
+
+
+Building Optiboot in the Arduino Source Development Install.
+
+In this case, there is no special shell script, and you're assumed to
+have "make" installed somewhere in your path.
+Build the Arduino source ("ant build") to unpack the tools into the
+expected directory.
+Work in Arduino/hardware/arduino/bootloaders/optiboot and use
+ make OS=windows ENV=arduinodev
+or make OS=macosx ENV=arduinodev
+
+
+Programming Chips Using the _isp Targets
+
+The CPU targets have corresponding ISP targets that will actuall
+program the bootloader into a chip. "atmega328_isp" for the atmega328,
+for example. These will set the fuses and lock bits as appropriate as
+well as uploading the bootloader code.
+
+ISP Targets in Version 5.0 and later:
+
+The isp targets are now built using a separate "Makefile.isp" makefile,
+which should make modification easier and more obvious. This also fixes
+the atmega8_isp target problem mentioned below. The default
+configuration assumes an ArduinoISP setup, but you will probably need to
+update at least the serial port, since those are different for each
+Arduino board and/or system/
+
+
+ISP Targets in Version 4.6 and earlier:
+
+The older makefiles default to using a USB programmer, but you can use a
+serial programmer like ArduinoISP by changing the appropriate variables
+when you invoke make:
+
+ make ISPTOOL=stk500v1 ISPPORT=/dev/tty.usbserial-A20e1eAN \
+ ISPSPEED=-b19200 atmega328_isp
+
+The "atmega8_isp" target does not currently work, because the mega8
+doesn't have the "extended" fuse that the generic ISP target wants to
+pass on to avrdude. You'll need to run avrdude manually.
+
+
+Standard Targets
+
+I've reduced the pre-built and source-version-controlled targets
+(.hex and .lst files included in the git repository) to just the
+three basic 16MHz targets: atmega8, atmega16, atmega328.
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/baudcheck.c b/ActualOptiboot/optiboot/bootloaders/optiboot/baudcheck.c
new file mode 100644
index 0000000..2c9406a
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/baudcheck.c
@@ -0,0 +1,56 @@
+/*
+ * baudcheck.c
+ * Mar, 2013 by Bill Westfield (WestfW@yahoo.com)
+ * Exercises in executing arithmetic code on a system that we can't count
+ * on having the usual languages or tools installed.
+ *
+ * This little "C program" is run through the C preprocessor using the same
+ * arguments as our "real" target (which should assure that it gets the
+ * same values for clock speed and desired baud rate), and produces as
+ * output a shell script that can be run through bash, and THAT in turn
+ * writes the desired output...
+ *
+ * Note that the C-style comments are stripped by the C preprocessor.
+ *
+ * Copyright 2013-2015 by Bill Westfield.
+ * This software is licensed under version 2 of the Gnu Public Licence.
+ * See optiboot.c for details.
+ */
+
+/*
+ * First strip any trailing "L" from the defined constants. To do this
+ * we need to make the constants into shell variables first.
+ */
+bpsx=BAUD_RATE
+bps=${bpsx/L/}
+bps=${bps/U/}
+fcpux=F_CPU
+fcpu=${fcpux/L/}
+fcpu=${fcpu/U/}
+
+// echo f_cpu = $fcpu, baud = $bps
+/*
+ * Compute the divisor
+ */
+BAUD_SETTING=$(( ( ($fcpu + $bps * 4) / (($bps * 8))) - 1 ))
+// echo baud setting = $BAUD_SETTING
+
+/*
+ * Based on the computer divisor, calculate the actual bitrate,
+ * And the error. Since we're all integers, we have to calculate
+ * the tenths part of the error separately.
+ */
+BAUD_ACTUAL=$(( ($fcpu/(8 * (($BAUD_SETTING)+1))) ))
+BAUD_ERROR=$(( (( 100*($BAUD_ACTUAL - $bps) ) / $bps) ))
+ERR_TS=$(( ((( 1000*($BAUD_ACTUAL - $bps) ) / $bps) - $BAUD_ERROR * 10) ))
+ERR_TENTHS=$(( ERR_TS > 0 ? ERR_TS: -ERR_TS ))
+
+/*
+ * Print a nice message containing the info we've calculated
+ */
+echo BAUD RATE CHECK: Desired: $bps, Real: $BAUD_ACTUAL, UBRRL = $BAUD_SETTING, Difference=$BAUD_ERROR.$ERR_TENTHS\%
+
+
+
+
+
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/boot_opt.h b/ActualOptiboot/optiboot/bootloaders/optiboot/boot_opt.h
new file mode 100644
index 0000000..aa11e43
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/boot_opt.h
@@ -0,0 +1,99 @@
+// Get all the "standard" definitions from the official boot.h
+#include
+
+
+/*
+ * Implement some optimized versions that will use OUT instead
+ * of STS to write SPMCSR.
+ * (However, omit the *_extended_short, since by the time you
+ * need _extended_, the extra byte shouldn't be relevant any more)
+ *
+ * The C preprocessor can not determin at compile time whether SPMCSR is
+ * "out of range" of the OUT instruction, but we CAN do that in the
+ * assembler. We can even make it pretty with a macro.
+ * With this modification, the _short functions should work on cpus
+ * (like ATmega128) where STS is required.
+ */
+
+asm(".macro __wr_spmcsr p, v \n\t"
+ ".if \\p > 0x37 \n\t"
+ "sts \\p, \\v \n\t"
+ ".else \n\t"
+ "out \\p, \\v \n\t"
+ ".endif \n\t"
+ ".endm \n");
+
+
+#if defined(SPMCSR) || defined(SPMCR)
+
+#define __boot_page_fill_short(address, data) \
+(__extension__({ \
+ __asm__ __volatile__ \
+ ( \
+ "movw r0, %3\n\t" \
+ "__wr_spmcsr %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_erase_short(address) \
+(__extension__({ \
+ __asm__ __volatile__ \
+ ( \
+ "__wr_spmcsr %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_write_short(address) \
+(__extension__({ \
+ __asm__ __volatile__ \
+ ( \
+ "__wr_spmcsr %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_rww_enable_short() \
+(__extension__({ \
+ __asm__ __volatile__ \
+ ( \
+ "__wr_spmcsr %0, %1\n\t" \
+ "spm\n\t" \
+ : \
+ : "i" (_SFR_IO_ADDR(__SPM_REG)), \
+ "r" ((uint8_t)__BOOT_RWW_ENABLE) \
+ ); \
+}))
+
+#else
+
+/*
+ * if SPMCSR or SPMCR isn't defined, it means we have some sort of
+ * new-fangled chip that post-dates the version of boot.h that we
+ * know about. In this case, it's possible that the standard boot.h
+ * still has workable functions, so we'll alias those.
+ */
+
+#define __boot_page_fill_short(address, data) boot_page_fill(address, data)
+#define __boot_page_erase_short(address) boot_page_erase(address)
+#define __boot_page_write_short(address) boot_page_write(address)
+#define __boot_rww_enable_short() boot_rww_enable()
+
+#endif
+
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/make-ccversions b/ActualOptiboot/optiboot/bootloaders/optiboot/make-ccversions
new file mode 100755
index 0000000..5618c33
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/make-ccversions
@@ -0,0 +1,34 @@
+#
+# Compile a couple of Optiboot variations using several different compilers
+#
+
+
+# A list of compilers that are available.
+# This is, um, 4.3.3, 4.6.2, 4.8.1, 4.9.2, and 5.4.0
+#
+COMPS='
+/usr/local/CrossPack-AVR-20100115/bin/
+/usr/local/CrossPack-AVR-20121207/bin/
+/usr/local/CrossPack-AVR-48/bin/
+/usr/local/avr8-atmel-20160624/bin/
+/usr/local/avr8-Atmel-3.6.0.487/bin/
+'
+
+for c in $COMPS; do
+ # Pretty print for readability
+ echo
+ echo
+ echo ===========================================================
+ echo Using compiler in $c
+ $c/avr-gcc --version | head -1
+ echo ===========================================================
+
+ echo --------------- make GCCROOT=$c atmega328
+ make GCCROOT=$c atmega328
+ echo --------------- make GCCROOT=$c atmega1284
+ make GCCROOT=$c atmega1284
+ echo --------------- make GCCROOT=$c luminet
+ make GCCROOT=$c luminet
+ echo --------------- make GCCROOT=$c mega1280
+ make GCCROOT=$c mega1280
+done
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/makeall b/ActualOptiboot/optiboot/bootloaders/optiboot/makeall
new file mode 100755
index 0000000..9288d48
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/makeall
@@ -0,0 +1,32 @@
+#!/bin/bash
+make clean
+#
+# buildable platforms of somewhat questionable support level
+make lilypad
+make pro8
+make pro16
+make pro20
+make atmega328_pro8
+make sanguino
+make mega1280
+make luminet
+make diecimila
+make bobuino
+make wildfirev2
+make atmega1284
+make atmega32
+make atmega88
+make atmega168p
+
+#
+# Atmel development board targets
+make xplained168pb
+make xplained328p
+make xplained328pb
+
+#
+# The "big three" standard bootloaders.
+# These need to be built AFTER the platforms, or they'll get renamed
+make atmega8
+make atmega168
+make atmega328
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/makeoptions b/ActualOptiboot/optiboot/bootloaders/optiboot/makeoptions
new file mode 100755
index 0000000..fad1631
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/makeoptions
@@ -0,0 +1,37 @@
+#!/bin/bash
+make clean
+#
+
+# don't build most of the targets already in makeall
+
+# The "big three" standard bootloaders.
+# These need to be built AFTER the platforms, or they'll get renamed
+make atmega8
+make virboot8
+make atmega168
+make atmega328
+make virboot328
+
+make atmega328 BIGBOOT=1
+make atmega328 SUPPORT_EEPROM=1 LED_START_FLASHES=0 LED_START_ON=1
+make atmega328 BAUD_RATE=19200
+make atmega328 SOFT_UART=1
+make atmega328 LED_START_FLASHES=20
+
+make atmega1284 UART=1 LED=A1
+
+echo --------------------------------------------------
+echo Expected to fail !!!!
+echo --------------------------------------------------
+
+# too big
+make atmega328 SUPPORT_EEPROM=1
+# no such port
+make atmega328 LED=J1
+# no such led
+make atmega328 LED=fred
+make atmega328 UART=1
+#
+#invalid bit rates
+make atmega328 BAUD_RATE=300
+make atmega328 BAUD_RATE=3000000
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/omake b/ActualOptiboot/optiboot/bootloaders/optiboot/omake
new file mode 100755
index 0000000..59d23d9
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/omake
@@ -0,0 +1,9 @@
+#%/bin/bash
+if [ -d ../../../tools ]; then
+ mypath=../../../tools/avr/bin
+else
+ mypath=../../../../tools/avr/bin
+fi
+
+echo $mypath/make OS=macosx ENV=arduino $*
+$mypath/make OS=macosx ENV=arduino $*
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/omake.bat b/ActualOptiboot/optiboot/bootloaders/optiboot/omake.bat
new file mode 100644
index 0000000..4c9b13d
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/omake.bat
@@ -0,0 +1,221 @@
+@echo off
+SET DEBUG=REM
+
+REM Batch file to build Optiboot by searching around for the right tools, and then
+REM setting the path and invoking them with the specified arguments.
+REM Based on https://github.com/WestfW/Arduino-avr-tools-install
+
+REM Batch file must run in Delayed Evaluation mode.
+%DEBUG% checking cmd mode
+call :clearerrors
+if "!x!" EQU "%x%" (
+
+REM Things are good; try to set the paths and run the compile
+
+REM --------------------------------------------------------
+ call :findArduino
+ %DEBUG% Using make %*
+ make %*
+ exit /b 0
+REM --------------------------------------------------------
+
+)
+REM We have to run in /V mode to get late evaluation of variables inside loops
+%DEBUG% re-running in delayed eval mode
+cmd.exe /V /C "%0" %*
+exit /b 0
+
+
+
+REM ======================================================================
+
+:findArduino
+REM Here is most of the work of the script.
+REM Look through the various places where an Arduino install is likely to exist,
+REM make sure that we can find the avr-gcc binaries that should be part of that
+REM install, print out the version, and ask the user if that's what they want.
+
+REM Look for existing avr-gcc in path.
+%DEBUG% Looking for avr-gcc in current path
+call :clearerrors
+call :which avr-gcc.exe
+IF "%gotwhich%" NEQ "" (
+ @ECHO avr-gcc already installed at %gotwhich%
+ exit /b 123
+) ELSE (
+ @ECHO No avr-gcc in current path
+)
+
+REM look for Arduino install.
+set picked=n
+set printed=n
+call :scandir "%ProgramFiles%"
+if ERRORLEVEL 1 exit /b 1
+if "%picked%" NEQ "y" call :scandir "%ProgramFiles(x86)%"
+if ERRORLEVEL 1 exit /b 1
+if "%picked%" NEQ "y" call :scandir "C:\bin"
+if ERRORLEVEL 1 exit /b 1
+if "%picked%" EQU "y" goto gotdir
+@echo.
+ REM try some of the more unlikely places that Arduino might live.
+
+:noarduino
+ @echo Can't find Arduino
+ exit /b 1
+
+
+REM Given the name of a program-containing directory (like "\bin"),
+REM See if it looks like there are any "Arduino*" directories there,
+REM and prompt the user to ask whether that's the one we want to use
+REM for avr-gcc. If so, set variables saying we picked one.
+:scandir
+ %DEBUG% ScanDir %1
+ SET root=%~1
+ if NOT EXIST "%root%" exit /b 0
+ if NOT EXIST "%root%\Arduino*" exit /b 0
+ FOR /F "tokens=*" %%f IN ('dir /b /x "%root%\Arduino*"') DO (
+ SET prg=!root!\%%f
+ if exist "!prg!\Hardware\tools\avr\bin\avr-gcc.exe" (
+ if "%printed%" NEQ "Y" (
+ echo At least one Arduino install found.
+ echo.
+ set printed=Y
+ )
+ @echo Looks like !prg! has version
+ call :gccversion "!prg!\Hardware\tools\avr\bin\avr-gcc.exe"
+ SET aroot=!prg!
+ set picked=y
+ exit /b 0
+ ) else %DEBUG% No Arduino exe in expected spot !prg!
+ )
+ exit /b 0
+
+
+REM prompt for arduino install location.
+@echo ****WHY DID WE GET HERE****
+@echo asking if this is OK
+SET /P confirm="Use %prg% [y/n]>"
+if "%confirm%" NEQ "y" exit /b 0
+
+
+:gotdir
+REM figure out arduino install version.
+%DEBUG% gotdir has aroot = !aroot!
+IF EXIST "!aroot!\hardware\tools\avr\bin\avr-gcc.exe" (
+ set bin=!aroot!\hardware\tools\avr\bin
+ set etc=!aroot!\hardware\tools\avr\etc
+) else (
+ @echo Cant find a bin directory in !aroot!
+ exit /b 963
+)
+
+%DEBUG% Checking for utils at %prg%\hardware\tools\avr\utils\bin\
+IF EXIST "!aroot!\hardware\tools\avr\utils\bin\make.exe" (
+ REM See if we have make and etc as well (from Arduino 1.0.x/WinAVR)
+ %DEBUG% Found make.exe
+ set utils=!aroot!\hardware\tools\avr\utils\bin
+) else (
+ IF EXIST "C:\Program Files (X86)\GnuWin32" (
+ set utils="C:\Program Files (X86)\GnuWin32\bin"
+ )
+ IF EXIST "C:\Program Files\GnuWin32" (
+ set utils="C:\Program Files\GnuWin32\bin"
+ )
+)
+
+
+REM find bin directory.
+REM create tentative path for binaries and put it in our tmp batch file
+%DEBUG% Setting paths to include bin and etc
+REM
+REM setx will set a permanent path in the registry, but it won't take effect
+REM until the next invocation of cmd.exe
+REM setx PATH %bin%;%etc%
+REM
+%DEBUG% adding arduin bin and etc to PATH %bin%;%etc%
+call :shorten "%bin%"
+PATH %PATH%;!shortout!
+call :shorten "%etc%"
+PATH %PATH%;!shortout!
+
+%DEBUG% Have utils = %utils%
+
+IF %utils% NEQ "" (
+ REM Check for make already installed
+ %DEBUG% Have utils; checking whether make is already installed.
+ call :which make.exe
+ if "%gotwhich%" EQU "" (
+ echo Found Make at %utils%
+ call :shorten %utils%
+ PATH %PATH%;!shortout!
+ )
+)
+call :clearerrors
+exit /b 0
+goto eof
+
+
+REM ----------------------------------------------------------------------
+REM Subroutines
+REM ----------------------------------------------------------------------
+
+:which
+ %DEBUG% which %1
+ SET gotwhich=
+ for %%i in (%1) do set fullspec=%%~$PATH:i
+ if not "x!fullspec!"=="x" (
+ %DEBUG% !fullspec!
+ set gotwhich=!fullspec!
+ )
+ %DEBUG% End which %gotwhich%
+ goto eof
+
+
+REM ----------------------------------------------------------------------
+
+:gccversion
+ REM This implements "gcc --version | head -1" - show the first line
+ if EXIST %1 (
+ FOR /F "delims=*" %%l in ('%1 --version') DO (
+ @echo %%l
+ REM return after we've output one line
+ exit /b 0
+ )
+ )
+ exit /b 0
+
+
+REM ----------------------------------------------------------------------
+
+:avrdudeversion
+ SETLOCAL ENABLEDELAYEDEXPANSION
+ REM This implements "gcc --version | head -4" - show the first line
+ set /a count=4
+ FOR /F "delims=*" %%l in ('"avrdude -v 2>&1"') DO (
+ @echo %%l
+ set /a count=!count!-1
+ if !count! equ 0 (
+ ENDLOCAL
+ exit /b 0
+ )
+ )
+ exit /b 0
+goto :eof
+
+
+REM ----------------------------------------------------------------------
+
+REM Clear the ERRORLEVEL to 0, if it happened to be set
+:clearerrors
+ exit /b 0
+
+
+REM ----------------------------------------------------------------------
+
+REM Shorten a pathname to 8.3 format filenames.
+
+:shorten
+ set shortout=%~s1
+ exit /b 0
+
+:eof
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot.c b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot.c
new file mode 100644
index 0000000..6f89d29
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot.c
@@ -0,0 +1,1060 @@
+#define FUNC_READ 1
+#define FUNC_WRITE 1
+/**********************************************************/
+/* Optiboot bootloader for Arduino */
+/* */
+/* http://optiboot.googlecode.com */
+/* */
+/* Arduino-maintained version : See README.TXT */
+/* http://code.google.com/p/arduino/ */
+/* It is the intent that changes not relevant to the */
+/* Arduino production envionment get moved from the */
+/* optiboot project to the arduino project in "lumps." */
+/* */
+/* Heavily optimised bootloader that is faster and */
+/* smaller than the Arduino standard bootloader */
+/* */
+/* Enhancements: */
+/* Fits in 512 bytes, saving 1.5K of code space */
+/* 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) */
+/* */
+/* Beta test (believed working.) */
+/* ATmega8 based devices (Arduino legacy) */
+/* ATmega328 non-picopower devices */
+/* ATmega644P based devices (Sanguino) */
+/* ATmega1284P based devices */
+/* ATmega1280 based devices (Arduino Mega) */
+/* ATmega2560 based devices (Arduino Mega) */
+/* */
+/* Alpha test */
+/* ATmega32 */
+/* */
+/* Work in progress: */
+/* ATtiny84 based devices (Luminet) */
+/* */
+/* Does not support: */
+/* USB based devices (eg. Teensy, Leonardo) */
+/* */
+/* 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 */
+/* */
+
+/* Copyright 2013-2015 by Bill Westfield. */
+/* Copyright 2010 by Peter Knight. */
+/* */
+/* 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: */
+/* */
+/**********************************************************/
+/* */
+/* BIGBOOT: */
+/* Build a 1k bootloader, not 512 bytes. This turns on */
+/* extra functionality. */
+/* */
+/* BAUD_RATE: */
+/* Set bootloader baud rate. */
+/* */
+/* 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. */
+/* */
+/* UART: */
+/* UART number (0..n) for devices with more than */
+/* one hardware uart (644P, 1284P, etc) */
+/* */
+/**********************************************************/
+
+/**********************************************************/
+/* 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. */
+/* Version 5 was created at the time of the new Makefile */
+/* structure (Mar, 2013), even though no binaries changed*/
+/* It would be good if versions implemented outside the */
+/* official repository used an out-of-seqeunce version */
+/* number (like 104.6 if based on based on 4.5) to */
+/* prevent collisions. */
+/* */
+/**********************************************************/
+
+/**********************************************************/
+/* Edit History: */
+/* */
+/* July 2018 */
+/* 7.0 WestfW (with much input from Others) */
+/* Fix MCUSR treatement as per much discussion, */
+/* Patches by MarkG55, majekw. Preserve value */
+/* for the application, as much as possible. */
+/* see https://github.com/Optiboot/optiboot/issues/97 */
+/* Optimize a bit by implementing a union for the */
+/* various 16bit address values used (based on */
+/* observation by "aweatherguy", but different.) */
+/* Slightly optimize math in VIRTUAL_BOOT code */
+/* Add some virboot targets, fix some fuses. */
+/* Implement LED_START_ON; less code than flashes */
+/* Aug 2014 */
+/* 6.2 WestfW: make size of length variables dependent */
+/* on the SPM_PAGESIZE. This saves space */
+/* on the chips where it's most important. */
+/* 6.1 WestfW: Fix OPTIBOOT_CUSTOMVER (send it!) */
+/* Make no-wait mod less picky about */
+/* skipping the bootloader. */
+/* Remove some dead code */
+/* Jun 2014 */
+/* 6.0 WestfW: Modularize memory read/write functions */
+/* Remove serial/flash overlap */
+/* (and all references to NRWWSTART/etc) */
+/* Correctly handle pagesize > 255bytes */
+/* Add EEPROM support in BIGBOOT (1284) */
+/* EEPROM write on small chips now causes err */
+/* Split Makefile into smaller pieces */
+/* Add Wicked devices Wildfire */
+/* Move UART=n conditionals into pin_defs.h */
+/* Remove LUDICOUS_SPEED option */
+/* Replace inline assembler for .version */
+/* and add OPTIBOOT_CUSTOMVER for user code */
+/* Fix LED value for Bobuino (Makefile) */
+/* Make all functions explicitly inline or */
+/* noinline, so we fit when using gcc4.8 */
+/* Change optimization options for gcc4.8 */
+/* Make ENV=arduino work in 1.5.x trees. */
+/* May 2014 */
+/* 5.0 WestfW: Add support for 1Mbps UART */
+/* Mar 2013 */
+/* 5.0 WestfW: Major Makefile restructuring. */
+/* See Makefile and pin_defs.h */
+/* (no binary changes) */
+/* */
+/* 4.6 WestfW/Pito: Add ATmega32 support */
+/* 4.6 WestfW/radoni: Don't set LED_PIN as an output if */
+/* not used. (LED_START_FLASHES = 0) */
+/* Jan 2013 */
+/* 4.6 WestfW/dkinzer: use autoincrement lpm for read */
+/* 4.6 WestfW/dkinzer: pass reset cause to app in R2 */
+/* Mar 2012 */
+/* 4.5 WestfW: add infrastructure for non-zero UARTS. */
+/* 4.5 WestfW: fix SIGNATURE_2 for m644 (bad in avr-libc) */
+/* 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 7
+#define OPTIBOOT_MINVER 0
+
+/*
+ * OPTIBOOT_CUSTOMVER should be defined (by the makefile) for custom edits
+ * of optiboot. That way you don't wind up with very different code that
+ * matches the version number of a "released" optiboot.
+ */
+
+#if !defined(OPTIBOOT_CUSTOMVER)
+#define OPTIBOOT_CUSTOMVER 0
+#endif
+
+unsigned const int __attribute__((section(".version")))
+optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER;
+
+
+#include
+#include
+#include
+#include
+
+/*
+ * optiboot uses several "address" variables that are sometimes byte pointers,
+ * sometimes word pointers. sometimes 16bit quantities, and sometimes built
+ * up from 8bit input characters. avr-gcc is not great at optimizing the
+ * assembly of larger words from bytes, but we can use the usual union to
+ * do this manually. Expanding it a little, we can also get rid of casts.
+ */
+typedef union {
+ uint8_t *bptr;
+ uint16_t *wptr;
+ uint16_t word;
+ uint8_t bytes[2];
+} addr16_t;
+
+/*
+ * Note that we use a replacement of "boot.h"
+ * uses sts instructions, but this version uses out instructions
+ * This saves cycles and program memory, if possible.
+ * boot_opt.h pulls in the standard boot.h for the odd target (?)
+ */
+#include "boot_opt.h"
+
+
+// We don't use as those routines have interrupt overhead we don't need.
+
+/*
+ * pin_defs.h
+ * This contains most of the rather ugly defines that implement our
+ * ability to use UART=n and LED=D3, and some avr family bit name differences.
+ */
+#include "pin_defs.h"
+
+/*
+ * stk500.h contains the constant definitions for the stk500v1 comm protocol
+ */
+#include "stk500.h"
+
+#ifndef LED_START_FLASHES
+#define LED_START_FLASHES 0
+#endif
+
+/* set the UART baud rate defaults */
+#ifndef BAUD_RATE
+#if F_CPU >= 8000000L
+#define BAUD_RATE 115200L // Highest rate Avrdude win32 will support
+#elif F_CPU >= 1000000L
+#define BAUD_RATE 9600L // 19200 also supported, but with significant error
+#elif F_CPU >= 128000L
+#define BAUD_RATE 4800L // Good for 128kHz internal RC
+#else
+#define BAUD_RATE 1200L // Good even at 32768Hz
+#endif
+#endif
+
+#ifndef UART
+#define UART 0
+#endif
+
+#define BAUD_SETTING (( (F_CPU + BAUD_RATE * 4L) / ((BAUD_RATE * 8L))) - 1 )
+#define BAUD_ACTUAL (F_CPU/(8 * ((BAUD_SETTING)+1)))
+#if BAUD_ACTUAL <= BAUD_RATE
+ #define BAUD_ERROR (( 100*(BAUD_RATE - BAUD_ACTUAL) ) / BAUD_RATE)
+ #if BAUD_ERROR >= 5
+ #error BAUD_RATE off by greater than -5%
+ #elif BAUD_ERROR >= 2
+ #warning BAUD_RATE off by greater than -2%
+ #endif
+#else
+ #define BAUD_ERROR (( 100*(BAUD_ACTUAL - BAUD_RATE) ) / BAUD_RATE)
+ #if BAUD_ERROR >= 5
+ #error BAUD_RATE off by greater than 5%
+ #elif BAUD_ERROR >= 2
+ #warning BAUD_RATE off by greater than 2%
+ #endif
+#endif
+
+#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
+#if BAUD_ERROR != 0 // permit high bitrates (ie 1Mbps@16MHz) if error is zero
+#error Unachievable baud rate (too fast) BAUD_RATE
+#endif
+#endif // baud rate fastn check
+
+/* 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
+
+
+/*
+ * We can never load flash with more than 1 page at a time, so we can save
+ * some code space on parts with smaller pagesize by using a smaller int.
+ */
+#if SPM_PAGESIZE > 255
+typedef uint16_t pagelen_t ;
+#define GETLENGTH(len) len = getch()<<8; len |= getch()
+#else
+typedef uint8_t pagelen_t;
+#define GETLENGTH(len) (void) getch() /* skip high byte */; len = getch()
+#endif
+
+
+/* Function Prototypes
+ * The main() function is in init9, which removes the interrupt vector table
+ * we don't need. It is also 'OS_main', which means the compiler does not
+ * generate any entry or exit code itself (but unlike 'naked', it doesn't
+ * supress some compile-time options we want.)
+ */
+
+int main(void) __attribute__ ((OS_main)) __attribute__ ((section (".init9")));
+
+void __attribute__((noinline)) putch(char);
+uint8_t __attribute__((noinline)) getch(void);
+void __attribute__((noinline)) verifySpace();
+void __attribute__((noinline)) watchdogConfig(uint8_t x);
+
+static inline void getNch(uint8_t);
+#if LED_START_FLASHES > 0
+static inline void flash_led(uint8_t);
+#endif
+static inline void watchdogReset();
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+ addr16_t address, pagelen_t len);
+static inline void read_mem(uint8_t memtype,
+ addr16_t, pagelen_t len);
+
+#ifdef SOFT_UART
+void uartDelay() __attribute__ ((naked));
+#endif
+void appStart(uint8_t rstFlags) __attribute__ ((naked));
+
+/*
+ * RAMSTART should be self-explanatory. It's bigger on parts with a
+ * lot of peripheral registers. Let 0x100 be the default
+ * Note that RAMSTART (for optiboot) need not be exactly at the start of RAM.
+ */
+#if !defined(RAMSTART) // newer versions of gcc avr-libc define RAMSTART
+#define RAMSTART 0x100
+#if defined (__AVR_ATmega644P__)
+// correct for a bug in avr-libc
+#undef SIGNATURE_2
+#define SIGNATURE_2 0x0A
+#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
+#undef RAMSTART
+#define RAMSTART (0x200)
+#endif
+#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 */
+static addr16_t buff = {(uint8_t *)(RAMSTART)};
+
+/* Virtual boot partition support */
+#ifdef VIRTUAL_BOOT_PARTITION
+#define rstVect0_sav (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+4))
+#define rstVect1_sav (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+5))
+#define saveVect0_sav (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+6))
+#define saveVect1_sav (*(uint8_t*)(RAMSTART+SPM_PAGESIZE*2+7))
+// Vector to save original reset jump:
+// SPM Ready is least probably used, so it's default
+// if not, use old way WDT_vect_num,
+// or simply set custom save_vect_num in Makefile using vector name
+// or even raw number.
+#if !defined (save_vect_num)
+#if defined (SPM_RDY_vect_num)
+#define save_vect_num (SPM_RDY_vect_num)
+#elif defined (SPM_READY_vect_num)
+#define save_vect_num (SPM_READY_vect_num)
+#elif defined (WDT_vect_num)
+#define save_vect_num (WDT_vect_num)
+#else
+#error Cant find SPM or WDT interrupt vector for this CPU
+#endif
+#endif //save_vect_num
+// check if it's on the same page (code assumes that)
+#if (SPM_PAGESIZE <= save_vect_num)
+#error Save vector not in the same page as reset!
+#endif
+#if FLASHEND > 8192
+// AVRs with more than 8k of flash have 4-byte vectors, and use jmp.
+// We save only 16 bits of address, so devices with more than 128KB
+// may behave wrong for upper part of address space.
+#define rstVect0 2
+#define rstVect1 3
+#define saveVect0 (save_vect_num*4+2)
+#define saveVect1 (save_vect_num*4+3)
+#define appstart_vec (save_vect_num*2)
+#else
+// AVRs with up to 8k of flash have 2-byte vectors, and use rjmp.
+#define rstVect0 0
+#define rstVect1 1
+#define saveVect0 (save_vect_num*2)
+#define saveVect1 (save_vect_num*2+1)
+#define appstart_vec (save_vect_num)
+#endif
+#else
+#define appstart_vec (0)
+#endif // VIRTUAL_BOOT_PARTITION
+
+
+/* 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 addr16_t address;
+ register pagelen_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__");
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
+ SP=RAMEND; // This is done by hardware reset
+#endif
+
+ /*
+ * Protect as much from MCUSR as possible for application
+ * and still skip bootloader if not necessary
+ *
+ * Code by MarkG55
+ * see discusion in https://github.com/Optiboot/optiboot/issues/97
+ */
+#if !defined(__AVR_ATmega16__)
+ ch = MCUSR;
+#else
+ ch = MCUCSR;
+#endif
+ // Skip all logic and run bootloader if MCUSR is cleared (application request)
+ if (ch != 0) {
+ /*
+ * To run the boot loader, External Reset Flag must be set.
+ * If not, we could make shortcut and jump directly to application code.
+ * Also WDRF set with EXTRF is a result of Optiboot timeout, so we
+ * shouldn't run bootloader in loop :-) That's why:
+ * 1. application is running if WDRF is cleared
+ * 2. we clear WDRF if it's set with EXTRF to avoid loops
+ * One problematic scenario: broken application code sets watchdog timer
+ * without clearing MCUSR before and triggers it quickly. But it's
+ * recoverable by power-on with pushed reset button.
+ */
+ if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) {
+ if (ch & _BV(EXTRF)) {
+ /*
+ * Clear WDRF because it was most probably set by wdr in bootloader.
+ * It's also needed to avoid loop by broken application which could
+ * prevent entering bootloader.
+ * '&' operation is skipped to spare few bytes as bits in MCUSR
+ * can only be cleared.
+ */
+#if !defined(__AVR_ATmega16__)
+ MCUSR = ~(_BV(WDRF));
+#else
+ MCUCSR = ~(_BV(WDRF));
+#endif
+ }
+ appStart(ch);
+ }
+ }
+
+#if LED_START_FLASHES > 0
+ // Set up Timer 1 for timeout counter
+ TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+#endif
+
+#ifndef SOFT_UART
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
+ UCSRA = _BV(U2X); //Double speed mode USART
+ UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
+ UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
+ UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+#else
+ UART_SRA = _BV(U2X0); //Double speed mode USART0
+ UART_SRB = _BV(RXEN0) | _BV(TXEN0);
+ UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
+ UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+#endif
+#endif
+
+ // Set up watchdog to trigger after 1s
+ watchdogConfig(WATCHDOG_1S);
+
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
+ /* Set LED pin as output */
+ LED_DDR |= _BV(LED);
+#endif
+
+#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);
+#else
+#if defined(LED_START_ON)
+ /* Turn on LED to indicate starting bootloader (less code!) */
+ LED_PORT |= _BV(LED);
+#endif
+#endif
+
+ /* Forever loop: exits by causing WDT reset */
+ for (;;) {
+ /* get character from UART */
+ ch = getch();
+
+ if(ch == STK_GET_PARAMETER) {
+ unsigned char which = getch();
+ verifySpace();
+ /*
+ * Send optiboot version as "SW version"
+ * Note that the references to memory are optimized away.
+ */
+ if (which == STK_SW_MINOR) {
+ putch(optiboot_version & 0xFF);
+ } else if (which == STK_SW_MAJOR) {
+ putch(optiboot_version >> 8);
+ } 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
+ address.bytes[0] = getch();
+ address.bytes[1] = getch();
+#ifdef RAMPZ
+ // Transfer top bit to LSB in RAMPZ
+ if (address.bytes[1] & 0x80) {
+ RAMPZ |= 0x01;
+ }
+ else {
+ RAMPZ &= 0xFE;
+ }
+#endif
+ address.word *= 2; // Convert from word address to byte address
+ verifySpace();
+ }
+ else if(ch == STK_UNIVERSAL) {
+#ifdef RAMPZ
+ // LOAD_EXTENDED_ADDRESS is needed in STK_UNIVERSAL for addressing more than 128kB
+ if ( AVR_OP_LOAD_EXT_ADDR == getch() ) {
+ // get address
+ getch(); // get '0'
+ RAMPZ = (RAMPZ & 0x01) | ((getch() << 1) & 0xff); // get address and put it in RAMPZ
+ getNch(1); // get last '0'
+ // response
+ putch(0x00);
+ }
+ else {
+ // everything else is ignored
+ getNch(3);
+ putch(0x00);
+ }
+#else
+ // UNIVERSAL command is ignored
+ getNch(4);
+ putch(0x00);
+#endif
+ }
+ /* 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 desttype;
+ uint8_t *bufPtr;
+ pagelen_t savelength;
+
+ GETLENGTH(length);
+ savelength = length;
+ desttype = getch();
+
+ // read a page worth of contents
+ bufPtr = buff.bptr;
+ do *bufPtr++ = getch();
+ while (--length);
+
+ // Read command terminator, start reply
+ verifySpace();
+
+#ifdef VIRTUAL_BOOT_PARTITION
+#if FLASHEND > 8192
+/*
+ * AVR with 4-byte ISR Vectors and "jmp"
+ * WARNING: this works only up to 128KB flash!
+ */
+ if (address.word == 0) {
+ // This is the reset vector page. We need to live-patch the
+ // code so the bootloader runs first.
+ //
+ // Save jmp targets (for "Verify")
+ rstVect0_sav = buff.bptr[rstVect0];
+ rstVect1_sav = buff.bptr[rstVect1];
+ saveVect0_sav = buff.bptr[saveVect0];
+ saveVect1_sav = buff.bptr[saveVect1];
+
+ // Move RESET jmp target to 'save' vector
+ buff.bptr[saveVect0] = rstVect0_sav;
+ buff.bptr[saveVect1] = rstVect1_sav;
+
+ // Add jump to bootloader at RESET vector
+ // WARNING: this works as long as 'main' is in first section
+ buff.bptr[rstVect0] = ((uint16_t)main) & 0xFF;
+ buff.bptr[rstVect1] = ((uint16_t)main) >> 8;
+ }
+
+#else
+/*
+ * AVR with 2-byte ISR Vectors and rjmp
+ */
+ if (address.word == rstVect0) {
+ // This is the reset vector page. We need to live-patch
+ // the code so the bootloader runs first.
+ //
+ // Move RESET vector to 'save' vector
+ // Save jmp targets (for "Verify")
+ rstVect0_sav = buff.bptr[rstVect0];
+ rstVect1_sav = buff.bptr[rstVect1];
+ saveVect0_sav = buff.bptr[saveVect0];
+ saveVect1_sav = buff.bptr[saveVect1];
+
+ // Instruction is a relative jump (rjmp), so recalculate.
+ // an RJMP instruction is 0b1100xxxx xxxxxxxx, so we should be able to
+ // do math on the offsets without masking it off first.
+ addr16_t vect;
+ vect.bytes[0] = rstVect0_sav;
+ vect.bytes[1] = rstVect1_sav;
+ vect.word = (vect.word-save_vect_num); //substract 'save' interrupt position
+ // Move RESET jmp target to 'save' vector
+ buff.bptr[saveVect0] = vect.bytes[0];
+ buff.bptr[saveVect1] = (vect.bytes[1] & 0x0F)| 0xC0; // make an "rjmp"
+ // Add rjump to bootloader at RESET vector
+ vect.word = ((uint16_t)main); // (main) is always <= 0x0FFF; no masking needed.
+ buff.bptr[0] = vect.bytes[0]; // rjmp 0x1c00 instruction
+ buff.bptr[1] = vect.bytes[1] | 0xC0; // make an "rjmp"
+ }
+#endif // FLASHEND
+#endif // VBP
+
+ writebuffer(desttype, buff, address, savelength);
+
+
+ }
+ /* Read memory block mode, length is big endian. */
+ else if(ch == STK_READ_PAGE) {
+ uint8_t desttype;
+ GETLENGTH(length);
+
+ desttype = getch();
+
+ verifySpace();
+
+ read_mem(desttype, address, length);
+ }
+
+ /* 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 (!(UART_SRA & _BV(UDRE0)));
+ UART_UDR = 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
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
+ LED_PORT ^= _BV(LED);
+#else
+ LED_PIN |= _BV(LED);
+#endif
+#endif
+
+#ifdef SOFT_UART
+ watchdogReset();
+ __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(!(UART_SRA & _BV(RXC0)))
+ ;
+ if (!(UART_SRA & _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 = UART_UDR;
+#endif
+
+#ifdef LED_DATA_FLASH
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
+ 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)));
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
+ LED_PORT ^= _BV(LED);
+#else
+ LED_PIN |= _BV(LED);
+#endif
+ watchdogReset();
+#ifndef SOFT_UART
+ /*
+ * While in theory, the STK500 initial commands would be buffered
+ * by the UART hardware, avrdude sends several attempts in rather
+ * quick succession, some of which will be lost and cause us to
+ * get out of sync. So if we see any data; stop blinking.
+ */
+ if (UART_SRA & _BV(RXC0))
+ break;
+#else
+// This doesn't seem to work?
+// if ((UART_PIN & (1<:
+ // SP points to RAMEND
+ // r1 contains zero
+ //
+ // If not, uncomment the following instructions:
+ // cli();
+ asm volatile ("clr __zero_reg__");
+ 1fc00: 11 24 eor r1, r1
+ *
+ * Code by MarkG55
+ * see discusion in https://github.com/Optiboot/optiboot/issues/97
+ */
+#if !defined(__AVR_ATmega16__)
+ ch = MCUSR;
+ 1fc02: 84 b7 in r24, 0x34 ; 52
+#else
+ ch = MCUCSR;
+#endif
+ // Skip all logic and run bootloader if MCUSR is cleared (application request)
+ if (ch != 0) {
+ 1fc04: 88 23 and r24, r24
+ 1fc06: 49 f0 breq .+18 ; 0x1fc1a
+ * 2. we clear WDRF if it's set with EXTRF to avoid loops
+ * One problematic scenario: broken application code sets watchdog timer
+ * without clearing MCUSR before and triggers it quickly. But it's
+ * recoverable by power-on with pushed reset button.
+ */
+ if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) {
+ 1fc08: 98 2f mov r25, r24
+ 1fc0a: 9a 70 andi r25, 0x0A ; 10
+ 1fc0c: 92 30 cpi r25, 0x02 ; 2
+ 1fc0e: 29 f0 breq .+10 ; 0x1fc1a
+ if (ch & _BV(EXTRF)) {
+ 1fc10: 81 ff sbrs r24, 1
+ 1fc12: 02 c0 rjmp .+4 ; 0x1fc18
+ * prevent entering bootloader.
+ * '&' operation is skipped to spare few bytes as bits in MCUSR
+ * can only be cleared.
+ */
+#if !defined(__AVR_ATmega16__)
+ MCUSR = ~(_BV(WDRF));
+ 1fc14: 97 ef ldi r25, 0xF7 ; 247
+ 1fc16: 94 bf out 0x34, r25 ; 52
+#else
+ MCUCSR = ~(_BV(WDRF));
+#endif
+ }
+ appStart(ch);
+ 1fc18: 10 d1 rcall .+544 ; 0x1fe3a
+ }
+ }
+
+#if LED_START_FLASHES > 0
+ // Set up Timer 1 for timeout counter
+ TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+ 1fc1a: 85 e0 ldi r24, 0x05 ; 5
+ 1fc1c: 80 93 81 00 sts 0x0081, r24 ; 0x800081 <__TEXT_REGION_LENGTH__+0x7e0081>
+ UCSRA = _BV(U2X); //Double speed mode USART
+ UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
+ UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
+ UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+#else
+ UART_SRA = _BV(U2X0); //Double speed mode USART0
+ 1fc20: 82 e0 ldi r24, 0x02 ; 2
+ 1fc22: 80 93 c0 00 sts 0x00C0, r24 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ UART_SRB = _BV(RXEN0) | _BV(TXEN0);
+ 1fc26: 88 e1 ldi r24, 0x18 ; 24
+ 1fc28: 80 93 c1 00 sts 0x00C1, r24 ; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7e00c1>
+ UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
+ 1fc2c: 86 e0 ldi r24, 0x06 ; 6
+ 1fc2e: 80 93 c2 00 sts 0x00C2, r24 ; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7e00c2>
+ UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+ 1fc32: 80 e1 ldi r24, 0x10 ; 16
+ 1fc34: 80 93 c4 00 sts 0x00C4, r24 ; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7e00c4>
+#endif
+#endif
+
+ // Set up watchdog to trigger after 1s
+ watchdogConfig(WATCHDOG_1S);
+ 1fc38: 8e e0 ldi r24, 0x0E ; 14
+ 1fc3a: ea d0 rcall .+468 ; 0x1fe10
+
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
+ /* Set LED pin as output */
+ LED_DDR |= _BV(LED);
+ 1fc3c: 27 9a sbi 0x04, 7 ; 4
+ 1fc3e: 86 e0 ldi r24, 0x06 ; 6
+}
+
+#if LED_START_FLASHES > 0
+void flash_led(uint8_t count) {
+ do {
+ TCNT1 = -(F_CPU/(1024*16));
+ 1fc40: 20 e3 ldi r18, 0x30 ; 48
+ 1fc42: 3c ef ldi r19, 0xFC ; 252
+ TIFR1 = _BV(TOV1);
+ 1fc44: 91 e0 ldi r25, 0x01 ; 1
+}
+
+#if LED_START_FLASHES > 0
+void flash_led(uint8_t count) {
+ do {
+ TCNT1 = -(F_CPU/(1024*16));
+ 1fc46: 30 93 85 00 sts 0x0085, r19 ; 0x800085 <__TEXT_REGION_LENGTH__+0x7e0085>
+ 1fc4a: 20 93 84 00 sts 0x0084, r18 ; 0x800084 <__TEXT_REGION_LENGTH__+0x7e0084>
+ TIFR1 = _BV(TOV1);
+ 1fc4e: 96 bb out 0x16, r25 ; 22
+ while(!(TIFR1 & _BV(TOV1)));
+ 1fc50: b0 9b sbis 0x16, 0 ; 22
+ 1fc52: fe cf rjmp .-4 ; 0x1fc50
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
+ LED_PORT ^= _BV(LED);
+#else
+ LED_PIN |= _BV(LED);
+ 1fc54: 1f 9a sbi 0x03, 7 ; 3
+}
+#endif
+
+// Watchdog functions. These are only safe with interrupts turned off.
+void watchdogReset() {
+ __asm__ __volatile__ (
+ 1fc56: a8 95 wdr
+ * While in theory, the STK500 initial commands would be buffered
+ * by the UART hardware, avrdude sends several attempts in rather
+ * quick succession, some of which will be lost and cause us to
+ * get out of sync. So if we see any data; stop blinking.
+ */
+ if (UART_SRA & _BV(RXC0))
+ 1fc58: 40 91 c0 00 lds r20, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ 1fc5c: 47 fd sbrc r20, 7
+ 1fc5e: 02 c0 rjmp .+4 ; 0x1fc64
+ 1fc60: 81 50 subi r24, 0x01 ; 1
+#else
+// This doesn't seem to work?
+// if ((UART_PIN & (1<
+
+ /*
+ * Copy data from the buffer into the flash write buffer.
+ */
+ do {
+ __boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+ 1fc64: ff 24 eor r15, r15
+ 1fc66: f3 94 inc r15
+ } while (len -= 2);
+
+ /*
+ * Actually Write the buffer to flash (and wait for it to finish.)
+ */
+ __boot_page_write_short(address.word);
+ 1fc68: 55 e0 ldi r21, 0x05 ; 5
+ 1fc6a: e5 2e mov r14, r21
+ boot_spm_busy_wait();
+#if defined(RWWSRE)
+ // Reenable read access to flash
+ __boot_rww_enable_short();
+ 1fc6c: 61 e1 ldi r22, 0x11 ; 17
+#endif
+
+ /* Forever loop: exits by causing WDT reset */
+ for (;;) {
+ /* get character from UART */
+ ch = getch();
+ 1fc6e: d6 2e mov r13, r22
+
+ if(ch == STK_GET_PARAMETER) {
+ 1fc70: c3 d0 rcall .+390 ; 0x1fdf8
+ unsigned char which = getch();
+ 1fc72: 81 34 cpi r24, 0x41 ; 65
+ 1fc74: c1 f4 brne .+48 ; 0x1fca6
+ 1fc76: c0 d0 rcall .+384 ; 0x1fdf8
+ verifySpace();
+ 1fc78: c8 2f mov r28, r24
+ 1fc7a: d0 d0 rcall .+416 ; 0x1fe1c
+ /*
+ * Send optiboot version as "SW version"
+ * Note that the references to memory are optimized away.
+ */
+ if (which == STK_SW_MINOR) {
+ 1fc7c: c2 38 cpi r28, 0x82 ; 130
+ 1fc7e: 09 f4 brne .+2 ; 0x1fc82
+ 1fc80: 3a c0 rjmp .+116 ; 0x1fcf6
+ putch(optiboot_version & 0xFF);
+ } else if (which == STK_SW_MAJOR) {
+ 1fc82: c1 38 cpi r28, 0x81 ; 129
+ 1fc84: 69 f4 brne .+26 ; 0x1fca0
+ putch(optiboot_version >> 8);
+ 1fc86: 87 e0 ldi r24, 0x07 ; 7
+ 1fc88: 0c c0 rjmp .+24 ; 0x1fca2
+ writebuffer(desttype, buff, address, savelength);
+
+
+ }
+ /* Read memory block mode, length is big endian. */
+ else if(ch == STK_READ_PAGE) {
+ 1fc8a: 84 37 cpi r24, 0x74 ; 116
+ 1fc8c: 09 f4 brne .+2 ; 0x1fc90
+
+ read_mem(desttype, address, length);
+ }
+
+ /* Get device signature bytes */
+ else if(ch == STK_READ_SIGN) {
+ 1fc8e: 82 c0 rjmp .+260 ; 0x1fd94
+ 1fc90: 85 37 cpi r24, 0x75 ; 117
+ // READ SIGN - return what Avrdude wants to hear
+ verifySpace();
+ 1fc92: 09 f0 breq .+2 ; 0x1fc96
+ putch(SIGNATURE_0);
+ 1fc94: a2 c0 rjmp .+324 ; 0x1fdda
+ 1fc96: c2 d0 rcall .+388 ; 0x1fe1c
+ 1fc98: 8e e1 ldi r24, 0x1E ; 30
+ putch(SIGNATURE_1);
+ 1fc9a: a7 d0 rcall .+334 ; 0x1fdea
+ 1fc9c: 87 e9 ldi r24, 0x97 ; 151
+ 1fc9e: a5 d0 rcall .+330 ; 0x1fdea
+ } else {
+ /*
+ * GET PARAMETER returns a generic 0x03 reply for
+ * other parameters - enough to keep Avrdude happy
+ */
+ putch(0x03);
+ 1fca0: 83 e0 ldi r24, 0x03 ; 3
+ 1fca2: a3 d0 rcall .+326 ; 0x1fdea
+ 1fca4: 9f c0 rjmp .+318 ; 0x1fde4
+ }
+ }
+ else if(ch == STK_SET_DEVICE) {
+ 1fca6: 82 34 cpi r24, 0x42 ; 66
+ 1fca8: 11 f4 brne .+4 ; 0x1fcae
+ // SET DEVICE is ignored
+ getNch(20);
+ 1fcaa: 84 e1 ldi r24, 0x14 ; 20
+ }
+ else if(ch == STK_SET_DEVICE_EXT) {
+ 1fcac: 03 c0 rjmp .+6 ; 0x1fcb4
+ // SET DEVICE EXT is ignored
+ getNch(5);
+ 1fcae: 85 34 cpi r24, 0x45 ; 69
+ 1fcb0: 19 f4 brne .+6 ; 0x1fcb8
+ 1fcb2: 85 e0 ldi r24, 0x05 ; 5
+ 1fcb4: bb d0 rcall .+374 ; 0x1fe2c
+ }
+ else if(ch == STK_LOAD_ADDRESS) {
+ 1fcb6: 96 c0 rjmp .+300 ; 0x1fde4
+ 1fcb8: 85 35 cpi r24, 0x55 ; 85
+ // LOAD ADDRESS
+ address.bytes[0] = getch();
+ 1fcba: 79 f4 brne .+30 ; 0x1fcda
+ 1fcbc: 9d d0 rcall .+314 ; 0x1fdf8
+ 1fcbe: 08 2f mov r16, r24
+ address.bytes[1] = getch();
+ 1fcc0: 9b d0 rcall .+310 ; 0x1fdf8
+ 1fcc2: 18 2f mov r17, r24
+ 1fcc4: 87 ff sbrs r24, 7
+#ifdef RAMPZ
+ // Transfer top bit to LSB in RAMPZ
+ if (address.bytes[1] & 0x80) {
+ 1fcc6: 03 c0 rjmp .+6 ; 0x1fcce
+ RAMPZ |= 0x01;
+ 1fcc8: 8b b7 in r24, 0x3b ; 59
+ 1fcca: 81 60 ori r24, 0x01 ; 1
+ }
+ else {
+ RAMPZ &= 0xFE;
+ 1fccc: 02 c0 rjmp .+4 ; 0x1fcd2
+ 1fcce: 8b b7 in r24, 0x3b ; 59
+ }
+#endif
+ address.word *= 2; // Convert from word address to byte address
+ 1fcd0: 8e 7f andi r24, 0xFE ; 254
+ 1fcd2: 8b bf out 0x3b, r24 ; 59
+ 1fcd4: 00 0f add r16, r16
+ verifySpace();
+ }
+ else if(ch == STK_UNIVERSAL) {
+ 1fcd6: 11 1f adc r17, r17
+#ifdef RAMPZ
+ // LOAD_EXTENDED_ADDRESS is needed in STK_UNIVERSAL for addressing more than 128kB
+ if ( AVR_OP_LOAD_EXT_ADDR == getch() ) {
+ 1fcd8: 84 c0 rjmp .+264 ; 0x1fde2
+ 1fcda: 86 35 cpi r24, 0x56 ; 86
+ 1fcdc: 81 f4 brne .+32 ; 0x1fcfe
+ 1fcde: 8c d0 rcall .+280 ; 0x1fdf8
+ // get address
+ getch(); // get '0'
+ 1fce0: 8d 34 cpi r24, 0x4D ; 77
+ 1fce2: 59 f4 brne .+22 ; 0x1fcfa
+ RAMPZ = (RAMPZ & 0x01) | ((getch() << 1) & 0xff); // get address and put it in RAMPZ
+ 1fce4: 89 d0 rcall .+274 ; 0x1fdf8
+ 1fce6: cb b7 in r28, 0x3b ; 59
+ 1fce8: 87 d0 rcall .+270 ; 0x1fdf8
+ 1fcea: c1 70 andi r28, 0x01 ; 1
+ 1fcec: 88 0f add r24, r24
+ 1fcee: c8 2b or r28, r24
+ getNch(1); // get last '0'
+ 1fcf0: cb bf out 0x3b, r28 ; 59
+ 1fcf2: 81 e0 ldi r24, 0x01 ; 1
+ // response
+ putch(0x00);
+ 1fcf4: 9b d0 rcall .+310 ; 0x1fe2c
+ 1fcf6: 80 e0 ldi r24, 0x00 ; 0
+ }
+ else {
+ // everything else is ignored
+ getNch(3);
+ 1fcf8: d4 cf rjmp .-88 ; 0x1fca2
+ 1fcfa: 83 e0 ldi r24, 0x03 ; 3
+ getNch(4);
+ putch(0x00);
+#endif
+ }
+ /* Write memory, length is big endian and is in bytes */
+ else if(ch == STK_PROG_PAGE) {
+ 1fcfc: fb cf rjmp .-10 ; 0x1fcf4
+ 1fcfe: 84 36 cpi r24, 0x64 ; 100
+ // PROGRAM PAGE - we support flash programming only, not EEPROM
+ uint8_t desttype;
+ uint8_t *bufPtr;
+ pagelen_t savelength;
+
+ GETLENGTH(length);
+ 1fd00: 09 f0 breq .+2 ; 0x1fd04
+ 1fd02: c3 cf rjmp .-122 ; 0x1fc8a
+ 1fd04: 79 d0 rcall .+242 ; 0x1fdf8
+ 1fd06: c8 2f mov r28, r24
+ 1fd08: d0 e0 ldi r29, 0x00 ; 0
+ 1fd0a: dc 2f mov r29, r28
+ 1fd0c: cc 27 eor r28, r28
+ 1fd0e: 74 d0 rcall .+232 ; 0x1fdf8
+ savelength = length;
+ desttype = getch();
+ 1fd10: c8 2b or r28, r24
+ 1fd12: 72 d0 rcall .+228 ; 0x1fdf8
+ 1fd14: c8 2e mov r12, r24
+ // PROGRAM PAGE - we support flash programming only, not EEPROM
+ uint8_t desttype;
+ uint8_t *bufPtr;
+ pagelen_t savelength;
+
+ GETLENGTH(length);
+ 1fd16: 5e 01 movw r10, r28
+ savelength = length;
+ desttype = getch();
+ 1fd18: 81 2c mov r8, r1
+ 1fd1a: 32 e0 ldi r19, 0x02 ; 2
+ 1fd1c: 93 2e mov r9, r19
+
+ // read a page worth of contents
+ bufPtr = buff.bptr;
+ do *bufPtr++ = getch();
+ 1fd1e: 6c d0 rcall .+216 ; 0x1fdf8
+ 1fd20: f4 01 movw r30, r8
+ 1fd22: 81 93 st Z+, r24
+ 1fd24: 4f 01 movw r8, r30
+ 1fd26: f1 e0 ldi r31, 0x01 ; 1
+ while (--length);
+ 1fd28: af 1a sub r10, r31
+ 1fd2a: b1 08 sbc r11, r1
+ 1fd2c: c1 f7 brne .-16 ; 0x1fd1e
+
+ // Read command terminator, start reply
+ verifySpace();
+ 1fd2e: 76 d0 rcall .+236 ; 0x1fe1c
+ 1fd30: 85 e4 ldi r24, 0x45 ; 69
+ * void writebuffer(memtype, buffer, address, length)
+ */
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+ addr16_t address, pagelen_t len)
+{
+ switch (memtype) {
+ 1fd32: c8 12 cpse r12, r24
+ 1fd34: 12 c0 rjmp .+36 ; 0x1fd5a
+ 1fd36: de 5f subi r29, 0xFE ; 254
+ 1fd38: 48 01 movw r8, r16
+ 1fd3a: a1 2c mov r10, r1
+ 1fd3c: 92 e0 ldi r25, 0x02 ; 2
+ 1fd3e: b9 2e mov r11, r25
+ 1fd40: ac 16 cp r10, r28
+ case 'E': // EEPROM
+#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
+ while(len--) {
+ 1fd42: bd 06 cpc r11, r29
+ 1fd44: 09 f4 brne .+2 ; 0x1fd48
+ 1fd46: 4e c0 rjmp .+156 ; 0x1fde4
+ 1fd48: f5 01 movw r30, r10
+ eeprom_write_byte((address.bptr++), *(mybuff.bptr++));
+ 1fd4a: 61 91 ld r22, Z+
+ 1fd4c: 5f 01 movw r10, r30
+ 1fd4e: c4 01 movw r24, r8
+ 1fd50: 82 d0 rcall .+260 ; 0x1fe56
+ 1fd52: ff ef ldi r31, 0xFF ; 255
+ 1fd54: 8f 1a sub r8, r31
+ 1fd56: 9f 0a sbc r9, r31
+ 1fd58: f3 cf rjmp .-26 ; 0x1fd40
+ 1fd5a: 83 e0 ldi r24, 0x03 ; 3
+ 1fd5c: f8 01 movw r30, r16
+ * Start the page erase and wait for it to finish. There
+ * used to be code to do this while receiving the data over
+ * the serial link, but the performance improvement was slight,
+ * and we needed the space back.
+ */
+ __boot_page_erase_short(address.word);
+ 1fd5e: 87 bf out 0x37, r24 ; 55
+ 1fd60: e8 95 spm
+ 1fd62: 07 b6 in r0, 0x37 ; 55
+ 1fd64: 00 fc sbrc r0, 0
+ boot_spm_busy_wait();
+ 1fd66: fd cf rjmp .-6 ; 0x1fd62
+ 1fd68: a0 e0 ldi r26, 0x00 ; 0
+ 1fd6a: b2 e0 ldi r27, 0x02 ; 2
+ 1fd6c: f8 01 movw r30, r16
+ 1fd6e: 8d 91 ld r24, X+
+
+ /*
+ * Copy data from the buffer into the flash write buffer.
+ */
+ do {
+ __boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+ 1fd70: 9d 91 ld r25, X+
+ 1fd72: 0c 01 movw r0, r24
+ 1fd74: f7 be out 0x37, r15 ; 55
+ 1fd76: e8 95 spm
+ 1fd78: 11 24 eor r1, r1
+ addrPtr += 2;
+ } while (len -= 2);
+ 1fd7a: 22 97 sbiw r28, 0x02 ; 2
+ 1fd7c: 32 96 adiw r30, 0x02 ; 2
+ 1fd7e: 20 97 sbiw r28, 0x00 ; 0
+
+ /*
+ * Actually Write the buffer to flash (and wait for it to finish.)
+ */
+ __boot_page_write_short(address.word);
+ 1fd80: b1 f7 brne .-20 ; 0x1fd6e
+ 1fd82: f8 01 movw r30, r16
+ 1fd84: e7 be out 0x37, r14 ; 55
+ boot_spm_busy_wait();
+ 1fd86: e8 95 spm
+#if defined(RWWSRE)
+ // Reenable read access to flash
+ __boot_rww_enable_short();
+ 1fd88: 07 b6 in r0, 0x37 ; 55
+ 1fd8a: 00 fc sbrc r0, 0
+ 1fd8c: fd cf rjmp .-6 ; 0x1fd88
+
+ }
+ /* Read memory block mode, length is big endian. */
+ else if(ch == STK_READ_PAGE) {
+ uint8_t desttype;
+ GETLENGTH(length);
+ 1fd8e: d7 be out 0x37, r13 ; 55
+ 1fd90: e8 95 spm
+ 1fd92: 28 c0 rjmp .+80 ; 0x1fde4
+ 1fd94: 31 d0 rcall .+98 ; 0x1fdf8
+ 1fd96: c8 2f mov r28, r24
+ 1fd98: d0 e0 ldi r29, 0x00 ; 0
+ 1fd9a: dc 2f mov r29, r28
+ 1fd9c: cc 27 eor r28, r28
+ 1fd9e: 2c d0 rcall .+88 ; 0x1fdf8
+
+ desttype = getch();
+ 1fda0: 5e 01 movw r10, r28
+ 1fda2: a8 2a or r10, r24
+ 1fda4: 29 d0 rcall .+82 ; 0x1fdf8
+
+ verifySpace();
+ 1fda6: 98 2e mov r9, r24
+ 1fda8: 39 d0 rcall .+114 ; 0x1fe1c
+ 1fdaa: e8 01 movw r28, r16
+
+static inline void read_mem(uint8_t memtype, addr16_t address, pagelen_t length)
+{
+ uint8_t ch;
+
+ switch (memtype) {
+ 1fdac: f5 e4 ldi r31, 0x45 ; 69
+
+#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
+ case 'E': // EEPROM
+ do {
+ putch(eeprom_read_byte((address.bptr++)));
+ 1fdae: 9f 12 cpse r9, r31
+ 1fdb0: 0b c0 rjmp .+22 ; 0x1fdc8
+ 1fdb2: ce 01 movw r24, r28
+ 1fdb4: 48 d0 rcall .+144 ; 0x1fe46
+ } while (--length);
+ 1fdb6: 19 d0 rcall .+50 ; 0x1fdea
+ 1fdb8: 81 e0 ldi r24, 0x01 ; 1
+ 1fdba: a8 1a sub r10, r24
+ 1fdbc: b1 08 sbc r11, r1
+ 1fdbe: 21 96 adiw r28, 0x01 ; 1
+ 1fdc0: a1 14 cp r10, r1
+ 1fdc2: b1 04 cpc r11, r1
+ 1fdc4: b1 f7 brne .-20 ; 0x1fdb2
+ // Since RAMPZ should already be set, we need to use EPLM directly.
+ // Also, we can use the autoincrement version of lpm to update "address"
+ // do putch(pgm_read_byte_near(address++));
+ // while (--length);
+ // read a Flash and increment the address (may increment RAMPZ)
+ __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+ 1fdc6: 0e c0 rjmp .+28 ; 0x1fde4
+ 1fdc8: fe 01 movw r30, r28
+ 1fdca: 87 91 elpm r24, Z+
+#else
+ // read a Flash byte and increment the address
+ __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+#endif
+ putch(ch);
+ 1fdcc: ef 01 movw r28, r30
+ 1fdce: 0d d0 rcall .+26 ; 0x1fdea
+ } while (--length);
+ 1fdd0: e1 e0 ldi r30, 0x01 ; 1
+ 1fdd2: ae 1a sub r10, r30
+ 1fdd4: b1 08 sbc r11, r1
+ 1fdd6: c1 f7 brne .-16 ; 0x1fdc8
+ 1fdd8: 05 c0 rjmp .+10 ; 0x1fde4
+ verifySpace();
+ putch(SIGNATURE_0);
+ putch(SIGNATURE_1);
+ putch(SIGNATURE_2);
+ }
+ else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+ 1fdda: 81 35 cpi r24, 0x51 ; 81
+ 1fddc: 11 f4 brne .+4 ; 0x1fde2
+ // Adaboot no-wait mod
+ watchdogConfig(WATCHDOG_16MS);
+ 1fdde: 88 e0 ldi r24, 0x08 ; 8
+ 1fde0: 17 d0 rcall .+46 ; 0x1fe10
+ 1fde2: 1c d0 rcall .+56 ; 0x1fe1c
+ verifySpace();
+ }
+ else {
+ // This covers the response to commands like STK_ENTER_PROGMODE
+ verifySpace();
+ 1fde4: 80 e1 ldi r24, 0x10 ; 16
+ 1fde6: 01 d0 rcall .+2 ; 0x1fdea
+ }
+ putch(STK_OK);
+ 1fde8: 43 cf rjmp .-378 ; 0x1fc70
+
+0001fdea :
+ 1fdea: 90 91 c0 00 lds r25, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ }
+ 1fdee: 95 ff sbrs r25, 5
+}
+
+void putch(char ch) {
+#ifndef SOFT_UART
+ while (!(UART_SRA & _BV(UDRE0)));
+ 1fdf0: fc cf rjmp .-8 ; 0x1fdea
+ UART_UDR = ch;
+ 1fdf2: 80 93 c6 00 sts 0x00C6, r24 ; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+ 1fdf6: 08 95 ret
+
+0001fdf8 :
+ [uartBit] "I" (UART_RX_BIT)
+ :
+ "r25"
+);
+#else
+ while(!(UART_SRA & _BV(RXC0)))
+ 1fdf8: 80 91 c0 00 lds r24, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ 1fdfc: 87 ff sbrs r24, 7
+ 1fdfe: fc cf rjmp .-8 ; 0x1fdf8
+ ;
+ if (!(UART_SRA & _BV(FE0))) {
+ 1fe00: 80 91 c0 00 lds r24, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ 1fe04: 84 fd sbrc r24, 4
+ 1fe06: 01 c0 rjmp .+2 ; 0x1fe0a
+}
+#endif
+
+// Watchdog functions. These are only safe with interrupts turned off.
+void watchdogReset() {
+ __asm__ __volatile__ (
+ 1fe08: a8 95 wdr
+ * don't care that an invalid char is returned...)
+ */
+ watchdogReset();
+ }
+
+ ch = UART_UDR;
+ 1fe0a: 80 91 c6 00 lds r24, 0x00C6 ; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+ LED_PIN |= _BV(LED);
+#endif
+#endif
+
+ return ch;
+}
+ 1fe0e: 08 95 ret
+
+0001fe10 :
+ "wdr\n"
+ );
+}
+
+void watchdogConfig(uint8_t x) {
+ WDTCSR = _BV(WDCE) | _BV(WDE);
+ 1fe10: e0 e6 ldi r30, 0x60 ; 96
+ 1fe12: f0 e0 ldi r31, 0x00 ; 0
+ 1fe14: 98 e1 ldi r25, 0x18 ; 24
+ 1fe16: 90 83 st Z, r25
+ WDTCSR = x;
+ 1fe18: 80 83 st Z, r24
+ 1fe1a: 08 95 ret
+
+0001fe1c :
+ do getch(); while (--count);
+ verifySpace();
+}
+
+void verifySpace() {
+ if (getch() != CRC_EOP) {
+ 1fe1c: ed df rcall .-38 ; 0x1fdf8
+ 1fe1e: 80 32 cpi r24, 0x20 ; 32
+ 1fe20: 19 f0 breq .+6 ; 0x1fe28
+ watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
+ 1fe22: 88 e0 ldi r24, 0x08 ; 8
+ 1fe24: f5 df rcall .-22 ; 0x1fe10
+ 1fe26: ff cf rjmp .-2 ; 0x1fe26
+ while (1) // and busy-loop so that WD causes
+ ; // a reset and app start.
+ }
+ putch(STK_INSYNC);
+ 1fe28: 84 e1 ldi r24, 0x14 ; 20
+ 1fe2a: df cf rjmp .-66 ; 0x1fdea
+
+0001fe2c :
+ ::[count] "M" (UART_B_VALUE)
+ );
+}
+#endif
+
+void getNch(uint8_t count) {
+ 1fe2c: cf 93 push r28
+ 1fe2e: c8 2f mov r28, r24
+ do getch(); while (--count);
+ 1fe30: e3 df rcall .-58 ; 0x1fdf8
+ 1fe32: c1 50 subi r28, 0x01 ; 1
+ 1fe34: e9 f7 brne .-6 ; 0x1fe30
+ verifySpace();
+ 1fe36: cf 91 pop r28
+ 1fe38: f1 cf rjmp .-30 ; 0x1fe1c
+
+0001fe3a :
+
+void appStart(uint8_t rstFlags) {
+ // save the reset flags in the designated register
+ // This can be saved in a main program by putting code in .init0 (which
+ // executes before normal c init code) to save R2 to a global variable.
+ __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
+ 1fe3a: 28 2e mov r2, r24
+
+ watchdogConfig(WATCHDOG_OFF);
+ 1fe3c: 80 e0 ldi r24, 0x00 ; 0
+ 1fe3e: e8 df rcall .-48 ; 0x1fe10
+ 1fe40: e0 e0 ldi r30, 0x00 ; 0
+ // Note that appstart_vec is defined so that this works with either
+ // real or virtual boot partitions.
+ __asm__ __volatile__ (
+ 1fe42: ff 27 eor r31, r31
+ 1fe44: 09 94 ijmp
+
+0001fe46 :
+ 1fe46: f9 99 sbic 0x1f, 1 ; 31
+ 1fe48: fe cf rjmp .-4 ; 0x1fe46
+ 1fe4a: 92 bd out 0x22, r25 ; 34
+ 1fe4c: 81 bd out 0x21, r24 ; 33
+ 1fe4e: f8 9a sbi 0x1f, 0 ; 31
+ 1fe50: 99 27 eor r25, r25
+ 1fe52: 80 b5 in r24, 0x20 ; 32
+ 1fe54: 08 95 ret
+
+0001fe56 :
+ 1fe56: 26 2f mov r18, r22
+
+0001fe58 :
+ 1fe58: f9 99 sbic 0x1f, 1 ; 31
+ 1fe5a: fe cf rjmp .-4 ; 0x1fe58
+ 1fe5c: 1f ba out 0x1f, r1 ; 31
+ 1fe5e: 92 bd out 0x22, r25 ; 34
+ 1fe60: 81 bd out 0x21, r24 ; 33
+ 1fe62: 20 bd out 0x20, r18 ; 32
+ 1fe64: 0f b6 in r0, 0x3f ; 63
+ 1fe66: f8 94 cli
+ 1fe68: fa 9a sbi 0x1f, 2 ; 31
+ 1fe6a: f9 9a sbi 0x1f, 1 ; 31
+ 1fe6c: 0f be out 0x3f, r0 ; 63
+ 1fe6e: 01 96 adiw r24, 0x01 ; 1
+ 1fe70: 08 95 ret
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega328.hex b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega328.hex
new file mode 100644
index 0000000..8e1e547
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega328.hex
@@ -0,0 +1,31 @@
+:107E0000112484B7882349F0982F9A70923029F072
+:107E100081FF02C097EF94BFCCD085E080938100B2
+:107E200082E08093C00088E18093C10086E0809367
+:107E3000C20080E18093C4008EE0A6D0259A86E03F
+:107E400020E33CEF91E0309385002093840096BBC3
+:107E5000B09BFECF1D9AA8954091C00047FD02C07F
+:107E6000815089F7EE24E39495E0D92E21E1C22ECA
+:107E70007FD0813461F47CD0182F8CD01238E9F097
+:107E8000113811F487E001C083E06BD067C0823401
+:107E900011F484E103C0853419F485E083D05EC019
+:107EA000853539F465D0C82F63D0D82FCC0FDD1FAE
+:107EB00054C0863521F484E075D080E0E6CF843666
+:107EC00009F02EC055D054D0F82E52D0B82E00E074
+:107ED00011E04ED0F80181938F01FE12FACF5AD0F3
+:107EE000F5E4BF1201C0FFCF83E0FE0187BFE89534
+:107EF00007B600FCFDCFA0E0B1E0FE018D919D91A1
+:107F00000C01E7BEE89511243296FA12F7CFFE0174
+:107F1000D7BEE89507B600FCFDCFC7BEE8951EC0EA
+:107F2000843771F425D024D0F82E22D033D08E019E
+:107F3000F80185918F0115D0FA94F110F9CF0EC098
+:107F4000853739F427D08EE10CD085E90AD08FE04F
+:107F50009CCF813511F488E017D01CD080E101D08E
+:107F600087CF9091C00095FFFCCF8093C600089505
+:107F70008091C00087FFFCCF8091C00084FD01C0CC
+:107F8000A8958091C6000895E0E6F0E098E190831E
+:107F900080830895EDDF803219F088E0F5DFFFCFB0
+:107FA00084E1DFCFCF93C82FE3DFC150E9F7CF9152
+:0E7FB000F1CF282E80E0E8DFE0E0FF27099403
+:027FFE0000077A
+:0400000300007E007B
+:00000001FF
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega328.lst b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega328.lst
new file mode 100644
index 0000000..f27d30c
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega328.lst
@@ -0,0 +1,584 @@
+
+optiboot_atmega328.elf: file format elf32-avr
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 .data 00000000 00800100 00007fbe 00000252 2**0
+ CONTENTS, ALLOC, LOAD, DATA
+ 1 .text 000001be 00007e00 00007e00 00000094 2**1
+ CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 2 .version 00000002 00007ffe 00007ffe 00000252 2**0
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+ 3 .comment 0000002f 00000000 00000000 00000254 2**0
+ CONTENTS, READONLY
+ 4 .debug_aranges 00000028 00000000 00000000 00000283 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 5 .debug_info 000005c8 00000000 00000000 000002ab 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 6 .debug_abbrev 00000282 00000000 00000000 00000873 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 7 .debug_line 000002f9 00000000 00000000 00000af5 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 8 .debug_frame 0000008c 00000000 00000000 00000df0 2**2
+ CONTENTS, READONLY, DEBUGGING
+ 9 .debug_str 000001fa 00000000 00000000 00000e7c 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 10 .debug_loc 00000331 00000000 00000000 00001076 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 11 .debug_ranges 00000060 00000000 00000000 000013a7 2**0
+ CONTENTS, READONLY, DEBUGGING
+
+Disassembly of section .text:
+
+00007e00 :
+ // SP points to RAMEND
+ // r1 contains zero
+ //
+ // If not, uncomment the following instructions:
+ // cli();
+ asm volatile ("clr __zero_reg__");
+ 7e00: 11 24 eor r1, r1
+ *
+ * Code by MarkG55
+ * see discusion in https://github.com/Optiboot/optiboot/issues/97
+ */
+#if !defined(__AVR_ATmega16__)
+ ch = MCUSR;
+ 7e02: 84 b7 in r24, 0x34 ; 52
+#else
+ ch = MCUCSR;
+#endif
+ // Skip all logic and run bootloader if MCUSR is cleared (application request)
+ if (ch != 0) {
+ 7e04: 88 23 and r24, r24
+ 7e06: 49 f0 breq .+18 ; 0x7e1a
+ * 2. we clear WDRF if it's set with EXTRF to avoid loops
+ * One problematic scenario: broken application code sets watchdog timer
+ * without clearing MCUSR before and triggers it quickly. But it's
+ * recoverable by power-on with pushed reset button.
+ */
+ if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) {
+ 7e08: 98 2f mov r25, r24
+ 7e0a: 9a 70 andi r25, 0x0A ; 10
+ 7e0c: 92 30 cpi r25, 0x02 ; 2
+ 7e0e: 29 f0 breq .+10 ; 0x7e1a
+ if (ch & _BV(EXTRF)) {
+ 7e10: 81 ff sbrs r24, 1
+ 7e12: 02 c0 rjmp .+4 ; 0x7e18
+ * prevent entering bootloader.
+ * '&' operation is skipped to spare few bytes as bits in MCUSR
+ * can only be cleared.
+ */
+#if !defined(__AVR_ATmega16__)
+ MCUSR = ~(_BV(WDRF));
+ 7e14: 97 ef ldi r25, 0xF7 ; 247
+ 7e16: 94 bf out 0x34, r25 ; 52
+#else
+ MCUCSR = ~(_BV(WDRF));
+#endif
+ }
+ appStart(ch);
+ 7e18: cc d0 rcall .+408 ; 0x7fb2
+ }
+ }
+
+#if LED_START_FLASHES > 0
+ // Set up Timer 1 for timeout counter
+ TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+ 7e1a: 85 e0 ldi r24, 0x05 ; 5
+ 7e1c: 80 93 81 00 sts 0x0081, r24 ; 0x800081 <__TEXT_REGION_LENGTH__+0x7e0081>
+ UCSRA = _BV(U2X); //Double speed mode USART
+ UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
+ UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
+ UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+#else
+ UART_SRA = _BV(U2X0); //Double speed mode USART0
+ 7e20: 82 e0 ldi r24, 0x02 ; 2
+ 7e22: 80 93 c0 00 sts 0x00C0, r24 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ UART_SRB = _BV(RXEN0) | _BV(TXEN0);
+ 7e26: 88 e1 ldi r24, 0x18 ; 24
+ 7e28: 80 93 c1 00 sts 0x00C1, r24 ; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7e00c1>
+ UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
+ 7e2c: 86 e0 ldi r24, 0x06 ; 6
+ 7e2e: 80 93 c2 00 sts 0x00C2, r24 ; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7e00c2>
+ UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+ 7e32: 80 e1 ldi r24, 0x10 ; 16
+ 7e34: 80 93 c4 00 sts 0x00C4, r24 ; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7e00c4>
+#endif
+#endif
+
+ // Set up watchdog to trigger after 1s
+ watchdogConfig(WATCHDOG_1S);
+ 7e38: 8e e0 ldi r24, 0x0E ; 14
+ 7e3a: a6 d0 rcall .+332 ; 0x7f88
+
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
+ /* Set LED pin as output */
+ LED_DDR |= _BV(LED);
+ 7e3c: 25 9a sbi 0x04, 5 ; 4
+ 7e3e: 86 e0 ldi r24, 0x06 ; 6
+}
+
+#if LED_START_FLASHES > 0
+void flash_led(uint8_t count) {
+ do {
+ TCNT1 = -(F_CPU/(1024*16));
+ 7e40: 20 e3 ldi r18, 0x30 ; 48
+ 7e42: 3c ef ldi r19, 0xFC ; 252
+ TIFR1 = _BV(TOV1);
+ 7e44: 91 e0 ldi r25, 0x01 ; 1
+}
+
+#if LED_START_FLASHES > 0
+void flash_led(uint8_t count) {
+ do {
+ TCNT1 = -(F_CPU/(1024*16));
+ 7e46: 30 93 85 00 sts 0x0085, r19 ; 0x800085 <__TEXT_REGION_LENGTH__+0x7e0085>
+ 7e4a: 20 93 84 00 sts 0x0084, r18 ; 0x800084 <__TEXT_REGION_LENGTH__+0x7e0084>
+ TIFR1 = _BV(TOV1);
+ 7e4e: 96 bb out 0x16, r25 ; 22
+ while(!(TIFR1 & _BV(TOV1)));
+ 7e50: b0 9b sbis 0x16, 0 ; 22
+ 7e52: fe cf rjmp .-4 ; 0x7e50
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
+ LED_PORT ^= _BV(LED);
+#else
+ LED_PIN |= _BV(LED);
+ 7e54: 1d 9a sbi 0x03, 5 ; 3
+}
+#endif
+
+// Watchdog functions. These are only safe with interrupts turned off.
+void watchdogReset() {
+ __asm__ __volatile__ (
+ 7e56: a8 95 wdr
+ * While in theory, the STK500 initial commands would be buffered
+ * by the UART hardware, avrdude sends several attempts in rather
+ * quick succession, some of which will be lost and cause us to
+ * get out of sync. So if we see any data; stop blinking.
+ */
+ if (UART_SRA & _BV(RXC0))
+ 7e58: 40 91 c0 00 lds r20, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ 7e5c: 47 fd sbrc r20, 7
+ 7e5e: 02 c0 rjmp .+4 ; 0x7e64
+ 7e60: 81 50 subi r24, 0x01 ; 1
+#else
+// This doesn't seem to work?
+// if ((UART_PIN & (1<
+
+ /*
+ * Copy data from the buffer into the flash write buffer.
+ */
+ do {
+ __boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+ 7e64: ee 24 eor r14, r14
+ 7e66: e3 94 inc r14
+ } while (len -= 2);
+
+ /*
+ * Actually Write the buffer to flash (and wait for it to finish.)
+ */
+ __boot_page_write_short(address.word);
+ 7e68: 95 e0 ldi r25, 0x05 ; 5
+ 7e6a: d9 2e mov r13, r25
+ boot_spm_busy_wait();
+#if defined(RWWSRE)
+ // Reenable read access to flash
+ __boot_rww_enable_short();
+ 7e6c: 21 e1 ldi r18, 0x11 ; 17
+#endif
+
+ /* Forever loop: exits by causing WDT reset */
+ for (;;) {
+ /* get character from UART */
+ ch = getch();
+ 7e6e: c2 2e mov r12, r18
+
+ if(ch == STK_GET_PARAMETER) {
+ 7e70: 7f d0 rcall .+254 ; 0x7f70
+ unsigned char which = getch();
+ 7e72: 81 34 cpi r24, 0x41 ; 65
+ 7e74: 61 f4 brne .+24 ; 0x7e8e
+ 7e76: 7c d0 rcall .+248 ; 0x7f70
+ verifySpace();
+ 7e78: 18 2f mov r17, r24
+ 7e7a: 8c d0 rcall .+280 ; 0x7f94
+ /*
+ * Send optiboot version as "SW version"
+ * Note that the references to memory are optimized away.
+ */
+ if (which == STK_SW_MINOR) {
+ 7e7c: 12 38 cpi r17, 0x82 ; 130
+ 7e7e: e9 f0 breq .+58 ; 0x7eba
+ putch(optiboot_version & 0xFF);
+ } else if (which == STK_SW_MAJOR) {
+ 7e80: 11 38 cpi r17, 0x81 ; 129
+ putch(optiboot_version >> 8);
+ 7e82: 11 f4 brne .+4 ; 0x7e88
+ 7e84: 87 e0 ldi r24, 0x07 ; 7
+ } else {
+ /*
+ * GET PARAMETER returns a generic 0x03 reply for
+ * other parameters - enough to keep Avrdude happy
+ */
+ putch(0x03);
+ 7e86: 01 c0 rjmp .+2 ; 0x7e8a
+ 7e88: 83 e0 ldi r24, 0x03 ; 3
+ 7e8a: 6b d0 rcall .+214 ; 0x7f62
+ 7e8c: 67 c0 rjmp .+206 ; 0x7f5c
+ }
+ }
+ else if(ch == STK_SET_DEVICE) {
+ 7e8e: 82 34 cpi r24, 0x42 ; 66
+ // SET DEVICE is ignored
+ getNch(20);
+ 7e90: 11 f4 brne .+4 ; 0x7e96
+ 7e92: 84 e1 ldi r24, 0x14 ; 20
+ }
+ else if(ch == STK_SET_DEVICE_EXT) {
+ 7e94: 03 c0 rjmp .+6 ; 0x7e9c
+ // SET DEVICE EXT is ignored
+ getNch(5);
+ 7e96: 85 34 cpi r24, 0x45 ; 69
+ 7e98: 19 f4 brne .+6 ; 0x7ea0
+ 7e9a: 85 e0 ldi r24, 0x05 ; 5
+ }
+ else if(ch == STK_LOAD_ADDRESS) {
+ 7e9c: 83 d0 rcall .+262 ; 0x7fa4
+ 7e9e: 5e c0 rjmp .+188 ; 0x7f5c
+ // LOAD ADDRESS
+ address.bytes[0] = getch();
+ 7ea0: 85 35 cpi r24, 0x55 ; 85
+ 7ea2: 39 f4 brne .+14 ; 0x7eb2
+ 7ea4: 65 d0 rcall .+202 ; 0x7f70
+ address.bytes[1] = getch();
+ 7ea6: c8 2f mov r28, r24
+ 7ea8: 63 d0 rcall .+198 ; 0x7f70
+ }
+ else {
+ RAMPZ &= 0xFE;
+ }
+#endif
+ address.word *= 2; // Convert from word address to byte address
+ 7eaa: d8 2f mov r29, r24
+ 7eac: cc 0f add r28, r28
+ 7eae: dd 1f adc r29, r29
+ verifySpace();
+ }
+ else if(ch == STK_UNIVERSAL) {
+ 7eb0: 54 c0 rjmp .+168 ; 0x7f5a
+ getNch(3);
+ putch(0x00);
+ }
+#else
+ // UNIVERSAL command is ignored
+ getNch(4);
+ 7eb2: 86 35 cpi r24, 0x56 ; 86
+ 7eb4: 21 f4 brne .+8 ; 0x7ebe
+ putch(0x00);
+ 7eb6: 84 e0 ldi r24, 0x04 ; 4
+ 7eb8: 75 d0 rcall .+234 ; 0x7fa4
+#endif
+ }
+ /* Write memory, length is big endian and is in bytes */
+ else if(ch == STK_PROG_PAGE) {
+ 7eba: 80 e0 ldi r24, 0x00 ; 0
+ 7ebc: e6 cf rjmp .-52 ; 0x7e8a
+ // PROGRAM PAGE - we support flash programming only, not EEPROM
+ uint8_t desttype;
+ uint8_t *bufPtr;
+ pagelen_t savelength;
+
+ GETLENGTH(length);
+ 7ebe: 84 36 cpi r24, 0x64 ; 100
+ 7ec0: 09 f0 breq .+2 ; 0x7ec4
+ 7ec2: 2e c0 rjmp .+92 ; 0x7f20
+ 7ec4: 55 d0 rcall .+170 ; 0x7f70
+ savelength = length;
+ desttype = getch();
+ 7ec6: 54 d0 rcall .+168 ; 0x7f70
+ 7ec8: f8 2e mov r15, r24
+ 7eca: 52 d0 rcall .+164 ; 0x7f70
+ 7ecc: b8 2e mov r11, r24
+ 7ece: 00 e0 ldi r16, 0x00 ; 0
+
+ // read a page worth of contents
+ bufPtr = buff.bptr;
+ do *bufPtr++ = getch();
+ 7ed0: 11 e0 ldi r17, 0x01 ; 1
+ 7ed2: 4e d0 rcall .+156 ; 0x7f70
+ 7ed4: f8 01 movw r30, r16
+ 7ed6: 81 93 st Z+, r24
+ 7ed8: 8f 01 movw r16, r30
+ while (--length);
+ 7eda: fe 12 cpse r15, r30
+ 7edc: fa cf rjmp .-12 ; 0x7ed2
+
+ // Read command terminator, start reply
+ verifySpace();
+ 7ede: 5a d0 rcall .+180 ; 0x7f94
+ 7ee0: f5 e4 ldi r31, 0x45 ; 69
+ * void writebuffer(memtype, buffer, address, length)
+ */
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+ addr16_t address, pagelen_t len)
+{
+ switch (memtype) {
+ 7ee2: bf 12 cpse r11, r31
+ 7ee4: 01 c0 rjmp .+2 ; 0x7ee8
+ 7ee6: ff cf rjmp .-2 ; 0x7ee6
+ 7ee8: 83 e0 ldi r24, 0x03 ; 3
+ * Start the page erase and wait for it to finish. There
+ * used to be code to do this while receiving the data over
+ * the serial link, but the performance improvement was slight,
+ * and we needed the space back.
+ */
+ __boot_page_erase_short(address.word);
+ 7eea: fe 01 movw r30, r28
+ 7eec: 87 bf out 0x37, r24 ; 55
+ 7eee: e8 95 spm
+ 7ef0: 07 b6 in r0, 0x37 ; 55
+ boot_spm_busy_wait();
+ 7ef2: 00 fc sbrc r0, 0
+ 7ef4: fd cf rjmp .-6 ; 0x7ef0
+ 7ef6: a0 e0 ldi r26, 0x00 ; 0
+ 7ef8: b1 e0 ldi r27, 0x01 ; 1
+ 7efa: fe 01 movw r30, r28
+ 7efc: 8d 91 ld r24, X+
+
+ /*
+ * Copy data from the buffer into the flash write buffer.
+ */
+ do {
+ __boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+ 7efe: 9d 91 ld r25, X+
+ 7f00: 0c 01 movw r0, r24
+ 7f02: e7 be out 0x37, r14 ; 55
+ 7f04: e8 95 spm
+ 7f06: 11 24 eor r1, r1
+ 7f08: 32 96 adiw r30, 0x02 ; 2
+ addrPtr += 2;
+ } while (len -= 2);
+ 7f0a: fa 12 cpse r15, r26
+
+ /*
+ * Actually Write the buffer to flash (and wait for it to finish.)
+ */
+ __boot_page_write_short(address.word);
+ 7f0c: f7 cf rjmp .-18 ; 0x7efc
+ 7f0e: fe 01 movw r30, r28
+ boot_spm_busy_wait();
+ 7f10: d7 be out 0x37, r13 ; 55
+ 7f12: e8 95 spm
+#if defined(RWWSRE)
+ // Reenable read access to flash
+ __boot_rww_enable_short();
+ 7f14: 07 b6 in r0, 0x37 ; 55
+ 7f16: 00 fc sbrc r0, 0
+ 7f18: fd cf rjmp .-6 ; 0x7f14
+ writebuffer(desttype, buff, address, savelength);
+
+
+ }
+ /* Read memory block mode, length is big endian. */
+ else if(ch == STK_READ_PAGE) {
+ 7f1a: c7 be out 0x37, r12 ; 55
+ 7f1c: e8 95 spm
+ uint8_t desttype;
+ GETLENGTH(length);
+ 7f1e: 1e c0 rjmp .+60 ; 0x7f5c
+ 7f20: 84 37 cpi r24, 0x74 ; 116
+ 7f22: 71 f4 brne .+28 ; 0x7f40
+
+ desttype = getch();
+ 7f24: 25 d0 rcall .+74 ; 0x7f70
+
+ verifySpace();
+ 7f26: 24 d0 rcall .+72 ; 0x7f70
+ 7f28: f8 2e mov r15, r24
+ 7f2a: 22 d0 rcall .+68 ; 0x7f70
+ // while (--length);
+ // read a Flash and increment the address (may increment RAMPZ)
+ __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+#else
+ // read a Flash byte and increment the address
+ __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+ 7f2c: 33 d0 rcall .+102 ; 0x7f94
+ 7f2e: 8e 01 movw r16, r28
+#endif
+ putch(ch);
+ 7f30: f8 01 movw r30, r16
+ } while (--length);
+ 7f32: 85 91 lpm r24, Z+
+ 7f34: 8f 01 movw r16, r30
+ 7f36: 15 d0 rcall .+42 ; 0x7f62
+ 7f38: fa 94 dec r15
+
+ read_mem(desttype, address, length);
+ }
+
+ /* Get device signature bytes */
+ else if(ch == STK_READ_SIGN) {
+ 7f3a: f1 10 cpse r15, r1
+ 7f3c: f9 cf rjmp .-14 ; 0x7f30
+ // READ SIGN - return what Avrdude wants to hear
+ verifySpace();
+ 7f3e: 0e c0 rjmp .+28 ; 0x7f5c
+ 7f40: 85 37 cpi r24, 0x75 ; 117
+ putch(SIGNATURE_0);
+ 7f42: 39 f4 brne .+14 ; 0x7f52
+ 7f44: 27 d0 rcall .+78 ; 0x7f94
+ 7f46: 8e e1 ldi r24, 0x1E ; 30
+ putch(SIGNATURE_1);
+ 7f48: 0c d0 rcall .+24 ; 0x7f62
+ 7f4a: 85 e9 ldi r24, 0x95 ; 149
+ 7f4c: 0a d0 rcall .+20 ; 0x7f62
+ putch(SIGNATURE_2);
+ 7f4e: 8f e0 ldi r24, 0x0F ; 15
+ 7f50: 9c cf rjmp .-200 ; 0x7e8a
+ }
+ else if (ch == STK_LEAVE_PROGMODE) { /* 'Q' */
+ 7f52: 81 35 cpi r24, 0x51 ; 81
+ 7f54: 11 f4 brne .+4 ; 0x7f5a
+ // Adaboot no-wait mod
+ watchdogConfig(WATCHDOG_16MS);
+ 7f56: 88 e0 ldi r24, 0x08 ; 8
+ 7f58: 17 d0 rcall .+46 ; 0x7f88
+ 7f5a: 1c d0 rcall .+56 ; 0x7f94
+ verifySpace();
+ }
+ else {
+ // This covers the response to commands like STK_ENTER_PROGMODE
+ verifySpace();
+ 7f5c: 80 e1 ldi r24, 0x10 ; 16
+ 7f5e: 01 d0 rcall .+2 ; 0x7f62
+ }
+ putch(STK_OK);
+ 7f60: 87 cf rjmp .-242 ; 0x7e70
+
+00007f62 :
+ 7f62: 90 91 c0 00 lds r25, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ }
+ 7f66: 95 ff sbrs r25, 5
+}
+
+void putch(char ch) {
+#ifndef SOFT_UART
+ while (!(UART_SRA & _BV(UDRE0)));
+ 7f68: fc cf rjmp .-8 ; 0x7f62
+ UART_UDR = ch;
+ 7f6a: 80 93 c6 00 sts 0x00C6, r24 ; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+ 7f6e: 08 95 ret
+
+00007f70 :
+ [uartBit] "I" (UART_RX_BIT)
+ :
+ "r25"
+);
+#else
+ while(!(UART_SRA & _BV(RXC0)))
+ 7f70: 80 91 c0 00 lds r24, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ 7f74: 87 ff sbrs r24, 7
+ 7f76: fc cf rjmp .-8 ; 0x7f70
+ ;
+ if (!(UART_SRA & _BV(FE0))) {
+ 7f78: 80 91 c0 00 lds r24, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ 7f7c: 84 fd sbrc r24, 4
+ 7f7e: 01 c0 rjmp .+2 ; 0x7f82
+}
+#endif
+
+// Watchdog functions. These are only safe with interrupts turned off.
+void watchdogReset() {
+ __asm__ __volatile__ (
+ 7f80: a8 95 wdr
+ * don't care that an invalid char is returned...)
+ */
+ watchdogReset();
+ }
+
+ ch = UART_UDR;
+ 7f82: 80 91 c6 00 lds r24, 0x00C6 ; 0x8000c6 <__TEXT_REGION_LENGTH__+0x7e00c6>
+ LED_PIN |= _BV(LED);
+#endif
+#endif
+
+ return ch;
+}
+ 7f86: 08 95 ret
+
+00007f88 :
+ "wdr\n"
+ );
+}
+
+void watchdogConfig(uint8_t x) {
+ WDTCSR = _BV(WDCE) | _BV(WDE);
+ 7f88: e0 e6 ldi r30, 0x60 ; 96
+ 7f8a: f0 e0 ldi r31, 0x00 ; 0
+ 7f8c: 98 e1 ldi r25, 0x18 ; 24
+ 7f8e: 90 83 st Z, r25
+ WDTCSR = x;
+ 7f90: 80 83 st Z, r24
+ 7f92: 08 95 ret
+
+00007f94 :
+ do getch(); while (--count);
+ verifySpace();
+}
+
+void verifySpace() {
+ if (getch() != CRC_EOP) {
+ 7f94: ed df rcall .-38 ; 0x7f70
+ 7f96: 80 32 cpi r24, 0x20 ; 32
+ 7f98: 19 f0 breq .+6 ; 0x7fa0
+ watchdogConfig(WATCHDOG_16MS); // shorten WD timeout
+ 7f9a: 88 e0 ldi r24, 0x08 ; 8
+ 7f9c: f5 df rcall .-22 ; 0x7f88
+ 7f9e: ff cf rjmp .-2 ; 0x7f9e
+ while (1) // and busy-loop so that WD causes
+ ; // a reset and app start.
+ }
+ putch(STK_INSYNC);
+ 7fa0: 84 e1 ldi r24, 0x14 ; 20
+ 7fa2: df cf rjmp .-66 ; 0x7f62
+
+00007fa4 :
+ ::[count] "M" (UART_B_VALUE)
+ );
+}
+#endif
+
+void getNch(uint8_t count) {
+ 7fa4: cf 93 push r28
+ 7fa6: c8 2f mov r28, r24
+ do getch(); while (--count);
+ 7fa8: e3 df rcall .-58 ; 0x7f70
+ 7faa: c1 50 subi r28, 0x01 ; 1
+ 7fac: e9 f7 brne .-6 ; 0x7fa8
+ verifySpace();
+ 7fae: cf 91 pop r28
+ 7fb0: f1 cf rjmp .-30 ; 0x7f94
+
+00007fb2 :
+
+void appStart(uint8_t rstFlags) {
+ // save the reset flags in the designated register
+ // This can be saved in a main program by putting code in .init0 (which
+ // executes before normal c init code) to save R2 to a global variable.
+ __asm__ __volatile__ ("mov r2, %0\n" :: "r" (rstFlags));
+ 7fb2: 28 2e mov r2, r24
+
+ watchdogConfig(WATCHDOG_OFF);
+ 7fb4: 80 e0 ldi r24, 0x00 ; 0
+ 7fb6: e8 df rcall .-48 ; 0x7f88
+ 7fb8: e0 e0 ldi r30, 0x00 ; 0
+ // Note that appstart_vec is defined so that this works with either
+ // real or virtual boot partitions.
+ __asm__ __volatile__ (
+ 7fba: ff 27 eor r31, r31
+ 7fbc: 09 94 ijmp
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega644p.hex b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega644p.hex
new file mode 100644
index 0000000..997a61c
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega644p.hex
@@ -0,0 +1,40 @@
+:10FC0000112484B7882349F0982F9A70923029F0F4
+:10FC100081FF02C097EF94BFFBD085E08093810005
+:10FC200082E08093C00088E18093C10086E08093E9
+:10FC3000C20080E18093C4008EE0D5D0209A86E097
+:10FC400020E33CEF91E0309385002093840096BB45
+:10FC5000B09BFECF189AA8954091C00047FD02C006
+:10FC6000815089F7FF24F39455E0E52E61E1D62E0B
+:10FC7000AED0813461F4ABD0C82FBBD0C238E9F02C
+:10FC8000C13811F487E001C083E09AD096C0823475
+:10FC900011F484E103C0853419F485E0B2D08DC03D
+:10FCA000853539F494D0082F92D0182F000F111FEA
+:10FCB00083C0863521F484E0A4D080E0E6CF84368A
+:10FCC00009F048C084D0C82FD0E0DC2FCC277FD0EB
+:10FCD000C82B7DD0C82E5E01812C9924939477D0B7
+:10FCE000F40181934F01F1E0AF1AB108C1F781D05F
+:10FCF00085E4C81212C0D3954801A12CBB24B3944B
+:10FD0000AC16BD0609F459C0F50161915F01C4014B
+:10FD10008DD0FFEF8F1A9F0AF3CF83E0F80187BFE2
+:10FD2000E89507B600FCFDCFA0E0B1E0F8018D91A9
+:10FD30009D910C01F7BEE8951124229732962097E9
+:10FD4000B1F7F801E7BEE89507B600FCFDCFD7BED6
+:10FD5000E89533C0843719F53AD0C82FD0E0DC2FAE
+:10FD6000CC2735D05E01A82A32D0982E42D0E801A7
+:10FD7000F5E49F120BC0CE0151D022D081E0A81A29
+:10FD8000B1082196A114B104B1F717C0FE01859105
+:10FD9000EF0116D0E1E0AE1AB108C1F70EC0853709
+:10FDA00039F427D08EE10CD086E90AD08AE06DCFF5
+:10FDB000813511F488E017D01CD080E101D058CFF4
+:10FDC0009091C00095FFFCCF8093C600089580916C
+:10FDD000C00087FFFCCF8091C00084FD01C0A895C2
+:10FDE0008091C6000895E0E6F0E098E1908380837A
+:10FDF0000895EDDF803219F088E0F5DFFFCF84E170
+:10FE0000DFCFCF93C82FE3DFC150E9F7CF91F1CF18
+:10FE1000282E80E0E8DFE0E0FF270994F999FECF83
+:10FE200092BD81BDF89A992780B50895262FF9993A
+:10FE3000FECF1FBA92BD81BD20BD0FB6F894FA9ACD
+:08FE4000F99A0FBE0196089526
+:02FFFE000007FA
+:040000030000FC00FD
+:00000001FF
diff --git a/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega644p.lst b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega644p.lst
new file mode 100644
index 0000000..2ba4775
--- /dev/null
+++ b/ActualOptiboot/optiboot/bootloaders/optiboot/optiboot_atmega644p.lst
@@ -0,0 +1,683 @@
+
+optiboot_atmega644p.elf: file format elf32-avr
+
+Sections:
+Idx Name Size VMA LMA File off Algn
+ 0 .data 00000000 00800100 0000fe48 000002dc 2**0
+ CONTENTS, ALLOC, LOAD, DATA
+ 1 .text 00000248 0000fc00 0000fc00 00000094 2**1
+ CONTENTS, ALLOC, LOAD, READONLY, CODE
+ 2 .version 00000002 0000fffe 0000fffe 000002dc 2**0
+ CONTENTS, ALLOC, LOAD, READONLY, DATA
+ 3 .comment 0000002f 00000000 00000000 000002de 2**0
+ CONTENTS, READONLY
+ 4 .debug_aranges 00000028 00000000 00000000 0000030d 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 5 .debug_info 00000625 00000000 00000000 00000335 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 6 .debug_abbrev 00000286 00000000 00000000 0000095a 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 7 .debug_line 0000035f 00000000 00000000 00000be0 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 8 .debug_frame 0000008c 00000000 00000000 00000f40 2**2
+ CONTENTS, READONLY, DEBUGGING
+ 9 .debug_str 0000021d 00000000 00000000 00000fcc 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 10 .debug_loc 00000421 00000000 00000000 000011e9 2**0
+ CONTENTS, READONLY, DEBUGGING
+ 11 .debug_ranges 00000060 00000000 00000000 0000160a 2**0
+ CONTENTS, READONLY, DEBUGGING
+
+Disassembly of section .text:
+
+0000fc00 :
+ // SP points to RAMEND
+ // r1 contains zero
+ //
+ // If not, uncomment the following instructions:
+ // cli();
+ asm volatile ("clr __zero_reg__");
+ fc00: 11 24 eor r1, r1
+ *
+ * Code by MarkG55
+ * see discusion in https://github.com/Optiboot/optiboot/issues/97
+ */
+#if !defined(__AVR_ATmega16__)
+ ch = MCUSR;
+ fc02: 84 b7 in r24, 0x34 ; 52
+#else
+ ch = MCUCSR;
+#endif
+ // Skip all logic and run bootloader if MCUSR is cleared (application request)
+ if (ch != 0) {
+ fc04: 88 23 and r24, r24
+ fc06: 49 f0 breq .+18 ; 0xfc1a
+ * 2. we clear WDRF if it's set with EXTRF to avoid loops
+ * One problematic scenario: broken application code sets watchdog timer
+ * without clearing MCUSR before and triggers it quickly. But it's
+ * recoverable by power-on with pushed reset button.
+ */
+ if ((ch & (_BV(WDRF) | _BV(EXTRF))) != _BV(EXTRF)) {
+ fc08: 98 2f mov r25, r24
+ fc0a: 9a 70 andi r25, 0x0A ; 10
+ fc0c: 92 30 cpi r25, 0x02 ; 2
+ fc0e: 29 f0 breq .+10 ; 0xfc1a
+ if (ch & _BV(EXTRF)) {
+ fc10: 81 ff sbrs r24, 1
+ fc12: 02 c0 rjmp .+4 ; 0xfc18
+ * prevent entering bootloader.
+ * '&' operation is skipped to spare few bytes as bits in MCUSR
+ * can only be cleared.
+ */
+#if !defined(__AVR_ATmega16__)
+ MCUSR = ~(_BV(WDRF));
+ fc14: 97 ef ldi r25, 0xF7 ; 247
+ fc16: 94 bf out 0x34, r25 ; 52
+#else
+ MCUCSR = ~(_BV(WDRF));
+#endif
+ }
+ appStart(ch);
+ fc18: fb d0 rcall .+502 ; 0xfe10
+ }
+ }
+
+#if LED_START_FLASHES > 0
+ // Set up Timer 1 for timeout counter
+ TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
+ fc1a: 85 e0 ldi r24, 0x05 ; 5
+ fc1c: 80 93 81 00 sts 0x0081, r24 ; 0x800081 <__TEXT_REGION_LENGTH__+0x7e0081>
+ UCSRA = _BV(U2X); //Double speed mode USART
+ UCSRB = _BV(RXEN) | _BV(TXEN); // enable Rx & Tx
+ UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0); // config USART; 8N1
+ UBRRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+#else
+ UART_SRA = _BV(U2X0); //Double speed mode USART0
+ fc20: 82 e0 ldi r24, 0x02 ; 2
+ fc22: 80 93 c0 00 sts 0x00C0, r24 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ UART_SRB = _BV(RXEN0) | _BV(TXEN0);
+ fc26: 88 e1 ldi r24, 0x18 ; 24
+ fc28: 80 93 c1 00 sts 0x00C1, r24 ; 0x8000c1 <__TEXT_REGION_LENGTH__+0x7e00c1>
+ UART_SRC = _BV(UCSZ00) | _BV(UCSZ01);
+ fc2c: 86 e0 ldi r24, 0x06 ; 6
+ fc2e: 80 93 c2 00 sts 0x00C2, r24 ; 0x8000c2 <__TEXT_REGION_LENGTH__+0x7e00c2>
+ UART_SRL = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
+ fc32: 80 e1 ldi r24, 0x10 ; 16
+ fc34: 80 93 c4 00 sts 0x00C4, r24 ; 0x8000c4 <__TEXT_REGION_LENGTH__+0x7e00c4>
+#endif
+#endif
+
+ // Set up watchdog to trigger after 1s
+ watchdogConfig(WATCHDOG_1S);
+ fc38: 8e e0 ldi r24, 0x0E ; 14
+ fc3a: d5 d0 rcall .+426 ; 0xfde6
+
+#if (LED_START_FLASHES > 0) || defined(LED_DATA_FLASH) || defined(LED_START_ON)
+ /* Set LED pin as output */
+ LED_DDR |= _BV(LED);
+ fc3c: 20 9a sbi 0x04, 0 ; 4
+ fc3e: 86 e0 ldi r24, 0x06 ; 6
+}
+
+#if LED_START_FLASHES > 0
+void flash_led(uint8_t count) {
+ do {
+ TCNT1 = -(F_CPU/(1024*16));
+ fc40: 20 e3 ldi r18, 0x30 ; 48
+ fc42: 3c ef ldi r19, 0xFC ; 252
+ TIFR1 = _BV(TOV1);
+ fc44: 91 e0 ldi r25, 0x01 ; 1
+}
+
+#if LED_START_FLASHES > 0
+void flash_led(uint8_t count) {
+ do {
+ TCNT1 = -(F_CPU/(1024*16));
+ fc46: 30 93 85 00 sts 0x0085, r19 ; 0x800085 <__TEXT_REGION_LENGTH__+0x7e0085>
+ fc4a: 20 93 84 00 sts 0x0084, r18 ; 0x800084 <__TEXT_REGION_LENGTH__+0x7e0084>
+ TIFR1 = _BV(TOV1);
+ fc4e: 96 bb out 0x16, r25 ; 22
+ while(!(TIFR1 & _BV(TOV1)));
+ fc50: b0 9b sbis 0x16, 0 ; 22
+ fc52: fe cf rjmp .-4 ; 0xfc50
+#if defined(__AVR_ATmega8__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega16__)
+ LED_PORT ^= _BV(LED);
+#else
+ LED_PIN |= _BV(LED);
+ fc54: 18 9a sbi 0x03, 0 ; 3
+}
+#endif
+
+// Watchdog functions. These are only safe with interrupts turned off.
+void watchdogReset() {
+ __asm__ __volatile__ (
+ fc56: a8 95 wdr
+ * While in theory, the STK500 initial commands would be buffered
+ * by the UART hardware, avrdude sends several attempts in rather
+ * quick succession, some of which will be lost and cause us to
+ * get out of sync. So if we see any data; stop blinking.
+ */
+ if (UART_SRA & _BV(RXC0))
+ fc58: 40 91 c0 00 lds r20, 0x00C0 ; 0x8000c0 <__TEXT_REGION_LENGTH__+0x7e00c0>
+ fc5c: 47 fd sbrc r20, 7
+ fc5e: 02 c0 rjmp .+4 ; 0xfc64
+ fc60: 81 50 subi r24, 0x01 ; 1
+#else
+// This doesn't seem to work?
+// if ((UART_PIN & (1<
+
+ /*
+ * Copy data from the buffer into the flash write buffer.
+ */
+ do {
+ __boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+ fc64: ff 24 eor r15, r15
+ fc66: f3 94 inc r15
+ } while (len -= 2);
+
+ /*
+ * Actually Write the buffer to flash (and wait for it to finish.)
+ */
+ __boot_page_write_short(address.word);
+ fc68: 55 e0 ldi r21, 0x05 ; 5
+ fc6a: e5 2e mov r14, r21
+ boot_spm_busy_wait();
+#if defined(RWWSRE)
+ // Reenable read access to flash
+ __boot_rww_enable_short();
+ fc6c: 61 e1 ldi r22, 0x11 ; 17
+#endif
+
+ /* Forever loop: exits by causing WDT reset */
+ for (;;) {
+ /* get character from UART */
+ ch = getch();
+ fc6e: d6 2e mov r13, r22
+
+ if(ch == STK_GET_PARAMETER) {
+ fc70: ae d0 rcall .+348 ; 0xfdce
+ unsigned char which = getch();
+ fc72: 81 34 cpi r24, 0x41 ; 65
+ fc74: 61 f4 brne .+24 ; 0xfc8e
+ fc76: ab d0 rcall .+342 ; 0xfdce
+ verifySpace();
+ fc78: c8 2f mov r28, r24
+ fc7a: bb d0 rcall .+374 ; 0xfdf2
+ /*
+ * Send optiboot version as "SW version"
+ * Note that the references to memory are optimized away.
+ */
+ if (which == STK_SW_MINOR) {
+ fc7c: c2 38 cpi r28, 0x82 ; 130
+ fc7e: e9 f0 breq .+58 ; 0xfcba
+ putch(optiboot_version & 0xFF);
+ } else if (which == STK_SW_MAJOR) {
+ fc80: c1 38 cpi r28, 0x81 ; 129
+ putch(optiboot_version >> 8);
+ fc82: 11 f4 brne .+4 ; 0xfc88
+ fc84: 87 e0 ldi r24, 0x07 ; 7
+ } else {
+ /*
+ * GET PARAMETER returns a generic 0x03 reply for
+ * other parameters - enough to keep Avrdude happy
+ */
+ putch(0x03);
+ fc86: 01 c0 rjmp .+2 ; 0xfc8a
+ fc88: 83 e0 ldi r24, 0x03 ; 3
+ fc8a: 9a d0 rcall .+308 ; 0xfdc0
+ fc8c: 96 c0 rjmp .+300 ; 0xfdba
+ }
+ }
+ else if(ch == STK_SET_DEVICE) {
+ fc8e: 82 34 cpi r24, 0x42 ; 66
+ // SET DEVICE is ignored
+ getNch(20);
+ fc90: 11 f4 brne .+4 ; 0xfc96
+ fc92: 84 e1 ldi r24, 0x14 ; 20
+ }
+ else if(ch == STK_SET_DEVICE_EXT) {
+ fc94: 03 c0 rjmp .+6 ; 0xfc9c
+ // SET DEVICE EXT is ignored
+ getNch(5);
+ fc96: 85 34 cpi r24, 0x45 ; 69
+ fc98: 19 f4 brne .+6 ; 0xfca0
+ fc9a: 85 e0 ldi r24, 0x05 ; 5
+ }
+ else if(ch == STK_LOAD_ADDRESS) {
+ fc9c: b2 d0 rcall .+356 ; 0xfe02
+ fc9e: 8d c0 rjmp .+282 ; 0xfdba
+ // LOAD ADDRESS
+ address.bytes[0] = getch();
+ fca0: 85 35 cpi r24, 0x55 ; 85
+ fca2: 39 f4 brne .+14 ; 0xfcb2
+ fca4: 94 d0 rcall .+296 ; 0xfdce
+ address.bytes[1] = getch();
+ fca6: 08 2f mov r16, r24
+ fca8: 92 d0 rcall .+292 ; 0xfdce
+ }
+ else {
+ RAMPZ &= 0xFE;
+ }
+#endif
+ address.word *= 2; // Convert from word address to byte address
+ fcaa: 18 2f mov r17, r24
+ fcac: 00 0f add r16, r16
+ fcae: 11 1f adc r17, r17
+ verifySpace();
+ }
+ else if(ch == STK_UNIVERSAL) {
+ fcb0: 83 c0 rjmp .+262 ; 0xfdb8
+ getNch(3);
+ putch(0x00);
+ }
+#else
+ // UNIVERSAL command is ignored
+ getNch(4);
+ fcb2: 86 35 cpi r24, 0x56 ; 86
+ fcb4: 21 f4 brne .+8 ; 0xfcbe
+ fcb6: 84 e0 ldi r24, 0x04 ; 4
+ putch(0x00);
+ fcb8: a4 d0 rcall .+328 ; 0xfe02
+#endif
+ }
+ /* Write memory, length is big endian and is in bytes */
+ else if(ch == STK_PROG_PAGE) {
+ fcba: 80 e0 ldi r24, 0x00 ; 0
+ fcbc: e6 cf rjmp .-52 ; 0xfc8a
+ // PROGRAM PAGE - we support flash programming only, not EEPROM
+ uint8_t desttype;
+ uint8_t *bufPtr;
+ pagelen_t savelength;
+
+ GETLENGTH(length);
+ fcbe: 84 36 cpi r24, 0x64 ; 100
+ fcc0: 09 f0 breq .+2 ; 0xfcc4
+ fcc2: 48 c0 rjmp .+144 ; 0xfd54
+ fcc4: 84 d0 rcall .+264 ; 0xfdce
+ fcc6: c8 2f mov r28, r24
+ fcc8: d0 e0 ldi r29, 0x00 ; 0
+ fcca: dc 2f mov r29, r28
+ fccc: cc 27 eor r28, r28
+ savelength = length;
+ desttype = getch();
+ fcce: 7f d0 rcall .+254 ; 0xfdce
+ fcd0: c8 2b or r28, r24
+ // PROGRAM PAGE - we support flash programming only, not EEPROM
+ uint8_t desttype;
+ uint8_t *bufPtr;
+ pagelen_t savelength;
+
+ GETLENGTH(length);
+ fcd2: 7d d0 rcall .+250 ; 0xfdce
+ savelength = length;
+ desttype = getch();
+ fcd4: c8 2e mov r12, r24
+ fcd6: 5e 01 movw r10, r28
+ fcd8: 81 2c mov r8, r1
+
+ // read a page worth of contents
+ bufPtr = buff.bptr;
+ do *bufPtr++ = getch();
+ fcda: 99 24 eor r9, r9
+ fcdc: 93 94 inc r9
+ fcde: 77 d0 rcall .+238 ; 0xfdce
+ fce0: f4 01 movw r30, r8
+ fce2: 81 93 st Z+, r24
+ while (--length);
+ fce4: 4f 01 movw r8, r30
+ fce6: f1 e0 ldi r31, 0x01 ; 1
+ fce8: af 1a sub r10, r31
+ fcea: b1 08 sbc r11, r1
+
+ // Read command terminator, start reply
+ verifySpace();
+ fcec: c1 f7 brne .-16 ; 0xfcde
+ fcee: 81 d0 rcall .+258 ; 0xfdf2
+ * void writebuffer(memtype, buffer, address, length)
+ */
+static inline void writebuffer(int8_t memtype, addr16_t mybuff,
+ addr16_t address, pagelen_t len)
+{
+ switch (memtype) {
+ fcf0: 85 e4 ldi r24, 0x45 ; 69
+ fcf2: c8 12 cpse r12, r24
+ fcf4: 12 c0 rjmp .+36 ; 0xfd1a
+ fcf6: d3 95 inc r29
+ fcf8: 48 01 movw r8, r16
+ fcfa: a1 2c mov r10, r1
+ fcfc: bb 24 eor r11, r11
+ case 'E': // EEPROM
+#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
+ while(len--) {
+ fcfe: b3 94 inc r11
+ fd00: ac 16 cp r10, r28
+ fd02: bd 06 cpc r11, r29
+ fd04: 09 f4 brne .+2 ; 0xfd08
+ eeprom_write_byte((address.bptr++), *(mybuff.bptr++));
+ fd06: 59 c0 rjmp .+178 ; 0xfdba
+ fd08: f5 01 movw r30, r10
+ fd0a: 61 91 ld r22, Z+
+ fd0c: 5f 01 movw r10, r30
+ fd0e: c4 01 movw r24, r8
+ fd10: 8d d0 rcall .+282 ; 0xfe2c
+ fd12: ff ef ldi r31, 0xFF ; 255
+ fd14: 8f 1a sub r8, r31
+ fd16: 9f 0a sbc r9, r31
+ fd18: f3 cf rjmp .-26 ; 0xfd00
+ * Start the page erase and wait for it to finish. There
+ * used to be code to do this while receiving the data over
+ * the serial link, but the performance improvement was slight,
+ * and we needed the space back.
+ */
+ __boot_page_erase_short(address.word);
+ fd1a: 83 e0 ldi r24, 0x03 ; 3
+ fd1c: f8 01 movw r30, r16
+ fd1e: 87 bf out 0x37, r24 ; 55
+ fd20: e8 95 spm
+ boot_spm_busy_wait();
+ fd22: 07 b6 in r0, 0x37 ; 55
+ fd24: 00 fc sbrc r0, 0
+ fd26: fd cf rjmp .-6 ; 0xfd22
+ fd28: a0 e0 ldi r26, 0x00 ; 0
+ fd2a: b1 e0 ldi r27, 0x01 ; 1
+ fd2c: f8 01 movw r30, r16
+
+ /*
+ * Copy data from the buffer into the flash write buffer.
+ */
+ do {
+ __boot_page_fill_short((uint16_t)(void*)addrPtr, *(mybuff.wptr++));
+ fd2e: 8d 91 ld r24, X+
+ fd30: 9d 91 ld r25, X+
+ fd32: 0c 01 movw r0, r24
+ fd34: f7 be out 0x37, r15 ; 55
+ fd36: e8 95 spm
+ addrPtr += 2;
+ } while (len -= 2);
+ fd38: 11 24 eor r1, r1
+ fd3a: 22 97 sbiw r28, 0x02 ; 2
+ fd3c: 32 96 adiw r30, 0x02 ; 2
+ fd3e: 20 97 sbiw r28, 0x00 ; 0
+
+ /*
+ * Actually Write the buffer to flash (and wait for it to finish.)
+ */
+ __boot_page_write_short(address.word);
+ fd40: b1 f7 brne .-20 ; 0xfd2e
+ fd42: f8 01 movw r30, r16
+ boot_spm_busy_wait();
+ fd44: e7 be out 0x37, r14 ; 55
+ fd46: e8 95 spm
+#if defined(RWWSRE)
+ // Reenable read access to flash
+ __boot_rww_enable_short();
+ fd48: 07 b6 in r0, 0x37 ; 55
+ fd4a: 00 fc sbrc r0, 0
+ fd4c: fd cf rjmp .-6 ; 0xfd48
+ writebuffer(desttype, buff, address, savelength);
+
+
+ }
+ /* Read memory block mode, length is big endian. */
+ else if(ch == STK_READ_PAGE) {
+ fd4e: d7 be out 0x37, r13 ; 55
+ fd50: e8 95 spm
+ uint8_t desttype;
+ GETLENGTH(length);
+ fd52: 33 c0 rjmp .+102 ; 0xfdba
+ fd54: 84 37 cpi r24, 0x74 ; 116
+ fd56: 19 f5 brne .+70 ; 0xfd9e
+ fd58: 3a d0 rcall .+116 ; 0xfdce
+ fd5a: c8 2f mov r28, r24
+ fd5c: d0 e0 ldi r29, 0x00 ; 0
+ fd5e: dc 2f mov r29, r28
+ fd60: cc 27 eor r28, r28
+
+ desttype = getch();
+ fd62: 35 d0 rcall .+106 ; 0xfdce
+ fd64: 5e 01 movw r10, r28
+ fd66: a8 2a or r10, r24
+
+ verifySpace();
+ fd68: 32 d0 rcall .+100 ; 0xfdce
+ fd6a: 98 2e mov r9, r24
+
+static inline void read_mem(uint8_t memtype, addr16_t address, pagelen_t length)
+{
+ uint8_t ch;
+
+ switch (memtype) {
+ fd6c: 42 d0 rcall .+132 ; 0xfdf2
+ fd6e: e8 01 movw r28, r16
+ fd70: f5 e4 ldi r31, 0x45 ; 69
+
+#if defined(SUPPORT_EEPROM) || defined(BIGBOOT)
+ case 'E': // EEPROM
+ do {
+ putch(eeprom_read_byte((address.bptr++)));
+ fd72: 9f 12 cpse r9, r31
+ fd74: 0b c0 rjmp .+22 ; 0xfd8c
+ fd76: ce 01 movw r24, r28
+ fd78: 51 d0 rcall .+162 ; 0xfe1c
+ } while (--length);
+ fd7a: 22 d0 rcall .+68 ; 0xfdc0
+ fd7c: 81 e0 ldi r24, 0x01 ; 1
+ fd7e: a8 1a sub r10, r24
+ fd80: b1 08 sbc r11, r1
+ fd82: 21 96 adiw r28, 0x01 ; 1
+ fd84: a1 14 cp r10, r1
+ fd86: b1 04 cpc r11, r1
+ // while (--length);
+ // read a Flash and increment the address (may increment RAMPZ)
+ __asm__ ("elpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+#else
+ // read a Flash byte and increment the address
+ __asm__ ("lpm %0,Z+\n" : "=r" (ch), "=z" (address.bptr): "1" (address));
+ fd88: b1 f7 brne .-20 ; 0xfd76
+ fd8a: 17 c0 rjmp .+46 ; 0xfdba
+#endif
+ putch(ch);
+ fd8c: fe 01 movw r30, r28
+ fd8e: 85 91 lpm r24, Z+
+ } while (--length);
+ fd90: ef 01 movw r28, r30
+ fd92: 16 d0 rcall .+44 ; 0xfdc0
+ fd94: e1 e0 ldi r30, 0x01 ; 1
+ fd96: ae 1a sub r10, r30
+ fd98: b1 08 sbc r11, r1
+
+ read_mem(desttype, address, length);
+ }
+
+ /* Get device signature bytes */
+ else if(ch == STK_READ_SIGN) {
+ fd9a: c1 f7 brne .-16 ; 0xfd8c
+ fd9c: 0e c0 rjmp .+28 ; 0xfdba
+ // READ SIGN - return what Avrdude wants to hear
+ verifySpace();
+ fd9e: 85 37 cpi r24, 0x75 ; 117
+ fda0: 39 f4 brne .+14 ; 0xfdb0