I have created two separate programs for my AT89C51ED2: bootloader (0x0000) and normal program (0x2000). I use an absolute memory addressed variable to distinguish between the two modes of operation so that interrupts either execute code in the bootloader or call the appropriate ISRs in the program code (above 0x2000). The following is an example of the code used for interrupts in program code, in order to eliminate the usual pushes, pops and reti done by the bootloader ISR.
/** Timer 1 ISR. */ void interruptTimer1(void) interrupt 3 { #pragma asm lcall interruptTimer1Mirror ret #pragma endasm } /** Timer 1 interrupt working function. This routine is used for delays. */ void interruptTimer1Mirror() { timer1Interrupted = TRUE; }