]> git.sur5r.net Git - cc65/blob - libsrc/pce/memcpy.s
Adjusted to the current multiline-comment style.
[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 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"!
15 ;
16
17         .export         _memcpy
18         .export         memcpy_increment, memcpy_transfer, memcpy_getparams
19
20         .import         incsp2, popax, popptr1
21         .importzp       sp, ptr1, ptr2, ptr3
22
23
24 ; The structure of the transfer instructions
25
26         .struct
27 opcode          .byte
28 source          .addr
29 destination     .addr
30 length          .word
31         .endstruct
32
33 ; ----------------------------------------------------------------------
34 _memcpy:
35         jsr     memcpy_getparams
36
37 memcpy_increment:
38         ldy     #$73                    ; TII opcode
39
40 memcpy_transfer:
41         sty     transfer + opcode
42
43         lda     ptr1
44         ldx     ptr1+1
45         sta     transfer + source
46         stx     transfer + source+1
47
48         lda     ptr2
49         ldx     ptr2+1
50         sta     transfer + destination
51         stx     transfer + destination+1
52
53         lda     ptr3
54         ldx     ptr3+1
55         sta     transfer + length
56         stx     transfer + length+1
57
58         jmp     transfer
59
60 ; ----------------------------------------------------------------------
61 ; Get the parameters from the stack, as follows:
62 ;
63 ;       size --> ptr3
64 ;       src  --> ptr1
65 ;       dest --> ptr2
66 ;
67 ; The first argument (dest) will remain on the stack; and, is returned in .XA!
68
69 memcpy_getparams:
70         sta     ptr3
71         stx     ptr3+1                  ; save size
72         ora     ptr3+1
73         bne     @L1
74
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.)
78
79         ply                             ; drop return address
80         plx
81         jsr     incsp2                  ; drop src address
82         jmp     popax                   ; get pointer; return it as result
83
84 @L1:    jsr     popptr1                 ; save src
85
86 ; (Direct stack access is six cycles faster [total cycle count].)
87
88         iny                             ; (Y=0 by popptr1, need '1' here) save dest
89         lda     (sp),y                  ; get high byte
90         tax
91         lda     (sp)                    ; get low byte
92         sta     ptr2
93         stx     ptr2+1
94         rts                             ; return dest address (for memmove)
95
96 ; ----------------------------------------------------------------------
97 ; The transfer instructions use inline arguments.
98 ; Therefore, we must build the instruction in the DATA segment.
99
100 .data
101
102 transfer:
103         tii     $FFFF, $FFFF, $0001
104         jmp     popax                   ; get pointer; return it as result