summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2021-05-09 12:19:34 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2021-05-09 12:19:34 -0400
commit98886be8aa8508feabbcd8f232ba85ef46a7a139 (patch)
tree1d02ce45dd81dbfacca53cca94afffbbb4e897d6
parente9001152cdb22751ccd27d73f3cbfcb921f9fbe4 (diff)
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.
-rw-r--r--programs/sub-suite/libc.s45
1 files changed, 41 insertions, 4 deletions
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.