2 ; 2003-08-20, Ullrich von Bassewitz
3 ; 2009-09-13, Christian Krueger -- performance increase (about 20%), 2013-07-25 improved unrolling
4 ; 2015-10-23, Greg King
6 ; void* __fastcall__ memmove (void* dest, const void* src, size_t size);
8 ; NOTE: This function uses entry points from memcpy!
12 .import memcpy_getparams, memcpy_upwards, popax
13 .importzp ptr1, ptr2, ptr3, ptr4, tmp1
18 ; ----------------------------------------------------------------------
22 ; Check for the copy direction. If dest < src, we must copy upwards (start at
23 ; low addresses and increase pointers), otherwise we must copy downwards
24 ; (start at high addresses and decrease pointers).
29 jcc memcpy_upwards ; Branch if dest < src (upwards copy)
31 ; Copy downwards. Adjust the pointers to the end of the memory regions.
41 ; handle fractions of a page size first
43 ldy ptr3 ; count, low byte
44 bne @entry ; something to copy?
45 beq PageSizeCopy ; here like bra...
53 lda (ptr1),y ; copy remaining byte
56 PageSizeCopy: ; assert Y = 0
57 ldx ptr3+1 ; number of pages
58 beq done ; none? -> done
61 dec ptr1+1 ; adjust base...
63 dey ; in entry case: 0 -> FF
65 .repeat 3 ; unroll this a bit to make it faster...
66 lda (ptr1),y ; important: unrolling three times gives a nice
67 sta (ptr2),y ; 255/3 = 85 loop which ends at 0
70 @copyEntry: ; in entry case: 0 -> FF
72 lda (ptr1),y ; Y = 0, copy last byte
74 dex ; one page to copy less
75 bne @initBase ; still a page to copy?
79 done: jmp popax ; Pop ptr and return as result