up_n_down: improve EEPROM access pattern

The original program writes to fixed EEPROM locations, stressing the
first two cells only. Let's do it differently:

1. All configuration is kept in a single data structure.
2. The EEPROM memory space is divided into slots.
3. Each slot has a sequence number.
4. A new slot is always used to write the configuration, and it gets
   the next highest available sequence number.
5. Number of slots is not a multiple of the highest sequence number.
6. Both sequence numbers and slot numbers can overflow eventually, but
   thanks to point 5, there will always be a "gap" after the last
   sequence number.

The configuration is read once at startup, and written once before
switching off, and only if any values actually changed.

I employed a few other clever tricks:

The sequence number 255 is never used, so there are only 255 sequence
numbers, which greatly helps satisfy point 5 above. But by choosing 255,
which is the default content of an EEPROM cell after erase, it can also
be used to detect uninitialised cells.

Finding the gap on startup is implemented as a binary search, rather than
a sequential search. With 512 bytes and a 4-byte slot, 9 steps are needed
to find the gap (as opposed to an average of 256 for a sequential search).

The binary search algorithm was designed to minimise EEPROM accesses.
That's why there are separate variables for sequence numbers.

The modulo 255 operation is a mock implementation optimised for speed. It
only works correctly in a limited range, and in fact also produces
positive remainders for negative numbers, but all these quirks are
desired for the purposes of determining whether there is a gap in the
sequence numbers.
bootloader: use noreturn attribute where appropriate

The application and the main() function never return, so the compiler
can omit some code that would be necessary if they did.
bootloader: compile with -mshort-calls

This option uses relative calls/jumps (rcall and rjmp instructions),
which are shorter. These instructions can address only +/- 2k (words),
but the bootloader should be shorter than that...

For the hexbright, this option saves 112 bytes of code.
bootloader: use a custom linker script

This commit only adds the appropriate gcc options. The linker script
itself is identical to the standard gcc script, so there is no change.
bootloader: remove interrupt vector table

IVSEL bit in MCUCR is zero on boot (so interrupt vectors are placed at
the start of the Flash memory), and lock bits specify BLB1 mode 3, so
interrupts are disabled while executing from the Boot Loader section.

Consequently, the interrupt vector table is not used, and its place
can be taken by the initialisation code.

The .text section from crtm168.o must be discarded, because it references
__vector_default, which is in the now-discarded .vectors section.
bootloader: put main() after the init sections

Instead of calling main(), put it directly after the init sections.
This saves 2 instructions (4 bytes), so not a big win, but every
instruction counts towards the goal (minimal bootloader of 1024 bytes).
bootloader: discard .fini* sections

The bootloader never exits, so this code is never executed.
Saves another 4 bytes.
bootloader: put PROGMEM data at the end of the text section

For the bootloader, this data cannot be in the low area anyway, so
just let's put it at the end, so it doesn't sit in the middle of code.

This commit doesn't help anything, it's purely a cleanup.
bootloader: remove cli()

Interrupts are disabled for the whole execution of the bootloader.
bootloader: do not bother setting DDR_LED if unused

If the LED is not used, then don't do anything.
Saves 2 bytes.
bootloader: address_high can be optimised out if not static

High byte of the address is only needed on MCUs which have RAMPZ. If
there is no RAMPZ, gcc will elide the code as dead store.
bootloader: remove unneeded ch2

Only one variable is needed to hold the last byte of input.

This change has no effect on the generated code.
bootloader: use named operands for spm inline asm

The main programmer asm statement is very long, so it is hard to follow
the positional operands.

This change doesn't affect the generated code.
bootloader: let gcc allocate registers for the asm statement

Instead of using hard-coded registers, let gcc choose which registers
should be used.

This change does not make a big difference, but it's easier to maintain
and also gives more freedom to the gcc register allocator.
bootloader: factor out SPMCR/SPMCSR into a pre-processor define

The only reason for the ugly conditional in the asm is the different
naming of the SPM control register on newer models. But this can be
done in a more readable way through a macro define.
bootloader: use in/out for SPMCSR if possible

Except on ATmega128, the SPM Control Register is in the range addressable
with the shorter I/O instructions.

This change saves 20 bytes.
bootloader: use sbrc to test SPMEN

One instruction per wait-loop can be saved this way.
bootloader: tell gcc that we want address in the Y and Z registers

This way, gcc can use r28-r31 for the calculations. No need to store
the value in memory and then load the same value from the asm() block.
bootloader: fix asm constraints for scratch counters

Input operands should not be modified by the asm block. If the previous
worked, then it was pure luck. Let's do this properly by declaring the
scratch counters in C.

This commit doesn't change the generated code except allocating other
registers for the counters, because gcc can see that the resulting
counter values are not used for anything.
bootloader: cleanup union types

The definition of address_union and length_union is the same. Let's
provide it only once and use typedef to provide a semantic type
(with possible distinction in the future).