I was looking at the code in optiboot, and found the following lines, which seem to me to be in error, although in practice they work correctly. I don't know if this had been noted and possibly revised since IDE v.1.05.
register uint8_t length;
.......
/* Write memory, length is big endian and is in bytes */
else if(ch == STK_PROG_PAGE) {
// PROGRAM PAGE - we support flash programming only, not EEPROM
uint8_t *bufPtr;
uint16_t addrPtr;
getch(); /* getlen() */
length = getch();
getch();
// If we are in RWW section, immediately start page erase
if (address < NRWWSTART) __boot_page_erase_short((uint16_t)(void*)address);
// While that is going on, read in page contents
bufPtr = buff;
do *bufPtr++ = getch();
while (--length);
Basically, what happens is the data that comes from avrdude right after the STK_PROG_PAGE char [ie, 0x64, 'd'] are first the high-byte and then the low-byte of the length of the page-write block. As is obvious here, the high-byte is ignored.
Also, looking back at the original ATmegaBOOT_168.c bootloader, the same lines read as follows, showing that both length bytes used to be intercepted.
/* Write memory, length is big endian and is in bytes */
else if(ch=='d') {
length.byte[1] = getch();
length.byte[0] = getch();
flags.eeprom = 0;
if (getch() == 'E') flags.eeprom = 1;
for (w=0;w<length.word;w++) {
buff[w] = getch(); // Store data in buffer, can't keep up with serial data stream whilst programming pages
}
In short, as written optiboot will work ok for page lengths <= 256, since a zero actually causes the do...while loop to execute 256 times, given the way it is written. In reality, for chips like the 1284 and 2560, avrdude sends 0x01,0x00 as the page length value, and optiboot ignores the 0x01, and uses just the 0x00, which works in the do...while loop the same as a length=256 would have worked.
I guess it's ok, as long as the page-write lengths never exceed 256 bytes, but .... ummmm.