gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/asm/mos6502/_memset.c
1 /*-------------------------------------------------------------------------
2 _memset.c - part of string library functions
3
4 Copyright (C) 1999, Sandeep Dutta . sandeep.dutta@usa.net
5 Copyright (C) 2020, Sergey Belyashov sergey.belyashov@gmail.com
6 Copyright (C) 2022, Sebastian 'basxto' Riedel
7 mcs51 assembler by Frieder Ferlemann (2007)
8
9 This library is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
12 later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this library; see the file COPYING. If not, write to the
21 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
22 MA 02110-1301, USA.
23
24 As a special exception, if you link this library with other files,
25 some of which are compiled with SDCC, to produce an executable,
26 this library does not by itself cause the resulting executable to
27 be covered by the GNU General Public License. This exception does
28 not however invalidate any other reasons why the executable file
29 might be covered by the GNU General Public License.
30 -------------------------------------------------------------------------*/
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 #undef memset /* Avoid conflict with builtin memset() in Z80 and some related ports */
36
37 #if defined (_SDCC_NO_ASM_LIB_FUNCS) || !defined (__SDCC_mcs51) || \
38 (!defined (__SDCC_MODEL_SMALL) && !defined (__SDCC_MODEL_LARGE)) || \
39 (defined (__SDCC_STACK_AUTO) || defined (__SDCC_PARMS_IN_BANK1) )
40
41 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
42 void *memset (void *s, unsigned char c, size_t n)
43 #else
44 void *memset (void *s, int c, size_t n)
45 #endif
46
47 #if !defined (_SDCC_NO_ASM_LIB_FUNCS) && (\
48 defined (__SDCC_z80) ||\
49 defined (__SDCC_z180) ||\
50 defined (__SDCC_z80n))
51 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
52 #error Unimplemented broken string function
53 #endif
54 __naked
55 {
56 (void)s;
57 (void)c;
58 (void)n;
59 __asm
60 pop iy
61 pop bc
62 push hl
63 ld a, c
64 or a, b
65 jr Z, end
66 ld (hl), e
67 dec bc
68 ld a, c
69 or a, b
70 jr Z, end
71 ld e, l
72 ld d, h
73 inc de
74 ldir
75 end:
76 pop de
77 jp (iy)
78 __endasm;
79 }
80 #elif !defined (_SDCC_NO_ASM_LIB_FUNCS) && (\
81 defined (__SDCC_ez80_z80) ||\
82 defined (__SDCC_r2k) ||\
83 defined (__SDCC_z3ka))
84
85 __naked
86 {
87 (void)s;
88 (void)c;
89 (void)n;
90 __asm
91 pop af
92 pop hl
93 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
94 dec sp
95 #endif
96 pop de
97 pop bc
98 push bc
99 push de
100 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
101 inc sp
102 #endif
103 push hl
104 push af
105 ld a, c
106 or a, b
107 ret Z
108 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
109 ld (hl), d
110 #else
111 ld (hl), e
112 #endif
113 dec bc
114 ld a, c
115 or a, b
116 ret Z
117 push hl
118 ld e, l
119 ld d, h
120 inc de
121 ldir
122 pop hl
123 ret
124 __endasm;
125 }
126 #elif !defined (_SDCC_NO_ASM_LIB_FUNCS) && defined(__SDCC_sm83)
127 __naked
128 {
129 (void)s;//de
130 (void)c;//bc or for broken string function in a
131 (void)n;//stack+2, stack+3
132 __asm
133 ; Algorithm is Duff`s device
134 ldhl sp, #3
135 __endasm;
136 #ifdef __SDCC_BROKEN_STRING_FUNCTIONS
137 __asm
138 ld b, (hl)
139 dec hl
140 __endasm;
141 #else
142 __asm
143
144 ld a, (hl-)
145 ld b, a
146 ld a, c
147 __endasm;
148 #endif
149 __asm
150 ld c, (hl)
151 ld l, e
152 ld h, d
153 ;shift LSB to carry
154 srl b
155 rr c
156 jr nc, skip_one
157 ld (hl+), a
158 skip_one:
159 ;n/2 in bc
160 ;shift second LSB to carry
161 srl b
162 rr c
163 ;n/4 in bc
164 inc b
165 inc c
166 jr nc, test
167 jr copy_two
168 copy_four:
169 ld (hl+), a
170 ld (hl+), a
171 copy_two:
172 ld (hl+), a
173 ld (hl+), a
174 test:
175 dec c
176 jr NZ, copy_four
177 dec b
178 jr NZ, copy_four
179 ;restore dest
180 ld c, e
181 ld b, d
182 pop hl
183 pop af
184 jp (hl)
185 __endasm;
186 }
187 #else
188 {
189 register size_t sz = n;
190 if (sz != 0)
191 {
192 register char *dst = s;
193 register char data = (char)c;
194 do {
195 *dst++ = data;
196 } while (--sz);
197 }
198 return s;
199 }
200 #endif
201 #else
202
203 /* assembler implementation for mcs51 */
204 static void dummy(void) __naked
205 {
206 __asm
207
208 /* assigning function parameters to registers.
209 __SDCC_PARMS_IN_BANK1 or __SDCC_STACK_AUTO not yet implemented. */
210 #if defined (__SDCC_MODEL_SMALL)
211
212 #if defined(__SDCC_NOOVERLAY)
213 .area DSEG (DATA)
214 #else
215 .area OSEG (OVR,DATA)
216 #endif
217 _memset_PARM_2::
218 .ds 1
219 _memset_PARM_3::
220 .ds 2
221
222 .area CSEG (CODE)
223
224 _memset::
225
226 ; Assign buf (b holds memspace, no need to touch)
227 mov r4,dpl
228 mov r5,dph
229 ;
230 ; Assign count
231 mov r6,_memset_PARM_3
232 mov r7,(_memset_PARM_3 + 1)
233 ;
234 ; if (!count) return buf;
235 ; check for count != 0 intermangled with gymnastic
236 ; preparing djnz instructions
237 cjne r6,#0x00,COUNT_LSB_NOT_ZERO
238 mov a,r7
239 jz MEMSET_END
240 dec r7
241 COUNT_LSB_NOT_ZERO:
242 inc r7
243 ;
244 ; This was 8 byte overhead for preparing
245 ; the count argument for an integer loop with two
246 ; djnz instructions - it might make sense to
247 ; let SDCC automatically generate this when
248 ; it encounters a loop like:
249 ; for(i=0;i<j;i++){...}
250 ; (at least for option --opt-code-speed)
251 ;
252
253 ; Assign ch
254 mov a,_memset_PARM_2
255
256 #else
257
258 .area XSEG (XDATA)
259
260 _memset_PARM_2::
261 .ds 1
262 _memset_PARM_3::
263 .ds 2
264
265 .area CSEG (CODE)
266
267 _memset::
268
269 ; Assign buf (b holds memspace, no need to touch)
270 mov r4,dpl
271 mov r5,dph
272 ;
273 ; Assign count
274 mov dptr,#_memset_PARM_3
275 movx a,@dptr
276 mov r6,a
277 inc dptr
278 movx a,@dptr
279 mov r7,a
280 ;
281 ; if (!count) return buf;
282 ; check for count != 0 intermangled with gymnastic
283 ; preparing djnz instructions
284 cjne r6,#0x00,COUNT_LSB_NOT_ZERO
285 ; acc holds r7
286 jz MEMSET_END
287 dec r7
288 COUNT_LSB_NOT_ZERO:
289 inc r7
290 ;
291 ; Assign ch
292 mov dptr,#_memset_PARM_2
293 movx a,@dptr
294 ; acc is precious now
295 ;
296 ; Restore dptr
297 mov dpl,r4
298 mov dph,r5
299
300 #endif
301
302 /* now independent of the parameter passing everything
303 should be in registers by now and the loop may start */
304 ; _memset.c do {
305
306 MEMSET_LOOP:
307 ; _memset.c *p = ch;
308 lcall __gptrput
309
310 ; _memset.c p++;
311 inc dptr
312
313 ; _memset.c } while(--count) ;
314 djnz r6,MEMSET_LOOP
315 djnz r7,MEMSET_LOOP
316 ;
317
318 MEMSET_END:
319 ; _memset.c return buf ;
320 ; b was unchanged
321 mov dpl,r4
322 mov dph,r5
323 ;
324 ret
325
326 __endasm;
327 }
328
329 #endif
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.