From 98886be8aa8508feabbcd8f232ba85ef46a7a139 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Sun, 9 May 2021 12:19:34 -0400 Subject: Add a end to start version of memcpy, and a selectable direction version of memcpy. This can help with some subroutines/functions like shftln, which need to copy data in a certain direction depending on the condition. --- programs/sub-suite/libc.s | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) (limited to 'programs') diff --git a/programs/sub-suite/libc.s b/programs/sub-suite/libc.s index 3de1094..b64eaf8 100644 --- a/programs/sub-suite/libc.s +++ b/programs/sub-suite/libc.s @@ -467,19 +467,56 @@ free: memcpy: phb.q ; Preserve B. - xor b, b ; Reset B. mov a, d ; Set the return value to the destination pointer. - cmp f, #0 ; Is the size zero? - beq @end ; Yes, so we're done. + and f, f ; Is the size zero? + beq @end ; The size is zero, so we're done. + xor b, b ; Reset B. @loop: mov (d+b), (s+b) ; Copy a byte from the source, into the destination. inb ; Increment the counter. cmp b, f ; Is the counter the same as the size? - bne @loop ; No, so keep looping. + bne @loop ; The size is non-zero, so keep looping. +@end: + plb.q ; Restore B. + rts ; End of memcpy. + +; memcpy_back: memory to memory copy from end to start. +; Input: D = Destination pointer. S = Source pointer. F = Number of bytes to copy. +; Output: A = Destination pointer. +; Caller preserved registers: D, S, F. +; Callee preserved registers: B. + +memcpy_back: + phb.q ; Preserve B. + mov a, d ; Set the return value to the destination pointer. + mov b, f ; Copy the size into B. +@loop: + cpb #0 ; Is the size zero? + beq @end ; Yes, so we're done. + deb ; No, so decrement the size. + mov (d+b), (s+b) ; Copy a byte from the source, into the destination. + bra @loop ; Keep looping. @end: plb.q ; Restore B. rts ; End of memcpy. +; memcpy_dir: memory to memory copy with selectable direction. +; Input: D = Destination pointer. S = Source pointer. F = Number of bytes to copy. +; C = direction flag, 0 = start to end, 1 = end to start. +; Output: A = Destination pointer. +; Caller preserved registers: D, S, F, C. +; Callee preserved registers: none. + +memcpy_dir: + and c, c ; Is the direction flag set? + bne @back ; Yes, so copy from end to start. +@forward: + jsr memcpy ; Copy from start to end. + bra @end ; We are done. +@back: + jsr memcpy_back ; Copy from end to start. +@end: + rts ; End of memcpy_dir. ; memset: Set memory to some value. ; Input: D = Destination pointer. S = Constant value. F = Number of bytes to set. -- cgit v1.2.3-13-gbd6f