summaryrefslogtreecommitdiff
path: root/src/kernel/plef.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/plef.c')
-rw-r--r--src/kernel/plef.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/kernel/plef.c b/src/kernel/plef.c
new file mode 100644
index 0000000..2cba843
--- /dev/null
+++ b/src/kernel/plef.c
@@ -0,0 +1,33 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include "plef.h"
+#include "drive.h"
+#include "util.h"
+#include "task.h"
+
+#define PLEF_MAGIC 0xb9ba4c50
+
+task_handle plef_run(struct drive *d, char *path) {
+ drive_file_id_t h = d->get_file(d, path);
+ if (!h)
+ return 0;
+
+ uint8_t start[512];
+ d->load_sector(d, h, 0, start);
+
+ struct plef_header head = *(struct plef_header *)start;
+ if ((head.magic != PLEF_MAGIC) || (head.version_high)) {
+ d->free_file(d, h);
+ return 0;
+ }
+
+ uint32_t payload_addr;
+ segment_id cs = new_segment(true, head.payload_length + head.bss_length, &payload_addr);
+ segment_id ds = mirror_segment(false, cs);
+
+ fmcpy((void *)payload_addr, d, h, head.payload_offset, head.payload_length);
+
+ d->free_file(d, h);
+
+ return new_task(cs, ds, head.entry_point, head.payload_length + head.bss_length);
+} \ No newline at end of file