Imported Upstream version 2.9.0
[debian/cc1111] / device / lib / pic16 / debug / gstack / gstack.c
1 /*-------------------------------------------------------------------------
2
3    gstack.c :- debug stack tracing support function
4
5    Written for pic16 port by Vangelis Rokas, 2004 (vrokas@otenet.gr)
6
7    This library is free software; you can redistribute it and/or modify it
8    under the terms of the GNU Library General Public License as published by the
9    Free Software Foundation; either version 2, or (at your option) any
10    later version.
11
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU Library General Public License for more details.
16
17    You should have received a copy of the GNU Library General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
21    In other words, you are welcome to use, share and improve this program.
22    You are forbidden to forbid anyone else to use, share and improve
23    what you give them.   Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
25 /*
26 ** $Id: gstack.c 3835 2005-08-07 20:09:11Z tecodev $
27 */
28
29 extern WREG;
30 extern FSR1L;
31 extern FSR1H;
32 extern FSR0L;
33 extern FSR0H;
34 extern STATUS;
35 extern POSTINC0;
36 extern POSTDEC1;
37 extern PREINC1;
38 extern TOSL;
39 extern TOSH;
40 extern TOSU;
41 extern PCL;
42 extern PCLATH;
43 extern PCLATU;
44 extern stack;
45 extern stack_end;
46
47 #pragma udata access _wreg_store _status_store _fsr0_store
48 #pragma udata access _gstack_begin _gstack_end _init_ok
49
50 static char _init_ok=0;
51 static char _wreg_store;
52 static char _status_store;
53 static unsigned int _fsr0_store;
54 static unsigned int _gstack_begin;
55 static unsigned int _gstack_end;
56
57 char _gstack_fail_str[]="Stack overflow\n";
58 char _gstack_succ_str[]="Stack ok\n";
59
60
61 static
62 void _gstack_overflow_default(void) __naked
63 {
64   __asm
65     lfsr        0, __gstack_fail_str
66 ;    incf       _FSR0L, f
67
68 @0:
69     movf        _POSTINC0, w
70     movff       _WREG, 0xf7f
71     bnz         @0
72     
73 ;    sleep
74 @00:
75     goto        @00
76     
77   __endasm ;
78 }
79
80 void (* _gstack_overflow)(void)=_gstack_overflow_default;
81
82     
83 void _gstack_init(void) __naked
84 {
85   __asm
86     
87     movlw       LOW(_stack)
88     movwf       __gstack_begin
89     
90     movlw       HIGH(_stack)
91     movwf       __gstack_begin+1
92
93     movlw       LOW(_stack_end)
94     movwf       __gstack_end
95     
96     movlw       HIGH(_stack_end)
97     movwf       __gstack_end+1
98
99     ; load default handler
100 ;    movlw      LOW(__gstack_overflow_default)
101 ;    movwf      __gstack_overflow
102     
103 ;    movlw      HIGH(__gstack_overflow_default)
104 ;    movwf      __gstack_overflow+1
105     
106 ;    movlw      UPPER(__gstack_overflow_default)
107 ;    movwf      __gstack_overflow+2
108     
109
110     movlw       1
111     movwf       __init_ok
112     
113     return;    
114   __endasm ;
115 }
116
117
118 void _gstack_test(void) __naked
119 {
120   __asm
121     movff       _WREG, __wreg_store
122     movff       _STATUS, __status_store
123
124     ; if first time, initialize boundary variables
125     movf        __init_ok, w
126     bnz         @1
127     call        __gstack_init
128     
129 @1:
130     movf        __gstack_begin, w
131     cpfslt      _FSR1L
132     bra         @2
133     bra         @3
134
135 @2:
136     movf        __gstack_begin+1, w
137     cpfslt      _FSR1H
138     bra         @4
139     bra         @3
140
141 @4:
142     movf        __gstack_end, w
143     cpfsgt      _FSR1L
144     bra         @5
145     bra         @3
146
147 @5:
148     movf        __gstack_end+1, w
149     cpfsgt      _FSR1H
150     bra         @6
151
152     ; fail
153
154 @3:
155
156     push
157     movlw       LOW(ret_lab)
158     movwf       _TOSL
159
160     movlw       HIGH(ret_lab)
161     movwf       _TOSH
162
163     movlw       UPPER(ret_lab)
164     movwf       _TOSU
165
166     movff       __gstack_overflow+2, _PCLATU
167     movff       __gstack_overflow+1, _PCLATH
168     movf        __gstack_overflow, w
169     
170     ; execute 
171     movwf       _PCL
172     
173 ret_lab:
174     bra         @10
175
176     ; success
177 @6:
178     movff       _FSR0L, __fsr0_store
179     movff       _FSR0H, __fsr0_store+1
180     lfsr        0, __gstack_succ_str
181
182     ; print corresponding string
183 @8:
184     movf        _POSTINC0, w
185     movff       _WREG, 0xf7f
186     bnz         @8
187
188 @9:
189     movff       __fsr0_store+1, _FSR0H
190     movff       __fsr0_store, _FSR0L
191
192 @10:
193     movff       __status_store, _STATUS
194     movff       __wreg_store, _WREG
195     
196     return
197     
198     __endasm ;
199 }