Не у верен, что не сохраняет Вот такие сорцы находятся
;----------------------------------------------------------------------------
;
; Library routines for the ATMEL AT90S processors
; setjmp/longjmp
;
; Copyright 1996-1998 IAR Systems. All rights reserved.
;
; $Revision: 1.12 $
;
;----------------------------------------------------------------------------
#include "macros.m90"
PUBLISH MACRO
PUBLIC ?\1_0
PUBLIC ?\1_1
PUBLIC ?\1_2
PUBLIC ?\1_3
PUBLIC ?\1_4
PUBLIC ?\1_5
PUBLIC ?\1_6
PUBLIC ?\1_7
PUBLIC ?\1_8
PUBLIC ?\1_9
PUBLIC ?\1_10
PUBLIC ?\1_11
PUBLIC ?\1_12
ENDM
ENTRY MACRO
\1 0,1,R15
\1 1,2,R14
\1 2,3,R13
\1 3,4,R12
\1 4,5,R11
\1 5,6,R10
\1 6,7,R9
\1 7,8,R8
\1 8,9,R7
\1 9,10,R6
\1 10,11,R5
\1 11,12,R4
\1 12
ENDM
REGS MACRO
\1 R15
\1 R14
\1 R13
\1 R12
\1 R11
\1 R10
\1 R9
\1 R8
\1 R7
\1 R6
\1 R5
\1 R4
ENDM
SAVE MACRO
RSEG CODE:CODE:NOROOT
PUBLIC ?setjmp_save_\1
?setjmp_save_\1:
ST Z+,\1
ENDM
RESTORE MACRO
RSEG CODE:CODE:NOROOT
PUBLIC ?longjmp_restore_\1
?longjmp_restore_\1:
LD \1,Z+
ENDM
ENTRY1 MACRO
RSEG CODE:CODE:NOROOT
?setjmp_\1:
IF _args > 1
REQUIRE ?setjmp_\2
IF _args > 2
REQUIRE ?setjmp_save_\3
ENDIF
ENDIF
ENDM
ENTRY2 MACRO
RSEG CODE:CODE:NOROOT
?longjmp_\1:
IF _args > 1
REQUIRE ?longjmp_\2
IF _args > 2
REQUIRE ?longjmp_restore_\3
ENDIF
ENDIF
ENDM
#define SPL 0x3D
#define SPH 0x3E
#ifdef __XMEGA_CORE__
#define CCP 0x34
#endif /* __XMEGA_CORE__ */
;-------------------------------------------------------------------------
;
; Function: setjmp
;
; Created: 18/Jun/96 IANP
;
; Inputs: P2:P1:P0 - jmp_buf
;
; Returns: P2:P1:P0 - == 0 when the buffer is set up,
; != 0 when returning from a longjmp
;
; Size:
;
; Destroys: T0 T1 T2 T3 Z (and all other scratch registers
; if returning from a longjmp).
;
; Description:
; Store the stack and register environment in the buffer pointed to
; by P2:P1:P0. PC, SP, Y, and all non-scratch registers are stored.
;
;-------------------------------------------------------------------------
MODULE setjmp
PUBLISH setjmp
ENTRY ENTRY1
MOV Z0,P0
#if (A90_POINTER_REG_SIZE > 1)
#if (MEMORY_MODEL == SMALL_MEMORY_MODEL) || (MEMORY_MODEL == LARGE_MEMORY_MODEL)
MOV Z1,P1
#else
LDI Z1,0 ; Running -v[3,5] -mt
#endif
#if (A90_POINTER_REG_SIZE == 3)
#if (MEMORY_MODEL == SMALL_MEMORY_MODEL)
CLR T0
OUT RAMPZ,T0
#else
OUT RAMPZ,P2
#endif
#endif
#endif
REQUIRE ?SAVE_R24
REGS SAVE
RSEG CODE:CODE:NOROOT
?SAVE_R24:
ST Z+,R24 ; save R24
ST Z+,R25 ; save R25
ST Z+,R26 ; save R26
ST Z+,R27 ; save R27
ST Z+,Y0 ; save Y0
ST Z+,Y1 ; save Y1
;; read PC by popping the return address stack
#ifdef A90_LARGE_CODE
POP T2
#endif
POP T1
POP T0
ST Z+,T0 ; save PC low
ST Z+,T1 ; save PC high
#ifdef A90_LARGE_CODE
ST Z+,T2 ; save PC highest
#endif
;; read SP from SFR SP
IN T3,SPL
ST Z+,T3 ; save SP low
#if A90_POINTER_REG_SIZE > 1
IN T3,SPH
ST Z+,T3 ; save SP high
#endif
LDI P0,0 ; return value 0
LDI P1,0
#ifdef __HAS_ENHANCED_CORE__
MOVW Z1:Z0,T1:T0
#else
MOV Z0,T0
MOV Z1,T1
#endif
#ifdef A90_LARGE_CODE
OUT EIND,T2
EIJMP ; return
#else
IJMP
#endif
ENDMOD
;-------------------------------------------------------------------------
;
; Function: longjmp
;
; Created: 18/Jun/96 IANP
;
; Inputs: P2:P1:P0 - jmp_buf
; Q1:Q0 - value to give as "return" from setjmp
;
; Returns: (not applicable)
;
; Size:
;
; Destroys: All scratch registers.
;
; Description:
; Restore the stack and register environment from the buffer pointed to
; by P2:P1:P0. PC, SP, Y, and all non-scratch registers are stored.
;
;-------------------------------------------------------------------------
MODULE longjmp
PUBLISH longjmp
#if (A90_POINTER_REG_SIZE == 3) && (MEMORY_MODEL == LARGE_MEMORY_MODEL)
#define V0 Q0
#define V1 Q1
#else
#define V0 R18
#define V1 R19
#endif
ENTRY ENTRY2
MOV Z0,P0
#if A90_POINTER_REG_SIZE > 1
#if (MEMORY_MODEL == SMALL_MEMORY_MODEL) || (MEMORY_MODEL == LARGE_MEMORY_MODEL)
MOV Z1,P1
#else
CLR Z1 ; Running -v[3,5] -mt
#endif
#if (A90_POINTER_REG_SIZE == 3)
CLR T0
#if (MEMORY_MODEL == SMALL_MEMORY_MODEL)
OUT RAMPZ,T0
#else
OUT RAMPZ,P2
#endif
OUT RAMPD,T0 ; Keep RAMPD zero
#endif
#endif
MOV P0,V0
MOV P1,V1 ; return value
OR V0,V1
BRNE ?SKIP
LDI P0,1 ; zero return --> make it non-zero
?SKIP: REQUIRE ?RESTORE_R24
REGS RESTORE
RSEG CODE:CODE:NOROOT
?RESTORE_R24:
LD R24,Z+ ; restore R24
LD R25,Z+ ; restore R25
LD R26,Z+ ; restore R26
LD R27,Z+ ; restore R27
#ifdef __XMEGA_CORE__
LD Q0,Z+ ; restore Y0
LD Q1,Z+ ; restore Y1
MOVW Y1:Y0,Q1:Q0
#else /* Classic */
;; Disable interrupts while restoring SP and Y
IN Q0,SREG
CLI ; disable interrupt
LD Y0,Z+ ; restore Y0
LD Y1,Z+ ; restore Y1
#endif /* !Classic */
;; saved PC
LD T0,Z+ ; restore PC low
LD T1,Z+ ; restore PC high
#ifdef A90_LARGE_CODE
LD T2,Z+ ; restore PC highest
#endif
#ifdef __XMEGA_CORE__
LDI Q0,0x9D
LD Q1,Z+ ; restore SP low
LD Q2,Z+ ; restore SP high
OUT CCP,Q0
;; store saved SP in SFR SP, while interrupts are disabled
OUT SPL,Q1
OUT SPH,Q2
#else /* Classic */
;; store saved SP in SFR SP, while interrupts are disabled
LD T3,Z+ ; restore SP low
OUT SPL,T3
#if A90_POINTER_REG_SIZE > 1
LD T3,Z+ ; restore SP high
OUT SPH,T3
#endif
;; Restore interrupt flag
OUT SREG,Q0
#endif /* !Classic */
#ifdef __HAS_ENHANCED_CORE__
MOVW Z1:Z0,T1:T0
#else
MOV Z0,T0
MOV Z1,T1
#endif
#ifdef A90_LARGE_CODE
OUT EIND,T2
EIJMP ; return
#else
IJMP
#endif
END
;----------------------------------------------------------------------------
; $Log: l05.s90 $
; Revision 1.12 2007/09/17 13:44:18Z IPEO
; Revision 1.11 2003/12/09 11:34:30Z IPEO
; Revision 1.10 2003/10/24 11:45:21Z IPEO
; Revision 1.9 2003/10/10 14:06:42Z IPEO
; S031011110A
; Revision 1.8 2003/10/01 12:19:54Z IPEO
; Revision 1.7 2003/09/03 13:05:10Z IPEO
; Revision 1.6 2003/08/22 14:09:14Z IPEO
; Revision 1.5 2003/08/22 08:54:13Z IPEO
; Revision 1.4 2003/08/20 08:39:01Z IPEO
; Revision 1.3 2003/08/05 15:35:25Z IPEO
; Revision 1.2 2002/11/27 16:45:48Z IPEO
; Revision 1.4 2000/12/07 14:48:17 daniel
; Revision 1.3 2000/10/19 09:17:46 daniel
; Revision 1.2 2000/05/31 14:55:23 daniel
; Revision 1.1 1999/10/18 09:06:31 daniel
; Initial revision
;---------------------------------------------------------------------------- ; ; MACROS.M90 ; ; This module contains the A90/AVR C macros ; used by cstartup.s90 and other assemble source. ; ; File version: $Revision: 1.8 $ ; ; ;---------------------------------------------------------------------------- #if (((__TID__ >> 8) & 0x7F) != 90) #error This file should only be assembled by aa90 or aavr #endif #define A90_PROC_OPTION ((__TID__ >> 4) & 0x0F) /* Long or relative jumps and calls */ #if (A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 1) #define XCALL RCALL #define XJMP RJMP #else #define XCALL CALL #define XJMP JMP #endif /* Length of pointer registers (X/Y/Z) */ #if (A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2) #define A90_POINTER_REG_SIZE 1 #define A90_TINY_INDEX #else /*!(A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2)*/ #if (A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5) #define A90_POINTER_REG_SIZE 2 #else /*!(A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5)*/ #if (A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6) #define A90_POINTER_REG_SIZE 3 #define A90_EXTENDED_DATA #else /*!(A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6)*/ #error Unknown processor option!! #endif /*!(A90_PROC_OPTION == 4) || (A90_PROC_OPTION == 6)*/ #endif /*!(A90_PROC_OPTION == 1) || (A90_PROC_OPTION == 3) || (A90_PROC_OPTION ==5)*/ #endif /*!(A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 2)*/ #if (A90_PROC_OPTION > 4) #define A90_LARGE_CODE #endif #if (A90_PROC_OPTION > 1) #define A90_HAS_POSSIBLE_ELPM #endif #ifdef A90_HAS_POSSIBLE_ELPM #ifdef __HAS_ELPM__ #define A90_HAS_ELPM #else #ifndef SMALL_FLASH #define A90_HAS_ELPM #endif #endif #endif #if A90_PROC_OPTION > 1 #define A90_24BIT_GENERIC #endif #if A90_PROC_OPTION < 2 #define A90_16BIT_GENERIC #endif #ifdef __MEMORY_MODEL__ #define TINY_MEMORY_MODEL 0 #define SMALL_MEMORY_MODEL 1 #define LARGE_MEMORY_MODEL 2 #define GENERIC_MEMORY_MODEL 3 #define HUGE_MEMORY_MODEL 4 #if __MEMORY_MODEL__ == 1 #undef MEMORY_MODEL #define MEMORY_MODEL TINY_MEMORY_MODEL #endif #if __MEMORY_MODEL__ == 2 #undef MEMORY_MODEL #define MEMORY_MODEL SMALL_MEMORY_MODEL #endif #if __MEMORY_MODEL__ == 3 #undef MEMORY_MODEL #define MEMORY_MODEL LARGE_MEMORY_MODEL #endif #if __MEMORY_MODEL__ == 4 #undef MEMORY_MODEL #define MEMORY_MODEL GENERIC_MEMORY_MODEL #endif #if __MEMORY_MODEL__ == 5 #undef MEMORY_MODEL #define MEMORY_MODEL HUGE_MEMORY_MODEL #endif #else #ifdef MEMORY_MODEL #define t 0 #define s 1 #define l 2 #define g 3 #define h 4 #define TINY_MEMORY_MODEL 0 #define SMALL_MEMORY_MODEL 1 #define LARGE_MEMORY_MODEL 2 #define GENERIC_MEMORY_MODEL 3 #define HUGE_MEMORY_MODEL 4 #if MEMORY_MODEL == t #undef MEMORY_MODEL #define MEMORY_MODEL TINY_MEMORY_MODEL #endif #if MEMORY_MODEL == s #undef MEMORY_MODEL #define MEMORY_MODEL SMALL_MEMORY_MODEL #endif #if MEMORY_MODEL == l #undef MEMORY_MODEL #define MEMORY_MODEL LARGE_MEMORY_MODEL #endif #if MEMORY_MODEL == g #undef MEMORY_MODEL #define MEMORY_MODEL GENERIC_MEMORY_MODEL #endif #if MEMORY_MODEL == h #undef MEMORY_MODEL #define MEMORY_MODEL HUGE_MEMORY_MODEL #endif #undef t #undef s #undef l #undef g #undef h #endif #endif /* Register nicknames */ #define T0 R0 #define T1 R1 #define T2 R2 #define T3 R3 #define P0 R16 #define P1 R17 #define P2 R18 #define P3 R19 #define Q0 R20 #define Q1 R21 #define Q2 R22 #define Q3 R23 #define X0 R26 #define X1 R27 #define X2 R25 #define Y0 R28 #define Y1 R29 #define Z0 R30 #define Z1 R31 #define Z2 R19 /* I/O-Space Register nicknames */ #define RAMPD 0x38 #define RAMPX 0x39 #define RAMPY 0x3A #define RAMPZ 0x3B #define EIND 0x3C #define SREG 0x3F