diff options
| author | Nakst <djnakst2@gmail.com> | 2017-11-26 11:03:11 +0000 |
|---|---|---|
| committer | Nakst <djnakst2@gmail.com> | 2017-11-26 11:03:11 +0000 |
| commit | b0d3fbba4761aff3dfc3bcded3da7000699a7766 (patch) | |
| tree | 0e01e8d853324dad51addbd416c1fe8156c097a3 /core | |
| parent | adb6c7637e8748b19e550e45cba42d1155657249 (diff) | |
essence cross compile
Diffstat (limited to 'core')
| -rw-r--r-- | core/os.odin | 1 | ||||
| -rw-r--r-- | core/os_essence.odin | 115 | ||||
| -rw-r--r-- | core/sys/essence_linker_userland64.ld | 24 |
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) + } +} |