Alguna vez tuve un contacto con Python y me fascinó, pero nunca le he podido dedicar el tiempo suficiente como para entenderlo hasta el punto de sacarle todo el partido.
Me pasa algo raro con un HEX para 24F.
Tanto en el "Program Memory" del MPLAB

como en el winpic800 del maestro Sisco

veo que la primera dirección ocupada es la 0x400, lo cual coincide con lo que he expresado en el código fuente.
#define LOADER_SIZE 0x07FF
#define LOADER_END 0xC00
#define LOADER_ADDR (LOADER_END - LOADER_SIZE)
Sin embargo, en tu macro, la primera posición ocupada es la 0x800.
Creo que alguna vez me ha pasado algo así con los HEX de los 24F, y es que las direcciones de memoria son doble de grandes (por aquello de los 16 bits).
Dejo el HEX adjunto por si quieres bichearlo.