summaryrefslogtreecommitdiff
path: root/src/kernel/plef.c
blob: 710943fcc91850087d6d49f993efe61bbe06741e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdint.h>
#include "drive.h"
#include "plef.h"
#include "task.h"
#include "util.h"

#define PLEF_MAGIC 0xb9ba4c50

task_handle plef_run(const struct drive *d, const 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);
}