bootloader: Fix wrong substitution for Cmnd_STK_SET_DEVICE_EXT

This was originally 'E', that is 0x45, not 0x44.
bootloader: use standard SPM_PAGESIZE macro

SPM_PAGESIZE is defined correctly in <avr/io.h> for all relevant MCUs.
However, it is the page size in bytes, not in words, so it must be
divided by 2.

This commit has no effect on the generated code.
bootloader: use standard SIGNATURE_x macros

These macros are correctly defined by including <avr/io.h>, so there
is no need to repeat them in our code.
bootloader: fix constraints for ldi

The LDI instruction requires a register from r16 to r31, so the
"r" constraint is too relaxed.
bootloader: move SPM programming into its own function

This helps gcc understand better the scope of temporary variables,
improving register allocation. In particular, one 16-bit register
reload could be saved, amounting to 6 bytes of instructions.

The main function body is also a lot more readable after moving the
big asm block away.
bootloader: cleanup putstr macros and helper routines

Unify the main routines and hide the differences in only 3 places:

1. the pgmptr_t type
2. putstr() macro definition
3. read_str_inc() helper
bootloader: make a general macro to read PROGMEM

Make it possible to use the general PROGMEM read trick for other
purposes than sending out a string variable.
bootloader: one function name to read from pgmptr_t

The PROGMEM abstraction is good, but code that reads from PROGMEM
is ugly, because it must still care about the size of pgmptr_t.

Thankfully, it is easy enough to factor this out into a macro.
bootloader: use &sym instead of sym for use_pgmvar (non-RAMPZ)

The RAMPZ definition of this macro requires a symbol, not a pointer
(a pointer is only 16 bits, a symbol has all 32 bits in asm), so
the non-RAMPZ definition must do the same.

This hasn't been an issue, because an array identifier in C can be
interpreted as both, but it may cause trouble if you try to use
something else.
bootloader: re-use signature bytes for both commands that need it

Do not include the signature bytes twice.

The code doesn't check array bounds. This is on purpose to save
a few instructions. It works correctly for all three documented
indexes. If you get an invalid index, you will get some garbage.
bootloader: use X register to read program buffer

The X register is cheaper for the gcc register allocator than the
Y register for certain reasons. When using the Y register, some
configurations (e.g. RAMPZ without LPMX) result in the following
gcc error:

error: can't find a register in class ‘POINTER_Y_REGS’ while reloading ‘asm’

This does not happen with the X register.
bootloader: prevent a gcc warning

I get the following warnings:

ATmegaBOOT_168.c:1013: warning: ‘gethex’ defined but not used
ATmegaBOOT_168.c:1018: warning: ‘puthex’ defined but not used

I know they are benign, but they might hide other (more important)
compiler warnings.
bootloader: allow to omit initialization of .data and/or .bss

The current bootloader does not define any initialized data, so the
corresponding loop does nothing. However, simply deleting it from the
file would be too fragile, because if somebody adds any initialized
data, the resulting code would be silently wrong.

Instead, make the initialization of .data optional, and check at link
time that either the .data section is empty, or the appropriate code
was compiled in.

Similarly for the .bss section (but since the .bss section is used by
error_count, the BSS initialization code must be included).
bootloader: unify inline asm style

This commit is purely cosmetic:
- With uniform line ends, any difference is more visible.
- Moving all asm labels left makes them easier to find.
bootloader: store error_count in GPIOR0

Since this variable was the only content of BSS, it is possible to
omit the code that initializes BSS.
bootloader: implement reading lock bits and fuse bits

The universal SPI programming command can be used to read the value
of lock bits and fuse bits. This is handy if you want to distinguish
between the full Hexbright bootloader and the Hexbright Tiny:

* Hexbright has EFUSE=00.
* Hexbright Tiny has EFUSE=02.

I had to move the definitions for prog_buffer higher up in the file,
so that they could be reused for reading the fuse bits.
bootloader: update address in prog_buffer

Address auto-increment is broken since moving the code in a separate
function, because changes to address are now local to this function.

Note that since the function gets inlined anyway, the pointer type
does not change the storage, but gcc emits an instruction to move
the target address from register Z to whichever register it uses
for address.
bootloader: fix address increment

The auto-increment is still broken. The address is now correctly
updated when reading or writing, but it is then multiplied by two
on the next read/write.

Since both programmable memory types are word-addressable, let's
convert the address when it is set, so I can get rid of the left
shift later before the actual read or write.
bootloader: use a 32-bit address on devices with >64k flash

If the device needs a RAMPZ register, use a 32-bit variable for the
addresss instead of storing the high byte in a separate variable.
The code is much cleaner this way.
bootloader: initialize data and BSS by default

Omitting the initialization code is an (extreme) case of optimization
for size. As such, it should only be enabled if really needed, so
turn it off by default and let the target override if desired.