aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorNakst <djnakst2@gmail.com>2017-11-26 11:03:11 +0000
committerNakst <djnakst2@gmail.com>2017-11-26 11:03:11 +0000
commitb0d3fbba4761aff3dfc3bcded3da7000699a7766 (patch)
tree0e01e8d853324dad51addbd416c1fe8156c097a3 /core
parentadb6c7637e8748b19e550e45cba42d1155657249 (diff)
essence cross compile
Diffstat (limited to 'core')
-rw-r--r--core/os.odin1
-rw-r--r--core/os_essence.odin115
-rw-r--r--core/sys/essence_linker_userland64.ld24
3 files changed, 140 insertions, 0 deletions
diff --git a/core/os.odin b/core/os.odin
index 8f7a4ff92..1ed920a45 100644
--- a/core/os.odin
+++ b/core/os.odin
@@ -1,6 +1,7 @@
when ODIN_OS == "windows" do export "core:os_windows.odin";
when ODIN_OS == "osx" do export "core:os_x.odin";
when ODIN_OS == "linux" do export "core:os_linux.odin";
+when ODIN_OS == "essence" do export "core:os_essence.odin";
import "mem.odin";
diff --git a/core/os_essence.odin b/core/os_essence.odin
new file mode 100644
index 000000000..b6670850f
--- /dev/null
+++ b/core/os_essence.odin
@@ -0,0 +1,115 @@
+foreign import api "system:api"
+
+Handle :: int;
+Errno :: int;
+
+O_RDONLY :: 1;
+O_WRONLY :: 2;
+O_CREATE :: 4;
+O_TRUNC :: 4;
+
+OS_Node_Type :: enum i32 {
+ File = 0,
+ Directory = 1,
+}
+
+OS_Node_Information :: struct #ordered {
+ handle: Handle,
+ id: [16]u8,
+ ntype: OS_Node_Type,
+ size: i64,
+ position: i64,
+}
+
+foreign api {
+ @(link_name="OSHelloWorld") os_hello_world :: proc() ---;
+ @(link_name="OSPrintDirect") os_print_direct :: proc(string: ^u8, length: int) ---;
+ @(link_name="OSHeapAllocate") os_heap_allocate :: proc(bytes: int, zero: bool) -> rawptr ---;
+ @(link_name="OSHeapFree") os_heap_free :: proc(address: rawptr) ---;
+ @(link_name="OSOpenNode") os_open_node :: proc(path: ^u8, path_length: int, flags: u64, information: ^OS_Node_Information) -> Errno ---;
+ @(link_name="OSResizeFile") os_resize_file :: proc(handle: Handle, new_size: u64) -> Errno ---;
+ @(link_name="OSCloseHandle") os_close_handle :: proc(handle: Handle) ---;
+ @(link_name="OSWriteFileSync") os_write_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
+ @(link_name="OSReadFileSync") os_read_file_sync :: proc(handle: Handle, offset: i64, size: i64, buffer: rawptr) -> i64 ---;
+ @(link_name="OSInitialiseAPI") os_initialise_api :: proc() -> int ---;
+ @(link_name="OSTerminateProcess") os_terminate_process :: proc(handle: Handle) ---;
+ @(link_name="realloc") os_heap_reallocate :: proc(address: rawptr, size: int) -> rawptr ---;
+}
+
+stdin := cast(Handle) -1; // Not implemented
+stdout := cast(Handle) 0;
+stderr := cast(Handle) 0;
+
+current_thread_id :: proc() -> int {
+ // Not implemented
+ return int(-1);
+}
+
+heap_alloc :: proc(size: int) -> rawptr {
+ return os_heap_allocate(size, true);
+}
+
+heap_free :: proc(address: rawptr) {
+ os_heap_free(address);
+}
+
+heap_resize :: proc(address: rawptr, new_size: int) -> rawptr {
+ return os_heap_reallocate(address, new_size);
+}
+
+open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errno) {
+ information := new(OS_Node_Information);
+ error := os_open_node(&path[0], len(path), cast(u64) mode, information);
+ if (error < -1) { return 0,1; }
+ information.position = 0;
+ if (mode&O_TRUNC==O_TRUNC) {
+ error := os_resize_file(information.handle, 0);
+ if (error < -1) { return 0,1; }
+ }
+ return cast(Handle) cast(uintptr) information,0;
+}
+
+close :: proc(fd: Handle) {
+ information := cast(^OS_Node_Information) cast(uintptr) fd;
+ os_close_handle(information.handle);
+ free(information);
+}
+
+file_size :: proc(fd: Handle) -> (i64, Errno) {
+ // Not (properly) implemented
+ information := cast(^OS_Node_Information) cast(uintptr) fd;
+ return information.size,0;
+}
+
+write :: proc(fd: Handle, data: []u8) -> (int, Errno) {
+ if (fd == 0) {
+ os_print_direct(&data[0], len(data));
+ return len(data), 0;
+ } else if (fd == 1) {
+ assert(false);
+ return 0, 1;
+ } else {
+ information := cast(^OS_Node_Information) cast(uintptr) fd;
+ count := os_write_file_sync(information.handle, information.position, cast(i64) len(data), cast(rawptr) &data[0]);
+ if (count < 0) { return 0, 1; }
+ information.position += count;
+ return cast(int) count, 0;
+ }
+}
+
+read :: proc(fd: Handle, data: []u8) -> (int, Errno) {
+ if (fd == 0 || fd == 1) {
+ assert(false);
+ return 0, 1;
+ } else {
+ information := cast(^OS_Node_Information) cast(uintptr) fd;
+ count := os_read_file_sync(information.handle, information.position, cast(i64) len(data), cast(rawptr) &data[0]);
+ if (count < 0) { return 0, 1; }
+ information.position += count;
+ return cast(int) count, 0;
+ }
+}
+
+os_terminate_this_process :: proc() {
+ os_terminate_process(0x1001);
+}
diff --git a/core/sys/essence_linker_userland64.ld b/core/sys/essence_linker_userland64.ld
new file mode 100644
index 000000000..5f6d92791
--- /dev/null
+++ b/core/sys/essence_linker_userland64.ld
@@ -0,0 +1,24 @@
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x100000;
+ .text BLOCK(4K) : ALIGN(4K)
+ {
+ *(.text)
+ }
+ .rodata BLOCK(4K) : ALIGN(4K)
+ {
+ *(.rodata)
+ }
+ .data BLOCK(4K) : ALIGN(4K)
+ {
+ *(.data)
+ }
+
+ .bss BLOCK(4K) : ALIGN(4K)
+ {
+ *(COMMON)
+ *(.bss)
+ }
+}