// // Low-level bootloader routines to replace "assembly.s90" // from the original ATMEL Butterfly bootloader code // which are not included in avr-libc's boot.h by the // time of writing this. // // 3/2004 Martin Thomas, Kaiserslautern, Germany // #include "lowlevel.h" unsigned int read_program_memory(unsigned int adr, unsigned char param) // to read lockbits give param=0x09, if param!=0 it is written to SPMCSR // this is a "translation" from the original code to gcc-inline-assembler { unsigned int retval; asm volatile ( "movw r30, %3\n\t" "sbrc %2,0x00\n\t" "sts %0, %2\n\t" #ifdef LARGE_MEMORY // If large memory (>64K) ELPM is needed to use RAMPZ "elpm\n\t" // read LSB #else "lpm\n\t" // R0 is now the LSB of the return value #endif "mov %A1,r0\n\t" "inc r30\n\t" #ifdef LARGE_MEMORY // If large memory (>64K) ELPM is needed to use RAMPZ "elpm\n\t" // read MSB #else "lpm\n\t" // R0 is now the MSB of the return value #endif "mov %B1,r0\n\t" : "=m" (SPM_REG), "=r" (retval) : "r" ((unsigned char)param), "r" ((unsigned short)adr) : "r30", "r31", "r0" ); return retval; }