_naked allows to use ret instead of sjmp to ret
[fw/sdcc] / device / lib / _gptrget.c
1 /*-------------------------------------------------------------------------
2
3   _gptrget.c :- get value for a generic pointer
4
5              Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1999)
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 /* not all devices use P2 to page pdata memory, therefore __XPAGE was
27    introduced. On some targets __XPAGE itself is a paged SFR so it is
28    not safe for all platforms to set this. Furthermore some targets
29    can be configured to behave differently for movx @dptr vs. movx @Ri
30    (don't drive high byte of address bus for movx @Ri only) */
31 #define USE_PDATA_PAGING_REGISTER 0
32
33 /* the  return value is expected to be in acc, and not in the standard
34  * location dpl. Therefore we choose return type void here: */
35 void
36 _gptrget (char *gptr) _naked
37 {
38     gptr; /* hush the compiler */
39
40     _asm
41         ar0 = 0x00
42     ;   save values passed
43     ;
44     ;   depending on the pointer type acc. to SDCCsymt.h
45     ;
46         mov     a,b
47         jz      00001$  ; 0 near
48         dec     a
49         jz      00002$  ; 1 far
50         dec     a
51         jz      00003$  ; 2 code
52         dec     a
53         jz      00004$  ; 3 pdata
54         dec     a       ; 4 skip generic pointer
55         dec     a
56         jz      00001$  ; 5 idata
57     ;
58     ;   any other value for type
59     ;   return xFF
60         mov     a,#0xff
61         ret
62     ;
63     ;   Pointer to data space
64     ;
65  00001$:
66         push    ar0
67         ;
68         mov     r0,dpl     ; use only low order address
69         mov     a,@r0
70         ;
71         pop     ar0
72         ;
73         ret
74     ;
75     ;   pointer to xternal data
76     ;
77  00002$:
78         movx    a,@dptr
79         ret
80 ;
81 ;   pointer to code area
82 ;
83  00003$:
84         ; clr     a  is already 0
85         movc    a,@a+dptr
86         ret
87 ;
88 ;   pointer to xternal stack or pdata
89 ;
90  00004$:
91 #if USE_PDATA_PAGING_REGISTER
92         mov     dph,__XPAGE     ; __XPAGE (usually p2) holds high byte for pdata access
93         movx    a,@dptr
94 #else
95         push    ar0
96         mov     r0,dpl
97         movx    a,@r0
98         pop     ar0
99 #endif
100         ret
101      _endasm ;
102 }
103
104 #ifdef SDCC_ds390
105 /* the  return value is expected to be in acc/_ap, and not in the standard
106  * location dpl/dph. Therefore we choose return type void here: */
107 void
108 _gptrgetWord (unsigned *gptr)
109 {
110     gptr; /* hush the compiler */
111
112     _asm
113     ;
114     ;   depending on the pointer type acc. to SDCCsymt.h
115     ;
116         mov     a,b
117         jz      00001$  ; 0 near
118         dec     a
119         jz      00002$  ; 1 far
120         dec     a
121         jz      00003$  ; 2 code
122         dec     a
123         jz      00004$  ; 3 pdata
124         dec     a       ; 4 skip generic pointer
125         dec     a
126         jz      00001$  ; 5 idata
127     ;
128     ;   any other value for type
129     ;   return xFF
130         mov     a,#0xff
131         sjmp    00006$
132     ;
133     ;   Pointer to data space
134     ;
135  00001$:
136         push    ar0
137         mov     r0,dpl     ; use only low order address
138         mov     _ap,@r0
139         inc     r0
140         mov     a,@r0
141         inc     dpl
142         sjmp    00005$
143     ;
144     ;   pointer to xternal data
145     ;
146  00002$:
147         movx    a,@dptr
148         mov     _ap,a
149         inc     dptr
150         movx    a,@dptr
151         sjmp    00006$
152 ;
153 ;   pointer to code area
154 ;
155  00003$:
156         ; clr     a  is already 0
157         movc    a,@a+dptr
158         mov     _ap,a
159         clr     a
160         inc     dptr
161         movc    a,@a+dptr
162         sjmp    00006$
163 ;
164 ;   pointer to xternal stack
165 ;
166  00004$:
167         push    ar0
168         mov     r0,dpl
169         movx    a,@r0
170         mov     _ap,a
171         inc     r0
172         movx    a,@r0
173         inc     dpl
174 ;
175 ;   restore and return
176 ;
177 00005$:
178     pop ar0
179 00006$:
180      _endasm ;
181
182 }
183 #endif