]> git.sur5r.net Git - cc65/blob - libsrc/pce/memcpy.s
Added code to handle the special case of a zero-length move.
[cc65] / libsrc / pce / memcpy.s
1 ;
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.
5 ;
6 ; 2003-08-20, Ullrich von Bassewitz
7 ; 2015-11-02, Greg King
8 ;
9 ; void* __fastcall__ memcpy (void* dest, const void* src, size_t size);
10 ;
11 ; NOTE:  This function contains entry points for memmove, which will resort
12 ; to memcpy for an incrementing copy.  Don't change this module without looking
13 ; at "pce/memmove.s"!
14 ;
15
16         .export         _memcpy
17         .export         memcpy_increment, memcpy_transfer, memcpy_getparams
18
19         .import         incsp2, popax
20         .importzp       sp, ptr1, ptr2, ptr3
21
22
23 ; The structure of the transfer instructions
24
25         .struct
26 opcode          .byte
27 source          .addr
28 destination     .addr
29 length          .word
30         .endstruct
31
32 ; ----------------------------------------------------------------------
33 _memcpy:
34         jsr     memcpy_getparams
35
36 memcpy_increment:
37         ldy     #$73                    ; TII
38
39 memcpy_transfer:
40         sty     transfer+opcode
41
42         lda     ptr1
43         ldx     ptr1+1
44         sta     transfer+source
45         stx     transfer+source+1
46
47         lda     ptr2
48         ldx     ptr2+1
49         sta     transfer+destination
50         stx     transfer+destination+1
51
52         lda     ptr3
53         ldx     ptr3+1
54         sta     transfer+length
55         stx     transfer+length+1
56
57         jmp     transfer
58
59 ; ----------------------------------------------------------------------
60 ; Get the parameters from the stack, as follows:
61 ;
62 ;       size --> ptr3
63 ;       src  --> ptr1
64 ;       dest --> ptr2
65 ;
66 ; The first argument (dest) will remain on the stack; and, is returned in .XA!
67
68 memcpy_getparams:
69         sta     ptr3
70         stx     ptr3+1                  ; save size
71         ora     ptr3+1
72         bne     @L1
73
74 ; The size is zero; copy nothing; just return the dest address.
75 ; (The HuC6280's transfer instructions can't copy $0000 bytes;
76 ;  they would copy $10000 [64K] bytes instead.)
77
78         ply                             ; drop return address
79         plx
80         jsr     incsp2                  ; drop src address
81         jmp     popax                   ; get pointer; return it as result
82
83 @L1:    jsr     popax
84         sta     ptr1
85         stx     ptr1+1                  ; save src
86
87 ; (Direct stack access is six cycles faster [total cycle count].)
88
89         ldy     #1                      ; save dest
90         lda     (sp),y                  ; get high byte
91         tax
92         lda     (sp)                    ; get low byte
93         sta     ptr2
94         stx     ptr2+1
95         rts                             ; return dest address (for memmove)
96
97 ; ----------------------------------------------------------------------
98 ; The transfer instructions use inline arguments.
99 ; Therefore, we must build the instruction, in the DATA segment.
100
101 .data
102
103 transfer:
104         tii     $FFFF, $FFFF, $0001
105         jmp     popax                   ; get pointer; return it as result