summaryrefslogtreecommitdiff
path: root/src/kernel/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/util.c')
-rw-r--r--src/kernel/util.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/kernel/util.c b/src/kernel/util.c
index ea0496e..279616c 100644
--- a/src/kernel/util.c
+++ b/src/kernel/util.c
@@ -2,7 +2,15 @@
#include <stdint.h>
#include "drive.h"
+#include "log.h"
+#define ACROSS 0x04004e60
+
void memcpy(void *to, const void *from, uint32_t n) {
+ if (((uint32_t)to <= ACROSS) && ((uint32_t)(to + n) > ACROSS)) {
+ logf(LOG_WARN, "memcpy across 0x%h!", ACROSS);
+ logf(LOG_INFO, "was: memcpy(0x%h, 0x%h, %d)", to, from, n);
+ }
+
uint32_t *tp = to;
const uint32_t *fp = from;
while (n >= 4) {
@@ -39,4 +47,32 @@ void fmcpy(void *to, const struct drive *d, file_id_t f, uint32_t from, uint32_t
d->load_sector(d, f, fsi, buf);
memcpy(to + i, buf, n);
+}
+
+void mfcpy(const struct drive *d, file_id_t f, uint32_t to, const void *from, uint32_t n) {
+ uint8_t buf[512];
+
+ const uint16_t first_batch = to % 512 + n >= 512 ? 512 - to % 512 : n;
+ if (first_batch) {
+ d->load_sector(d, f, to / 512, buf);
+ memcpy(buf + to % 512, from, first_batch);
+ d->save_sector(d, f, to / 512, buf);
+ n -= first_batch;
+ from += first_batch;
+ }
+
+ uint32_t sector_on = to / 512 + 1;
+ while (n >= 512) {
+ memcpy(buf, from, 512);
+ d->save_sector(d, f, sector_on, buf);
+ n -= 512;
+ from += 512;
+ ++sector_on;
+ }
+
+ if (n) {
+ d->load_sector(d, f, sector_on, buf);
+ memcpy(buf, from, n);
+ d->save_sector(d, f, sector_on, buf);
+ }
} \ No newline at end of file