]> git.sur5r.net Git - cc65/blob - libsrc/common/memset.s
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / libsrc / common / memset.s
1 ;
2 ; void* __fastcall__ memset (void* ptr, int c, size_t n);
3 ; void* __fastcall__ _bzero (void* ptr, size_t n);
4 ; void __fastcall__ bzero (void* ptr, size_t n);
5 ;
6 ; Ullrich von Bassewitz, 29.05.1998
7 ; Performance increase (about 20%) by
8 ; Christian Krueger, 12.09.2009, slightly improved 12.01.2011
9 ;
10 ; NOTE: bzero will return it's first argument as memset does. It is no problem
11 ;       to declare the return value as void, since it may be ignored. _bzero
12 ;       (note the leading underscore) is declared with the proper return type,
13 ;       because the compiler will replace memset by _bzero if the fill value
14 ;       is zero, and the optimizer looks at the return type to see if the value
15 ;       in a/x is of any use.
16 ;
17
18         .export         _memset, _bzero, __bzero
19         .import         popax
20         .importzp       sp, ptr1, ptr2, ptr3
21
22 _bzero:
23 __bzero:
24         sta     ptr3
25         stx     ptr3+1          ; Save n
26         ldx     #0              ; Fill with zeros
27         beq     common
28
29 _memset:
30         sta     ptr3            ; Save n
31         stx     ptr3+1
32         jsr     popax           ; Get c
33         tax
34
35 ; Common stuff for memset and bzero from here
36
37 common:                         ; Fill value is in X!
38         ldy     #1
39         lda     (sp),y
40         sta     ptr1+1          ; save high byte of ptr
41         dey                     ; Y = 0
42         lda     (sp),y          ; Get ptr
43         sta     ptr1
44
45         lsr     ptr3+1          ; divide number of
46         ror     ptr3            ; bytes by two to increase
47         bcc     evenCount       ; speed (ptr3 = ptr3/2)
48 oddCount:
49                                 ; y is still 0 here
50         txa                     ; restore fill value
51         sta     (ptr1),y        ; save value and increase
52         inc     ptr1            ; dest. pointer
53         bne     evenCount
54         inc     ptr1+1
55 evenCount:
56         lda     ptr1            ; build second pointer section
57         clc
58         adc     ptr3            ; ptr2 = ptr1 + (length/2) <- ptr3
59         sta     ptr2
60         lda     ptr1+1
61         adc     ptr3+1
62         sta     ptr2+1
63
64         txa                     ; restore fill value
65         ldx     ptr3+1          ; Get high byte of n
66         beq     L2              ; Jump if zero
67
68 ; Set 256/512 byte blocks
69                                 ; y is still 0 here
70 L1:     .repeat 2               ; Unroll this a bit to make it faster
71         sta     (ptr1),y        ; Set byte in lower section
72         sta     (ptr2),y        ; Set byte in upper section
73         iny
74         .endrepeat
75         bne     L1
76         inc     ptr1+1
77         inc     ptr2+1
78         dex                     ; Next 256 byte block
79         bne     L1              ; Repeat if any
80
81 ; Set the remaining bytes if any
82
83 L2:     ldy     ptr3            ; Get the low byte of n
84         beq     leave           ; something to set? No -> leave
85
86 L3:     dey
87         sta     (ptr1),y                ; set bytes in low
88         sta     (ptr2),y                ; and high section
89         bne     L3              ; flags still up to date from dey!
90 leave:  
91         jmp     popax           ; Pop ptr and return as result
92
93