mirror of
https://github.com/cc65/cc65.git
synced 2025-08-08 06:25:17 +00:00
Split memcpy and memmove, since the former is used a lot more often than
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
This commit is contained in:
@@ -109,6 +109,7 @@ S_OBJS = _cwd.o \
|
|||||||
memchr.o \
|
memchr.o \
|
||||||
memcmp.o \
|
memcmp.o \
|
||||||
memcpy.o \
|
memcpy.o \
|
||||||
|
memmove.o \
|
||||||
memset.o \
|
memset.o \
|
||||||
modfree.o \
|
modfree.o \
|
||||||
modload.o \
|
modload.o \
|
||||||
|
@@ -1,113 +1,70 @@
|
|||||||
;
|
;
|
||||||
; void* memcpy (void* dest, const void* src, size_t n);
|
; Ullrich von Bassewitz, 2003-08-20
|
||||||
; void* memmove (void* dest, const void* src, size_t n);
|
|
||||||
;
|
;
|
||||||
; 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
|
.export _memcpy, memcpy_upwards, memcpy_getparams
|
||||||
.import popax
|
.import popax
|
||||||
.importzp ptr1, ptr2, ptr3, tmp1, tmp2
|
.importzp ptr1, ptr2, ptr3, tmp1
|
||||||
|
|
||||||
; ----------------------------------------------------------------------
|
; ----------------------------------------------------------------------
|
||||||
_memcpy:
|
_memcpy:
|
||||||
jsr getparms ; Get the parameters from stack
|
jsr memcpy_getparams
|
||||||
|
|
||||||
; Copy upwards
|
memcpy_upwards:
|
||||||
|
ldy #0
|
||||||
|
ldx ptr3 ; Get low counter byte
|
||||||
|
|
||||||
copyup: ldy #0 ; set up to move 256
|
; Copy loop
|
||||||
ldx tmp2 ; hi byte of n
|
|
||||||
beq @L2
|
|
||||||
|
|
||||||
@L1: lda (ptr1),y ; get a byte
|
@L1: inx ; Bump low counter byte
|
||||||
sta (ptr2),y ; store it
|
beq @L2 ; Jump on overflow
|
||||||
iny
|
lda (ptr1),y
|
||||||
bne @L1
|
sta (ptr2),y
|
||||||
inc ptr1+1 ; bump ptrs
|
iny
|
||||||
inc ptr2+1
|
bne @L1
|
||||||
dex
|
inc ptr1+1 ; Bump pointers
|
||||||
bne @L1 ; do another block
|
inc ptr2+1
|
||||||
|
bne @L1 ; Branch always
|
||||||
|
@L2: inc ptr3+1 ; Bump high counter byte
|
||||||
|
bne @L1
|
||||||
|
|
||||||
@L2: ldx tmp1 ; get low byte of n
|
; Done. The low byte of dest is still in ptr2
|
||||||
beq done ; jump if done
|
|
||||||
|
|
||||||
@L3: lda (ptr1),y ; get a byte
|
done: lda ptr2
|
||||||
sta (ptr2),y ; store it
|
ldx tmp1 ; get function result (dest)
|
||||||
iny
|
|
||||||
dex
|
|
||||||
bne @L3
|
|
||||||
|
|
||||||
done: lda ptr3
|
|
||||||
ldx ptr3+1 ; get function result (dest)
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
; ----------------------------------------------------------------------
|
; ----------------------------------------------------------------------
|
||||||
_memmove:
|
; Get the parameters from stack as follows:
|
||||||
jsr getparms ; Get the parameters from stack
|
;
|
||||||
|
; -(size-1) --> ptr3
|
||||||
|
; src --> ptr1
|
||||||
|
; dest --> ptr2
|
||||||
|
; high(dest) --> tmp1
|
||||||
|
;
|
||||||
|
; dest is returned in a/x.
|
||||||
|
|
||||||
cpx ptr1+1 ; dest > src?
|
memcpy_getparams:
|
||||||
bne @L1
|
eor #$FF
|
||||||
cmp ptr1
|
sta ptr3
|
||||||
@L1: beq done ; Both pointers are equal - nothing to copy
|
txa
|
||||||
bcc copyup ; Copy upwards
|
eor #$FF
|
||||||
|
sta ptr3+1 ; Save -(size-1)
|
||||||
|
|
||||||
; 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
|
|
||||||
|
|
||||||
beq done
|
|
||||||
|
|
||||||
; ----------------------------------------------------------------------
|
|
||||||
; Get the parameters from stack
|
|
||||||
|
|
||||||
getparms:
|
|
||||||
sta tmp1 ; Save n
|
|
||||||
stx tmp2
|
|
||||||
jsr popax ; src
|
jsr popax ; src
|
||||||
sta ptr1
|
sta ptr1
|
||||||
stx ptr1+1
|
stx ptr1+1
|
||||||
|
|
||||||
jsr popax ; dest
|
jsr popax ; dest
|
||||||
sta ptr2
|
sta ptr2
|
||||||
stx ptr2+1 ; save work copy
|
stx ptr2+1 ; Save work copy
|
||||||
sta ptr3
|
stx tmp1 ; Save for function result
|
||||||
stx ptr3+1 ; save function result
|
|
||||||
rts
|
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
67
libsrc/common/memmove.s
Normal file
67
libsrc/common/memmove.s
Normal file
@@ -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
|
||||||
|
|
Reference in New Issue
Block a user