From 5768e8059dc3b7f56361fe5b5c578294df3fdf67 Mon Sep 17 00:00:00 2001
From: Christian Cunningham <cc@localhost>
Date: Mon, 20 Dec 2021 19:57:18 -0800
Subject: Implemented memory functions

---
 src/cpu/atomic/swap.a.h |  3 +--
 src/lib/mem.c           | 38 ++++++++++++++++++++++++++++++++++++++
 src/lib/mem.h           | 11 +++++++++++
 src/lib/strings.c       | 15 +++++++++++++--
 src/lib/strings.h       |  7 +++++--
 src/sys/core.c          |  5 +++--
 6 files changed, 71 insertions(+), 8 deletions(-)
 create mode 100644 src/lib/mem.c
 create mode 100644 src/lib/mem.h

diff --git a/src/cpu/atomic/swap.a.h b/src/cpu/atomic/swap.a.h
index 1ca2a52..5e8ff57 100644
--- a/src/cpu/atomic/swap.a.h
+++ b/src/cpu/atomic/swap.a.h
@@ -1,7 +1,6 @@
-#include "../../util/mutex.h"
-
 #ifndef CPU_ATOMIC_SWAP_A_H
 #define CPU_ATOMIC_SWAP_A_H
+#include "../../util/mutex.h"
 
 /// https://stackoverflow.com/questions/16329123/use-of-strexeq-instead-of-strex-for-spinlock-implementation-in-arm
 /// https://elixir.bootlin.com/linux/v4.9/source/arch/arm/include/asm/spinlock.h
diff --git a/src/lib/mem.c b/src/lib/mem.c
new file mode 100644
index 0000000..cf1c980
--- /dev/null
+++ b/src/lib/mem.c
@@ -0,0 +1,38 @@
+#include "../drivers/uart.a.h"
+
+void memshow32(unsigned long* addr, unsigned int n) {
+	for(unsigned int i = 0; i < n; i++) {
+		uart_hex(addr[i]);
+		if (i+1 != n)
+			uart_char(0x20);
+	}
+	uart_char(0x0a);
+}
+
+void memcpy(unsigned char* src, unsigned char* dest, unsigned int n) {
+	for(unsigned int i = 0; i < n; i++) {
+		dest[i] = src[i];
+	}
+}
+
+unsigned char memcmp(unsigned char* a, unsigned char* b, unsigned int n) {
+	for(unsigned int i = 0; i < n; i++) {
+		if (a[i] != b[i])
+			return 0;
+	}
+	return 1;
+}
+
+void memcpy32(unsigned long* src, unsigned long* dest, unsigned int n) {
+	for(unsigned int i = 0; i < n; i++) {
+		dest[i] = src[i];
+	}
+}
+
+unsigned char memcmp32(unsigned long* a, unsigned long* b, unsigned int n) {
+	for(unsigned int i = 0; i < n; i++) {
+		if (a[i] != b[i])
+			return 0;
+	}
+	return 1;
+}
diff --git a/src/lib/mem.h b/src/lib/mem.h
new file mode 100644
index 0000000..67e2717
--- /dev/null
+++ b/src/lib/mem.h
@@ -0,0 +1,11 @@
+#ifndef LIB_MEM_H
+#define LIB_MEM_H
+
+void memcpy(unsigned char* src, unsigned char* dest, unsigned int n);
+unsigned char memcmp(unsigned char* a, unsigned char* b, unsigned int n);
+
+void memshow32(unsigned long* addr, unsigned int n);
+void memcpy32(unsigned long* src, unsigned long* dest, unsigned int n);
+unsigned char memcmp32(unsigned long* a, unsigned long* b, unsigned int n);
+
+#endif
diff --git a/src/lib/strings.c b/src/lib/strings.c
index 8f62391..795caa2 100644
--- a/src/lib/strings.c
+++ b/src/lib/strings.c
@@ -1,6 +1,6 @@
 #include "../lib/strings.h"
 
-unsigned long strlen(char* s) {
+unsigned long strlen(string_t s) {
 	unsigned long len = 0;
 	while (s[len] != 0) {
 		len += 1;
@@ -8,7 +8,7 @@ unsigned long strlen(char* s) {
 	return len;
 }
 
-unsigned char strcmp(char* a, char* b) {
+unsigned char strcmp(string_t a, string_t b) {
 	unsigned long idx = 0;
 	while (a[idx] != 0 && b[idx] != 0) {
 		if (a[idx] != b[idx]) {
@@ -18,3 +18,14 @@ unsigned char strcmp(char* a, char* b) {
 	}
 	return a[idx] == b[idx];
 }
+
+unsigned char strcmpn(string_t a, string_t b, unsigned int n) {
+	unsigned long idx = 0;
+	while (a[idx] != 0 && b[idx] != 0 && idx+1 < n) {
+		if (a[idx] != b[idx]) {
+			return 0;
+		}
+		idx += 1;
+	}
+	return a[idx] == b[idx];
+}
diff --git a/src/lib/strings.h b/src/lib/strings.h
index 61dd316..1bbcac8 100644
--- a/src/lib/strings.h
+++ b/src/lib/strings.h
@@ -1,7 +1,10 @@
 #ifndef LIB_STRINGS_H
 #define LIB_STRINGS_H
 
-unsigned long strlen(char* s);
-unsigned char strcmp(char* a, char* b);
+#define string_t char*
+
+unsigned long strlen(string_t s);
+unsigned char strcmp(string_t a, string_t b);
+unsigned char strcmpn(string_t a, string_t b, unsigned int n);
 
 #endif
diff --git a/src/sys/core.c b/src/sys/core.c
index f4b0581..5cac672 100644
--- a/src/sys/core.c
+++ b/src/sys/core.c
@@ -1,6 +1,7 @@
 #include "../drivers/uart.a.h"
 #include "../drivers/uart.h"
 #include "../graphics/draw.h"
+#include "../lib/mem.h"
 #include "../lib/strings.h"
 #include "../util/time.h"
 #include "../util/mutex.h"
@@ -8,14 +9,14 @@
 #include "../sys/timer.h"
 #include "../sys/power.h"
 
+extern void init_graphics(void);
+
 #ifndef VERSION
 char* os_info_v = "?";
 #else
 char* os_info_v = VERSION;
 #endif
 
-extern void init_graphics(void);
-
 static char* irq_on  = " \033[92mEnabled\033[0m";
 static char* irq_off = " \033[91mDisabled\033[0m";
 
-- 
cgit v1.2.1