summaryrefslogtreecommitdiff
path: root/src/user
diff options
context:
space:
mode:
Diffstat (limited to 'src/user')
-rw-r--r--src/user/dirinfo/dirinfo.c2
-rw-r--r--src/user/fileman/fileman.c130
-rw-r--r--src/user/highway/line.c6
-rw-r--r--src/user/highway/main.c2
-rw-r--r--src/user/include/knob/block.h3
-rw-r--r--src/user/include/knob/file.h5
-rw-r--r--src/user/include/knob/quit.h7
-rw-r--r--src/user/include/knob/user.h3
-rw-r--r--src/user/include/pland/pcrt.h16
-rw-r--r--src/user/include/pland/syscall.h182
-rw-r--r--src/user/knob/block.c9
-rw-r--r--src/user/knob/entry.asm23
-rw-r--r--src/user/knob/file.c21
-rw-r--r--src/user/knob/quit.c8
-rw-r--r--src/user/knob/user.c13
-rw-r--r--src/user/runtimes/asm/elf.ld (renamed from src/user/elf.ld)0
-rw-r--r--src/user/runtimes/c/elf.ld22
-rw-r--r--src/user/runtimes/c/entry.asm42
18 files changed, 408 insertions, 86 deletions
diff --git a/src/user/dirinfo/dirinfo.c b/src/user/dirinfo/dirinfo.c
index 7484eb8..21afcc7 100644
--- a/src/user/dirinfo/dirinfo.c
+++ b/src/user/dirinfo/dirinfo.c
@@ -13,7 +13,7 @@ void main(const char *arg) {
tell_user_sz(*arg ? arg : "drive root");
tell_user_sz("\n");
- _dir_info_entry infos[MAX_DIR_ENTRIES];
+ _dir_info_entry_t infos[MAX_DIR_ENTRIES];
uint8_t count = _enumerate_dir(dn, path, infos, MAX_DIR_ENTRIES);
tell_user_sz(
count == MAX_DIR_ENTRIES
diff --git a/src/user/fileman/fileman.c b/src/user/fileman/fileman.c
new file mode 100644
index 0000000..0b28d1d
--- /dev/null
+++ b/src/user/fileman/fileman.c
@@ -0,0 +1,130 @@
+#include <pland/syscall.h>
+#include <knob/block.h>
+#include <knob/file.h>
+#include <knob/heap.h>
+#include <knob/task.h>
+
+char path_sz[1024] = "";
+uint32_t path_len = 0;
+
+_dir_info_entry_t *dir_info;
+uint32_t dir_info_len;
+
+uint32_t scroll;
+uint32_t selected;
+#define MAX_PER_SCREEN 18
+
+void paint_screen() {
+ _clear_screen();
+
+ _set_color(0x70);
+ _print_at(0, 0, path_sz);
+ _log_string("/");
+ _set_color(0x07);
+
+ for (uint32_t i = scroll, row = 2; (i < dir_info_len) && (row < MAX_PER_SCREEN + 2); ++i, ++row) {
+ if (i == selected)
+ _set_color(0x17);
+ _print_at(row, 0, dir_info[i].name);
+ if (dir_info[i].is_dir)
+ _log_string("/");
+ if (i == selected)
+ _set_color(0x07);
+ }
+
+ _print_at(21, 0, "keybindings:\n"
+ "UP, DOWN, PAGE UP, PAGE DOWN, HOME, END: move selection\n"
+ "ENTER: enter selected directory, run selected program\n"
+ "ESC: go up a directory Q: quit");
+}
+
+void load_dir() {
+ free_block(dir_info);
+ dir_info = get_directory_info(path_sz, &dir_info_len);
+ scroll = 0;
+ selected = 0;
+}
+
+void main(const char *sz) {
+ path_len = strcpy(path_sz, sz);
+ dir_info = get_directory_info(sz, &dir_info_len);
+
+ paint_screen();
+
+ while (true) {
+ _key_code_t key;
+ switch (key = _get_key()) {
+ case 0:
+ _yield_task();
+ continue;
+ case '\n':
+ {
+ uint32_t old_len = path_len;
+ if (path_len)
+ path_sz[path_len++] = '/';
+ path_len += strcpy(path_sz + path_len, dir_info[selected].name);
+ if (dir_info[selected].is_dir)
+ load_dir();
+ else {
+ try_run_command_blocking(path_sz);
+ //TODO: handle error
+ path_sz[old_len] = '\0';
+ path_len = old_len;
+ }
+ }
+ break;
+ case _KEY_ESC:
+ {
+ char *cutoff = path_sz;
+ for (char *i = path_sz + path_len - 1; i >= path_sz; --i)
+ if (*i == '/') {
+ cutoff = i;
+ break;
+ }
+ *cutoff = '\0';
+ path_len = cutoff - path_sz;
+ load_dir();
+ }
+ break;
+ case _KEY_HOME:
+ scroll = 0;
+ selected = 0;
+ break;
+ case _KEY_END:
+ selected = dir_info_len - 1;
+ scroll = dir_info_len >= MAX_PER_SCREEN
+ ? dir_info_len - MAX_PER_SCREEN : 0;
+ break;
+ case _KEY_UP:
+ if (!selected)
+ continue;
+ if (--selected < scroll)
+ scroll = selected;
+ break;
+ case _KEY_DOWN:
+ if (selected == dir_info_len - 1)
+ continue;
+ if (++selected >= scroll + MAX_PER_SCREEN)
+ ++scroll;
+ break;
+ case _KEY_PUP:
+ selected = selected >= MAX_PER_SCREEN
+ ? selected - MAX_PER_SCREEN : 0;
+ scroll = scroll >= MAX_PER_SCREEN
+ ? scroll - MAX_PER_SCREEN : 0;
+ break;
+ case _KEY_PDOWN:
+ if ((selected += MAX_PER_SCREEN) >= dir_info_len)
+ selected = dir_info_len - 1;
+ if ((scroll += MAX_PER_SCREEN) > selected)
+ scroll = selected;
+ break;
+ case 'q':
+ _clear_screen();
+ return;
+ default:
+ continue;
+ }
+ paint_screen();
+ }
+} \ No newline at end of file
diff --git a/src/user/highway/line.c b/src/user/highway/line.c
index ca38c9b..40dccfa 100644
--- a/src/user/highway/line.c
+++ b/src/user/highway/line.c
@@ -1,5 +1,5 @@
+#include <pland/pcrt.h>
#include <knob/block.h>
-#include <knob/quit.h>
#include <knob/task.h>
#include <knob/user.h>
#include "cmds.h"
@@ -68,7 +68,7 @@ void run_line(const char *original_line) {
else if (blockequ(line, "vars", space - line))
dump_vars();
else if (blockequ(line, "quit", space - line))
- quit(space + 1);
+ __pcrt_quit();
else if (blockequ(line, "help", space - line))
tell_user_sz("Highway is a command shell for Portland OS. It includes variables and a couple\n"
"of pseudo-commands. Variables are addressed by surrounding with \"$\". The\n"
@@ -78,7 +78,7 @@ void run_line(const char *original_line) {
" echo STRING print STRING\n"
" vars dump variables\n"
" quit exit highway\n"
- " help show this\n\n");
+ " help show this\n");
else if (!try_run_command_blocking(line)) {
struct no_null_sn arg = {
.data = "_path",
diff --git a/src/user/highway/main.c b/src/user/highway/main.c
index 1934920..61f736e 100644
--- a/src/user/highway/main.c
+++ b/src/user/highway/main.c
@@ -9,7 +9,7 @@ void main(const char *arg) {
yield_task();
tell_user_sz("Portland Highway\nType \"help\" for help.\n");
while (1) {
- tell_user_sz("> ");
+ tell_user_sz("\n> ");
ask_user_line_sz(cmd_buf, 127);
run_line(cmd_buf);
}
diff --git a/src/user/include/knob/block.h b/src/user/include/knob/block.h
index 4625577..43137e1 100644
--- a/src/user/include/knob/block.h
+++ b/src/user/include/knob/block.h
@@ -7,4 +7,7 @@
void blockcpy(void *to, const void *from, uint32_t size);
bool blockequ(const void *a, const void *b, uint32_t size) __attribute__ ((__pure__));
+//returns length without null-terminator
+uint32_t strcpy(char *to, const char *from);
+
#endif \ No newline at end of file
diff --git a/src/user/include/knob/file.h b/src/user/include/knob/file.h
index a0d084f..8862098 100644
--- a/src/user/include/knob/file.h
+++ b/src/user/include/knob/file.h
@@ -2,6 +2,7 @@
#define KNOB_FILE_H
#include <stdint.h>
+#include <pland/syscall.h>
struct file;
@@ -9,7 +10,6 @@ const char *remove_prefix(const char *path, uint8_t *dn_out);
struct file *open_file(const char *path);
void close_file(struct file *f);
-void _close_all_files();
uint32_t read_from_file(struct file *f, uint32_t max, void *buf);
//return value and max_length don't include null terminator
@@ -19,4 +19,7 @@ int32_t seek_file_by(struct file *f, int32_t by);
uint32_t file_size(struct file *f) __attribute__ ((pure));
+//return value must be manually freed, unless it is a null pointer
+_dir_info_entry_t *get_directory_info(const char *path, uint32_t *count_out);
+
#endif \ No newline at end of file
diff --git a/src/user/include/knob/quit.h b/src/user/include/knob/quit.h
deleted file mode 100644
index 7b10d09..0000000
--- a/src/user/include/knob/quit.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef KNOB_QUIT_H
-#define KNOB_QUIT_H
-
-void on_quit(void (*run_f)());
-void quit() __attribute__ ((noreturn));
-
-#endif \ No newline at end of file
diff --git a/src/user/include/knob/user.h b/src/user/include/knob/user.h
index 479a731..cd7676c 100644
--- a/src/user/include/knob/user.h
+++ b/src/user/include/knob/user.h
@@ -2,6 +2,9 @@
#define KNOB_USER_H
#include <stdint.h>
+#include <pland/syscall.h>
+
+char key_to_char(_key_code_t key) __attribute__ ((const));
void tell_user_sz(const char *sz);
diff --git a/src/user/include/pland/pcrt.h b/src/user/include/pland/pcrt.h
new file mode 100644
index 0000000..07ad453
--- /dev/null
+++ b/src/user/include/pland/pcrt.h
@@ -0,0 +1,16 @@
+#ifndef PLAND_PCRT_H
+#define PLAND_PCRT_H
+
+#define BEFORE_MAIN(f) \
+ __attribute__ ((section (".__pcrt_before_main"))) \
+ __attribute__ ((unused)) \
+ void (*const __pcrt_bm_##f)() = &f;
+
+#define BEFORE_QUIT(f) \
+ __attribute__ ((section (".__pcrt_before_quit"))) \
+ __attribute__ ((unused)) \
+ void (*const __pcrt_bq_##f)() = &f;
+
+void __pcrt_quit() __attribute__ ((noreturn));
+
+#endif \ No newline at end of file
diff --git a/src/user/include/pland/syscall.h b/src/user/include/pland/syscall.h
index e16a7fb..331002e 100644
--- a/src/user/include/pland/syscall.h
+++ b/src/user/include/pland/syscall.h
@@ -7,14 +7,9 @@
typedef uint32_t _file_handle_t;
typedef uint32_t _task_handle_t;
typedef uint32_t _drive_number_t;
-typedef uint32_t _pages_t;
typedef uint32_t _process_handle_t;
typedef enum {
- _KEY_BACKSPACE = '\b',
- _KEY_RETURN = '\n',
- //etc.
-
_KEY_LSHIFT = 0x00000100,
_KEY_RSHIFT = 0x00000200,
_KEY_CAPS = 0x00000400,
@@ -33,8 +28,103 @@ typedef enum {
_KEY_ALT = 0x0000c000,
_KEY_CTRL = 0x00030000,
_KEY_META = 0x000c0000,
+
+ _KEY_BEGIN_CAPS = 0x80,
+ _KEY_BEGIN_INSERT,
+ _KEY_BEGIN_NUM,
+ _KEY_BEGIN_SCROLL,
+ _KEY_BEGIN_LSHIFT,
+ _KEY_BEGIN_RSHIFT,
+ _KEY_BEGIN_LALT,
+ _KEY_BEGIN_RALT,
+ _KEY_BEGIN_LCTRL,
+ _KEY_BEGIN_RCTRL,
+ _KEY_BEGIN_LMETA,
+ _KEY_BEGIN_RMETA,
+ /* 0x8c - 0x97 reserved */
+ /* 0x98 - 0x9f unassigned */
+ _KEY_F1 = 0xa0,
+ _KEY_F2,
+ _KEY_F3,
+ _KEY_F4,
+ _KEY_F5,
+ _KEY_F6,
+ _KEY_F7,
+ _KEY_F8,
+ _KEY_F9,
+ _KEY_F10,
+ _KEY_F11,
+ _KEY_F12,
+ /* 0xac - 0xaf unassigned */
+ _KEY_NUM0 = 0xb0,
+ _KEY_NUM1,
+ _KEY_NUM2,
+ _KEY_NUM3,
+ _KEY_NUM4,
+ _KEY_NUM5,
+ _KEY_NUM6,
+ _KEY_NUM7,
+ _KEY_NUM8,
+ _KEY_NUM9,
+ _KEY_NTIMES,
+ _KEY_NPLUS,
+ _KEY_NENTER,
+ _KEY_NMINUS,
+ _KEY_NDOT,
+ _KEY_NSLASH,
+ /* 0xc0 unassigned */
+ _KEY_DELETE,
+ _KEY_HOME,
+ _KEY_END,
+ _KEY_PUP,
+ _KEY_PDOWN,
+ _KEY_UP,
+ _KEY_DOWN,
+ _KEY_LEFT,
+ _KEY_RIGHT,
+ _KEY_ESC,
+ _KEY_MENU,
+ _KEY_PAUSE,
+ _KEY_PRSCR,
+ /* 0xce - 0xef unassigned */
} _key_code_t;
+typedef enum {
+ _COLOR_FG_BLACK = 0x00,
+ _COLOR_FG_BLUE = 0x01,
+ _COLOR_FG_GREEN = 0x02,
+ _COLOR_FG_CYAN = 0x03,
+ _COLOR_FG_RED = 0x04,
+ _COLOR_FG_MAGENTA = 0x05,
+ _COLOR_FG_BROWN = 0x06,
+ _COLOR_FG_LGRAY = 0x07,
+
+ _COLOR_FG_DGRAY = 0x08,
+ _COLOR_FG_LBLUE = 0x09,
+ _COLOR_FG_LGREEN = 0x0a,
+ _COLOR_FG_LCYAN = 0x0b,
+ _COLOR_FG_LRED = 0x0c,
+ _COLOR_FG_PINK = 0x0d,
+ _COLOR_FG_YELLOW = 0x0e,
+ _COLOR_FG_WHITE = 0x0f,
+
+ _COLOR_BG_BLACK = 0x00,
+ _COLOR_BG_BLUE = 0x10,
+ _COLOR_BG_GREEN = 0x20,
+ _COLOR_BG_CYAN = 0x30,
+ _COLOR_BG_RED = 0x40,
+ _COLOR_BG_MAGENTA = 0x50,
+ _COLOR_BG_BROWN = 0x60,
+ _COLOR_BG_LGRAY = 0x70
+} _vga_color_t;
+
+typedef struct __attribute__ ((packed)) {
+ char name[100];
+ uint32_t size;
+ bool is_dir;
+ uint8_t pad[23];
+} _dir_info_entry_t;
+
enum _scn {
_SCN_OPEN_FILE,
_SCN_CLOSE_FILE,
@@ -46,72 +136,74 @@ enum _scn {
_SCN_ALLOCATE_RAM,
_SCN_MEMORY_INFO,
_SCN_WAIT_FOR_TASK,
- _SCN_ENUMERATE_DIR
+ _SCN_ENUMERATE_DIR,
+ _SCN_PRINT_AT,
+ _SCN_COUNT_OF_DIR,
+ _SCN_CLEAR_SCREEN,
+ _SCN_SET_COLOR
};
-typedef struct {
- bool is_dir;
- char name[100];
- uint32_t size;
-} _dir_info_entry;
-
static inline uint32_t _sc0(enum _scn eax) {
- volatile uint32_t out;
- asm (
+ uint32_t out;
+ asm volatile (
"int $0x30"
: "=a" (out) : "a" (eax) : "ecx", "edx");
return out;
}
static inline uint32_t _sc1(enum _scn eax, uint32_t ebx) {
- volatile uint32_t out;
- asm (
+ uint32_t out;
+ asm volatile (
"int $0x30"
: "=a" (out) : "a" (eax), "b" (ebx) : "ecx", "edx");
return out;
}
static inline uint32_t _sc2(enum _scn eax, uint32_t ebx, uint32_t ecx) {
- volatile uint32_t out;
- asm (
+ uint32_t out;
+ uint32_t dummy;
+ asm volatile (
"int $0x30"
- : "=a" (out) : "a" (eax), "b" (ebx), "c" (ecx) : "edx");
+ : "=a" (out), "=c" (dummy) : "a" (eax), "b" (ebx), "c" (ecx) : "edx");
return out;
}
static inline uint32_t _sc3(enum _scn eax, uint32_t ebx, uint32_t ecx, uint32_t edx) {
- volatile uint32_t out;
- asm (
+ uint32_t out;
+ uint32_t dummy;
+ asm volatile (
"int $0x30"
- : "=a" (out) : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx));
+ : "=a" (out), "=c" (dummy), "=d" (dummy) : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx));
return out;
}
static inline uint32_t _sc4(enum _scn eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi) {
- volatile uint32_t out;
- asm (
+ uint32_t out;
+ uint32_t dummy;
+ asm volatile (
"int $0x30"
- : "=a" (out) : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi));
+ : "=a" (out), "=c" (dummy), "=d" (dummy) : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi));
return out;
}
static inline uint32_t _sc5(enum _scn eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi) {
- volatile uint32_t out;
- asm (
+ uint32_t out;
+ uint32_t dummy;
+ asm volatile (
"int $0x30"
- : "=a" (out) : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));
+ : "=a" (out), "=c" (dummy), "=d" (dummy) : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));
return out;
}
static inline void _yield_task() {
- asm (
+ asm volatile (
"int $0x39"
: : : "eax");
}
__attribute__ ((noreturn))
static inline void _exit_task() {
- asm (
+ asm volatile (
"int $0x38"
);
__builtin_unreachable();
@@ -145,27 +237,27 @@ static inline _key_code_t _get_key() {
return _sc0(_SCN_GET_KEY);
}
-static inline void *_allocate_ram(_pages_t pages) {
+static inline void *_allocate_ram(uint32_t pages) {
return (void *)_sc1(_SCN_ALLOCATE_RAM, pages);
}
-static inline _pages_t _kernel_dynamic_area_size() {
+static inline uint32_t _kernel_dynamic_area_size() {
return _sc1(_SCN_MEMORY_INFO, 0x0);
}
-static inline _pages_t _kernel_dynamic_area_left() {
+static inline uint32_t _kernel_dynamic_area_left() {
return _sc1(_SCN_MEMORY_INFO, 0x1);
}
-static inline _pages_t _total_userspace_size() {
+static inline uint32_t _total_userspace_size() {
return _sc1(_SCN_MEMORY_INFO, 0x2);
}
-static inline _pages_t _total_userspace_left() {
+static inline uint32_t _total_userspace_left() {
return _sc1(_SCN_MEMORY_INFO, 0x3);
}
-static inline _pages_t _this_process_memory_left() {
+static inline uint32_t _this_process_memory_left() {
return _sc1(_SCN_MEMORY_INFO, 0x4);
}
@@ -173,8 +265,24 @@ static inline void _wait_for_task(_process_handle_t handle) {
_sc1(_SCN_WAIT_FOR_TASK, handle);
}
-static inline uint32_t _enumerate_dir(_drive_number_t drive_number, const char *path, _dir_info_entry *buffer, uint32_t max_count) {
+static inline uint32_t _enumerate_dir(_drive_number_t drive_number, const char *path, _dir_info_entry_t *buffer, uint32_t max_count) {
return _sc4(_SCN_ENUMERATE_DIR, drive_number, (uint32_t)path, (uint32_t)buffer, max_count);
}
+static inline void _print_at(uint8_t row, uint8_t col, const char *sz) {
+ _sc2(_SCN_PRINT_AT, (row << 8) | col, (uint32_t)sz);
+}
+
+static inline uint32_t _count_of_dir(uint8_t drive_number, const char *path) {
+ return _sc2(_SCN_COUNT_OF_DIR, drive_number, (uint32_t)path);
+}
+
+static inline void _clear_screen() {
+ _sc0(_SCN_CLEAR_SCREEN);
+}
+
+static inline void _set_color(_vga_color_t color) {
+ _sc1(_SCN_SET_COLOR, color);
+}
+
#endif \ No newline at end of file
diff --git a/src/user/knob/block.c b/src/user/knob/block.c
index 7524ad3..4ec0564 100644
--- a/src/user/knob/block.c
+++ b/src/user/knob/block.c
@@ -14,4 +14,13 @@ bool blockequ(const void *a, const void *b, uint32_t size) {
if (*(uint8_t *)(a++) != *(uint8_t *)(b++))
return false;
return true;
+}
+
+//returns length without null-terminator
+uint32_t strcpy(char *to, const char *from) {
+ uint32_t i = 0;
+ do
+ to[i] = from[i];
+ while (from[i++]);
+ return i - 1;
} \ No newline at end of file
diff --git a/src/user/knob/entry.asm b/src/user/knob/entry.asm
deleted file mode 100644
index e9548d4..0000000
--- a/src/user/knob/entry.asm
+++ /dev/null
@@ -1,23 +0,0 @@
-bits 32
-
-global _entry
-
-extern main
-extern quit
-
-extern current_disk
-
-section .text
-_entry:
- mov esp, stack
- push edx
-
- ;TODO: determine current_disk
- ;any further needed initialization
-
- push quit
- jmp main
-
-section .stack nobits alloc noexec write align=16
-resb 4096
-stack: \ No newline at end of file
diff --git a/src/user/knob/file.c b/src/user/knob/file.c
index 23b7564..f1a039d 100644
--- a/src/user/knob/file.c
+++ b/src/user/knob/file.c
@@ -1,4 +1,5 @@
#include <pland/syscall.h>
+#include <pland/pcrt.h>
#include <knob/format.h>
#include <knob/heap.h>
#include <knob/env.h>
@@ -11,11 +12,13 @@ struct ofl_node {
static struct ofl_node *head_ofl_node = 0;
-void _close_all_files() {
+static void _close_all_files() {
for (struct ofl_node *i = head_ofl_node; i; i = i->next)
_close_file(i->handle);
}
+BEFORE_QUIT(_close_all_files)
+
struct file {
struct ofl_node *node;
_file_handle_t handle;
@@ -121,4 +124,20 @@ int32_t seek_file_by(struct file *f, int32_t by) {
__attribute__ ((pure))
uint32_t file_size(struct file *f) {
return f->length;
+}
+
+//return value must be manually freed, unless it is a null pointer
+_dir_info_entry_t *get_directory_info(const char *path, uint32_t *count_out) {
+ uint8_t dn;
+ path = remove_prefix(path, &dn);
+
+ uint32_t count = _count_of_dir(dn, path);
+ if (!count) {
+ *count_out = 0;
+ return 0;
+ }
+
+ _dir_info_entry_t *buffer = get_block(count * sizeof(_dir_info_entry_t));
+ *count_out = _enumerate_dir(dn, path, buffer, count);
+ return buffer;
} \ No newline at end of file
diff --git a/src/user/knob/quit.c b/src/user/knob/quit.c
deleted file mode 100644
index 98881b7..0000000
--- a/src/user/knob/quit.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <pland/syscall.h>
-#include <knob/file.h>
-
-__attribute__ ((noreturn))
-void quit() {
- _close_all_files();
- _exit_task();
-} \ No newline at end of file
diff --git a/src/user/knob/user.c b/src/user/knob/user.c
index b642f79..dfcb791 100644
--- a/src/user/knob/user.c
+++ b/src/user/knob/user.c
@@ -116,10 +116,8 @@ static const uint8_t shifted[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-static char get_key_char() {
- _key_code_t key;
- while (!(key = _get_key()))
- _yield_task();
+__attribute__ ((const))
+char key_to_char(_key_code_t key) {
return
key & _KEY_CAPS
? key & _KEY_SHIFT
@@ -130,6 +128,13 @@ static char get_key_char() {
: key & 0xff;
}
+static char get_key_char() {
+ _key_code_t key;
+ while (!(key = _get_key()))
+ _yield_task();
+ return key_to_char(key);
+}
+
void tell_user_sz(const char *sz) {
_log_string(sz);
}
diff --git a/src/user/elf.ld b/src/user/runtimes/asm/elf.ld
index aaef517..aaef517 100644
--- a/src/user/elf.ld
+++ b/src/user/runtimes/asm/elf.ld
diff --git a/src/user/runtimes/c/elf.ld b/src/user/runtimes/c/elf.ld
new file mode 100644
index 0000000..f321be2
--- /dev/null
+++ b/src/user/runtimes/c/elf.ld
@@ -0,0 +1,22 @@
+OUTPUT_FORMAT(elf32-i386)
+OUTPUT_ARCH(i386)
+ENTRY(__pcrt_entry)
+
+MEMORY {
+ kernel (!a) : ORIGIN = 0x00000000, LENGTH = 0x08000000
+ user (awx) : ORIGIN = 0x08000000, LENGTH = 0xf8000000
+}
+
+SECTIONS {
+ .__pcrt_before_main : {
+ __pcrt_before_main_start = .;
+ *(.__pcrt_before_main)
+ __pcrt_before_main_end = .;
+ }
+
+ .__pcrt_before_quit : {
+ __pcrt_before_quit_start = .;
+ *(.__pcrt_before_quit)
+ __pcrt_before_quit_end = .;
+ }
+} \ No newline at end of file
diff --git a/src/user/runtimes/c/entry.asm b/src/user/runtimes/c/entry.asm
new file mode 100644
index 0000000..bba8060
--- /dev/null
+++ b/src/user/runtimes/c/entry.asm
@@ -0,0 +1,42 @@
+bits 32
+
+global __pcrt_entry
+global __pcrt_quit
+
+extern main
+extern __pcrt_before_main_start
+extern __pcrt_before_main_end
+extern __pcrt_before_quit_start
+extern __pcrt_before_quit_end
+
+section .text
+__pcrt_entry:
+ mov esp, stack
+ push edx
+
+ mov ebx, __pcrt_before_main_start
+.before_main_loop:
+ cmp ebx, __pcrt_before_main_end
+ je .call_main
+ call dword [ebx]
+ add ebx, 4
+ jmp .before_main_loop
+
+.call_main:
+ call main
+
+__pcrt_quit:
+ mov ebx, __pcrt_before_quit_start
+.before_quit_loop:
+ cmp ebx, __pcrt_before_quit_end
+ je .end_task
+ call dword [ebx]
+ add ebx, 4
+ jmp .before_quit_loop
+
+.end_task:
+ int 0x38
+
+section .stack nobits alloc noexec write align=16
+resb 4096
+stack: \ No newline at end of file