2 ; This file, instead of "common/memcpy.s", will be assembled for the pce
3 ; target. This version is smaller and faster because it uses the HuC6280's
4 ; block-copy instructions.
6 ; 2003-08-20, Ullrich von Bassewitz
7 ; 2015-11-02, Greg King
9 ; void* __fastcall__ memcpy (void* dest, const void* src, size_t size);
11 ; NOTE: This function contains entry points for memmove(), which resorts to
12 ; memcpy() for incrementing copies. The PC-Engine memset() uses this memcpy()
13 ; to fill memory quickly. Don't change this module without looking at
14 ; "pce/memmove.s" and "pce/memset.s"!
18 .export memcpy_increment, memcpy_transfer, memcpy_getparams
20 .import incsp2, popax, popptr1
21 .importzp sp, ptr1, ptr2, ptr3
24 ; The structure of the transfer instructions
33 ; ----------------------------------------------------------------------
46 stx transfer + source+1
50 sta transfer + destination
51 stx transfer + destination+1
56 stx transfer + length+1
60 ; ----------------------------------------------------------------------
61 ; Get the parameters from the stack, as follows:
67 ; The first argument (dest) will remain on the stack; and, is returned in .XA!
71 stx ptr3+1 ; save size
75 ; The size is zero; copy nothing; just return the dest address.
76 ; (The HuC6280's transfer instructions can't copy $0000 bytes;
77 ; they would copy $10000 [64K] bytes instead.)
79 ply ; drop return address
81 jsr incsp2 ; drop src address
82 jmp popax ; get pointer; return it as result
84 @L1: jsr popptr1 ; save src
86 ; (Direct stack access is six cycles faster [total cycle count].)
88 iny ; (Y=0 by popptr1, need '1' here) save dest
89 lda (sp),y ; get high byte
91 lda (sp) ; get low byte
94 rts ; return dest address (for memmove)
96 ; ----------------------------------------------------------------------
97 ; The transfer instructions use inline arguments.
98 ; Therefore, we must build the instruction in the DATA segment.
103 tii $FFFF, $FFFF, $0001
104 jmp popax ; get pointer; return it as result