]> git.sur5r.net Git - cc65/commitdiff
Split memcpy and memmove, since the former is used a lot more often than
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 20 Aug 2003 10:17:53 +0000 (10:17 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 20 Aug 2003 10:17:53 +0000 (10:17 +0000)
the latter.
Optimized the code for smaller size and greater speed.

git-svn-id: svn://svn.cc65.org/cc65/trunk@2382 b7a2c559-68d2-44c3-8de9-860c34a00d81

libsrc/common/Makefile
libsrc/common/memcpy.s
libsrc/common/memmove.s [new file with mode: 0644]

index 3d4ce55922d398d11c7199229afce2d6ef4bd547..21ed8aa29b0ef69b10a7315f81a135ac37dc8d38 100644 (file)
@@ -109,6 +109,7 @@ S_OBJS =    _cwd.o          \
                memchr.o        \
                memcmp.o        \
                memcpy.o        \
+                memmove.o       \
                memset.o        \
                modfree.o       \
                modload.o       \
index 4ef141df0d45f4f27a94193e76a93c5f1642da35..b61b82c1f68e4e1465aad89de080f8c720466af5 100644 (file)
 ;
-; void* memcpy (void* dest, const void* src, size_t n);
-; void* memmove (void* dest, const void* src, size_t n);
+; Ullrich von Bassewitz, 2003-08-20
 ;
-; Ullrich von Bassewitz, 10.12.1998
+; void* __fastcall__ memcpy (void* dest, const void* src, size_t n);
+;
+; NOTE: This function contains entry points for memmove, which will ressort
+; to memcpy for an upwards copy. Don't change this module without looking
+; at memmove!
 ;
 
-       .export         _memcpy, _memmove
-       .import         popax
-       .importzp       ptr1, ptr2, ptr3, tmp1, tmp2
+               .export         _memcpy, memcpy_upwards, memcpy_getparams
+               .import         popax
+               .importzp       ptr1, ptr2, ptr3, tmp1
 
 ; ----------------------------------------------------------------------
 _memcpy:
-       jsr     getparms        ; Get the parameters from stack
-
-; Copy upwards
-
-copyup:        ldy     #0              ; set up to move 256
-       ldx     tmp2            ; hi byte of n
-       beq     @L2
-
-@L1:   lda     (ptr1),y        ; get a byte
-       sta     (ptr2),y        ; store it
-       iny
-               bne     @L1
-       inc     ptr1+1          ; bump ptrs
-       inc     ptr2+1
-               dex
-       bne     @L1             ; do another block
-
-@L2:   ldx     tmp1            ; get low byte of n
-       beq     done            ; jump if done
-
-@L3:   lda     (ptr1),y        ; get a byte
-       sta     (ptr2),y        ; store it
-       iny
-       dex
-       bne     @L3
-
-done:  lda     ptr3
-       ldx     ptr3+1          ; get function result (dest)
+        jsr     memcpy_getparams
+
+memcpy_upwards:
+        ldy     #0
+        ldx     ptr3            ; Get low counter byte
+
+; Copy loop
+
+@L1:    inx                     ; Bump low counter byte
+        beq     @L2             ; Jump on overflow
+        lda     (ptr1),y
+        sta     (ptr2),y
+        iny
+        bne     @L1
+               inc     ptr1+1          ; Bump pointers
+               inc     ptr2+1
+        bne     @L1             ; Branch always
+@L2:    inc     ptr3+1          ; Bump high counter byte
+        bne     @L1
+
+; Done. The low byte of dest is still in ptr2
+
+done:          lda     ptr2
+               ldx     tmp1            ; get function result (dest)
                rts
 
-
 ; ----------------------------------------------------------------------
-_memmove:
-       jsr     getparms        ; Get the parameters from stack
-
-       cpx     ptr1+1          ; dest > src?
-       bne     @L1
-       cmp     ptr1
-@L1:   beq     done            ; Both pointers are equal - nothing to copy
-       bcc     copyup          ; Copy upwards
-
-; Copy downwards
-
-       clc
-               lda     ptr1+1
-       adc     tmp2
-       sta     ptr1+1
-
-       clc
-       lda     ptr2+1
-       adc     tmp2
-       sta     ptr2+1
-
-; Copy the incomplete page
-
-       ldy     tmp1            ; Get low byte of count
-       beq     @L3
-
-@L2:   dey
-       lda     (ptr1),y
-       sta     (ptr2),y
-       tya                     ; Test Y
-       bne     @L2             ; Jump if not zero
-
-; Copy complete pages
-
-@L3:   ldx     tmp2            ; Get hi byte of count
-       beq     done
-
-@L4:   dec     ptr1+1
-       dec     ptr2+1
-@L5:   dey
-       lda     (ptr1),y
-       sta     (ptr2),y
-       tya
-       bne     @L5
-       dex
-       bne     @L4
-
-; Done
+; Get the parameters from stack as follows:
+;
+;       -(size-1)       --> ptr3
+;       src             --> ptr1
+;       dest            --> ptr2
+;       high(dest)      --> tmp1
+;
+; dest is returned in a/x.
 
-       beq     done
+memcpy_getparams:
+        eor     #$FF
+        sta     ptr3
+        txa
+        eor     #$FF
+        sta     ptr3+1          ; Save -(size-1)
 
-; ----------------------------------------------------------------------
-; Get the parameters from stack
-          
-getparms:
-               sta     tmp1            ; Save n
-               stx     tmp2
                jsr     popax           ; src
                sta     ptr1
                stx     ptr1+1
+
                jsr     popax           ; dest
        sta     ptr2
-       stx     ptr2+1          ; save work copy
-       sta     ptr3
-       stx     ptr3+1          ; save function result
-       rts
+       stx     ptr2+1          ; Save work copy
+        stx     tmp1            ; Save for function result
 
+        rts
 
diff --git a/libsrc/common/memmove.s b/libsrc/common/memmove.s
new file mode 100644 (file)
index 0000000..f344f9d
--- /dev/null
@@ -0,0 +1,67 @@
+;
+; Ullrich von Bassewitz, 2003-08-20
+;
+; void* __fastcall__ memmove (void* dest, const void* src, size_t size);
+;
+; NOTE: This function uses entry points from memcpy!
+;
+
+               .export         _memmove
+        .import         memcpy_getparams, memcpy_upwards
+               .importzp       ptr1, ptr2, ptr3, ptr4, tmp1
+
+        .macpack        generic
+        .macpack        longbranch
+
+; ----------------------------------------------------------------------
+_memmove:
+        sta     ptr4
+        stx     ptr4+1          ; Size -> ptr4
+
+        jsr     memcpy_getparams
+
+; Check for the copy direction. If dest < src, we must copy upwards (start at
+; low addresses and increase pointers), otherwise we must copy downwards
+; (start at high addresses and decrease pointers).
+
+        sec
+        sbc     ptr1
+        txa
+        sbc     ptr1+1
+        jcc     memcpy_upwards  ; Branch if dest < src (upwards copy)
+
+; Copy downwards. Adjust the pointers to the end of the memory regions.
+
+        lda    ptr1+1
+               add     ptr4+1
+       sta     ptr1+1
+
+       lda     ptr2+1
+       add     ptr4+1
+       sta     ptr2+1
+
+; Load the low offset into Y, and the counter low byte into X.
+
+        ldy     ptr4
+        ldx     ptr3
+        jmp     @L2
+
+; Copy loop
+
+@L1:    dey
+        lda     (ptr1),y
+        sta     (ptr2),y
+
+@L2:    inx                     ; Bump counter low byte
+        bne     @L1
+        dec     ptr1+1
+        dec     ptr2+1
+        inc     ptr3+1          ; Bump counter high byte
+        bne     @L1
+
+; Done, return dest
+
+done:          lda     ptr2
+               ldx     tmp1            ; get function result (dest)
+               rts
+