diff --git a/.gitignore b/.gitignore index 36578e6..34b4b2c 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ colors.dtp apps/board_hello apps/board_cycle apps/readdir +apps/loader +apps/asciivju +apps/justawindow diff --git a/apps/justawindow.asm b/apps/justawindow.asm new file mode 100644 index 0000000..894ec57 --- /dev/null +++ b/apps/justawindow.asm @@ -0,0 +1,58 @@ +use32 + org 0 + db 'MENUET01' + dd 1, start, i_end, e_end, e_end, 0, 0 + +__DEBUG__ = 1 +__DEBUG_LEVEL__ = 1 + +include 'proc32.inc' +include 'macros.inc' +include 'debug-fdo.inc' + +EFLAGS.ID = 1 SHL 21 + +start: + pushfd + btr dword[esp], BSF EFLAGS.ID + popfd + + mcall 68, 11 + +redraw: + mcall 12, 1 + mcall 0, <100,200>, <100,100>, 0x34ff8888, , window_title + mcall 12, 2 + +still: + mcall 10 + dec eax + jz redraw + dec eax + jz key +button: + mcall 17 + shr eax, 8 + + cmp eax, 1 + jz exit + + jmp still + +key: + mcall 2 + cmp ah, 0x09 ; TAB key + + jmp still + +exit: + mcall -1 + +;include_debug_strings + +window_title db 'just a window',0 + +i_end: + +rb 0x100 ; stack +e_end: diff --git a/apps/loader.asm b/apps/loader.asm new file mode 100644 index 0000000..065ecf8 --- /dev/null +++ b/apps/loader.asm @@ -0,0 +1,82 @@ +use32 + org 0x1000000 + db 'MENUET01' + dd 1, start, i_end, e_end, e_end, 0, 0 + +__DEBUG__ = 1 +__DEBUG_LEVEL__ = 1 + +include 'proc32.inc' +include 'macros.inc' +include 'debug-fdo.inc' + +EFLAGS.ID = 1 SHL 21 + +start: + pushfd + btr dword[esp], BSF EFLAGS.ID + popfd + + mcall 68, 11 + + mcall 12, 1 + mcall 0, <50,200>, <50,100>, 0x3488ffff, , window_title + mcall 12, 2 + + mcall 15, 1, 2, 2 + mcall 15, 4, 1 + mcall 15, 6 + mov ecx, 0 + mov edx, 0xff + mov [eax+0], cl + mov [eax+1], cl + mov [eax+2], cl + mov [eax+3], dl + mov [eax+4], dl + mov [eax+5], dl + mov [eax+6], dl + mov [eax+7], dl + mov [eax+8], dl + mov [eax+9], cl + mov [eax+10], cl + mov [eax+11], cl + mcall 15, 7, eax + mcall 15, 3 + +redraw: + mcall 12, 1 + mcall 0, <50,200>, <50,100>, 0x3488ffff, , window_title + mcall 12, 2 + +still: + mcall 10 + dec eax + jz redraw + dec eax + jz key +button: + mcall 17 + shr eax, 8 + + cmp eax, 1 + jz exit + + jmp still + +key: + mcall 2 + cmp ah, 0x09 ; TAB key + + jmp still + +exit: + mcall -1 + +;include_debug_strings + +window_title db 'loader',0 + +i_end: + +rb 0x100 ; stack +e_end: diff --git a/apps/makefile b/apps/makefile index 95cb1aa..fd51837 100644 --- a/apps/makefile +++ b/apps/makefile @@ -11,7 +11,7 @@ else $(error your OS is not supported) endif -all: board_hello board_cycle readdir +all: board_hello board_cycle readdir loader justawindow %: %.asm $(FASM) $< $@ @@ -20,4 +20,4 @@ all: board_hello board_cycle readdir .PHONY: all clean clean: - rm -f board_hello board_cycle readdir + rm -f board_hello board_cycle readdir loader justawindow diff --git a/shell.c b/shell.c index 4faade0..f996515 100644 --- a/shell.c +++ b/shell.c @@ -641,7 +641,6 @@ cmd_ramdisk_init(struct shell_ctx *ctx, int argc, char **argv) { static void cmd_disk_add(struct shell_ctx *ctx, int argc, char **argv) { - (void)ctx; const char *usage = \ "usage: disk_add [option]...\n" " absolute or relative path\n" @@ -654,13 +653,13 @@ cmd_disk_add(struct shell_ctx *ctx, int argc, char **argv) { size_t cache_size = 0; int adjust_cache_size = 0; int opt; - optind = 1; - const char *file_name = argv[optind++]; - const char *disk_name = argv[optind++]; - while ((opt = getopt(argc, argv, "c:")) != -1) { + optparse_init(&ctx->opts, argv); + const char *file_name = optparse_arg(&ctx->opts); + const char *disk_name = optparse_arg(&ctx->opts); + while ((opt = optparse(&ctx->opts, "c:")) != -1) { switch (opt) { case 'c': - cache_size = strtoul(optarg, NULL, 0); + cache_size = strtoul(ctx->opts.optarg, NULL, 0); adjust_cache_size = 1; break; default: @@ -1056,11 +1055,12 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { fputs(usage, ctx->fout); return; } + int lbheld = 0, mbheld = 0, rbheld = 0, xabs = 0, yabs = 0; int32_t xmoving = 0, ymoving = 0, hscroll = 0, vscroll = 0; int opt; - optind = 1; - while ((opt = getopt(argc, argv, "lmrx:y:h:v:")) != -1) { + optparse_init(&ctx->opts, argv); + while ((opt = optparse(&ctx->opts, "lmrx:y:h:v:")) != -1) { switch (opt) { case 'l': lbheld = 1; @@ -1072,15 +1072,15 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { rbheld = 1; break; case 'x': - switch (*optarg++) { + switch (*ctx->opts.optarg++) { case '=': xabs = 1; __attribute__ ((fallthrough)); case '+': - xmoving = strtol(optarg, NULL, 0); + xmoving = strtol(ctx->opts.optarg, NULL, 0); break; case '-': - xmoving = -strtol(optarg, NULL, 0); + xmoving = -strtol(ctx->opts.optarg, NULL, 0); break; default: fputs(usage, ctx->fout); @@ -1088,15 +1088,15 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { } break; case 'y': - switch (*optarg++) { + switch (*ctx->opts.optarg++) { case '=': yabs = 1; __attribute__ ((fallthrough)); case '+': - ymoving = strtol(optarg, NULL, 0); + ymoving = strtol(ctx->opts.optarg, NULL, 0); break; case '-': - ymoving = -strtol(optarg, NULL, 0); + ymoving = -strtol(ctx->opts.optarg, NULL, 0); break; default: fputs(usage, ctx->fout); @@ -1104,18 +1104,18 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { } break; case 'h': - if ((optarg[0] != '+') && (optarg[0] != '-')) { + if ((ctx->opts.optarg[0] != '+') && (ctx->opts.optarg[0] != '-')) { fputs(usage, ctx->fout); return; } - hscroll = strtol(optarg, NULL, 0); + hscroll = strtol(ctx->opts.optarg, NULL, 0); break; case 'v': - if ((optarg[0] != '+') && (optarg[0] != '-')) { + if ((ctx->opts.optarg[0] != '+') && (ctx->opts.optarg[0] != '-')) { fputs(usage, ctx->fout); return; } - vscroll = strtol(optarg, NULL, 0); + vscroll = strtol(ctx->opts.optarg, NULL, 0); break; default: fputs(usage, ctx->fout); @@ -2438,28 +2438,28 @@ cmd_ls(struct shell_ctx *ctx, int argc, char **argv, const char *usage, return; } int opt; - optind = 1; const char *optstring = (f70or80 == F70) ? "f:c:e:" : "f:c:e:p:"; const char *path = "."; uint32_t readdir_enc = DEFAULT_READDIR_ENCODING; uint32_t path_enc = DEFAULT_PATH_ENCODING; uint32_t from_idx = 0, count = MAX_DIRENTS_TO_READ; - if (argc > 1 && *argv[optind] != '-') { - path = argv[optind++]; + optparse_init(&ctx->opts, argv); + if (argc > 1 && argv[1][0] != '-') { + path = optparse_arg(&ctx->opts); } - while ((opt = getopt(argc, argv, optstring)) != -1) { + while ((opt = optparse(&ctx->opts, optstring)) != -1) { switch (opt) { case 'f': - from_idx = strtoul(optarg, NULL, 0); + from_idx = strtoul(ctx->opts.optarg, NULL, 0); break; case 'c': - count = strtoul(optarg, NULL, 0); + count = strtoul(ctx->opts.optarg, NULL, 0); break; case 'e': - readdir_enc = parse_encoding(optarg); + readdir_enc = parse_encoding(ctx->opts.optarg); break; case 'p': - path_enc = parse_encoding(optarg); + path_enc = parse_encoding(ctx->opts.optarg); break; default: fputs(usage, ctx->fout); @@ -2525,6 +2525,7 @@ cmd_stat(struct shell_ctx *ctx, int argc, char **argv, f70or80_t f70or80) { fputs(usage, ctx->fout); return; } + optparse_init(&ctx->opts, argv); bool force_ctime = false, force_mtime = false, force_atime = false; f7080s5arg_t fX0 = {.sf = 5, .flags = 0}; f7080ret_t r; @@ -2532,10 +2533,10 @@ cmd_stat(struct shell_ctx *ctx, int argc, char **argv, f70or80_t f70or80) { fX0.buf = &file; if (f70or80 == F70) { fX0.u.f70.zero = 0; - fX0.u.f70.path = argv[1]; + fX0.u.f70.path = optparse_arg(&ctx->opts); } else { fX0.u.f80.path_encoding = DEFAULT_PATH_ENCODING; - fX0.u.f80.path = argv[1]; + fX0.u.f80.path = optparse_arg(&ctx->opts); } COVERAGE_ON(); umka_sys_lfn(&fX0, &r, f70or80); @@ -2551,8 +2552,7 @@ cmd_stat(struct shell_ctx *ctx, int argc, char **argv, f70or80_t f70or80) { } int opt; - optind = 2; // skip command and file - while ((opt = getopt(argc, argv, "cma")) != -1) { + while ((opt = optparse(&ctx->opts, "cma")) != -1) { switch (opt) { case 'c': force_ctime = true; @@ -3735,11 +3735,11 @@ cmd_board_get(struct shell_ctx *ctx, int argc, char **argv) { fputs(usage, ctx->fout); return; } + optparse_init(&ctx->opts, argv); int line = 0; int force_newline = 0; int opt; - optind = 1; - while ((opt = getopt(argc, argv, "ln")) != -1) { + while ((opt = optparse(&ctx->opts, "ln")) != -1) { switch (opt) { case 'l': line = 1; diff --git a/shell.h b/shell.h index ffd3f20..7b5139e 100644 --- a/shell.h +++ b/shell.h @@ -14,6 +14,7 @@ #include #include "umka.h" #include "umkaio.h" +#include "optparse.h" enum shell_var_type { SHELL_VAR_SINT, @@ -44,7 +45,7 @@ struct shell_ctx { const int *running; pthread_cond_t cmd_done; pthread_mutex_t cmd_mutex; - + struct optparse opts; }; struct shell_ctx * diff --git a/umka_os.c b/umka_os.c index 8b00d54..e528fe8 100644 --- a/umka_os.c +++ b/umka_os.c @@ -11,7 +11,6 @@ #include #include #include -#include #define __USE_GNU #include #include @@ -20,14 +19,9 @@ #include #define __USE_MISC #include -#include -#include #include #include #include -#define __USE_GNU -#include -#include #include #include "umka.h" #include "umkart.h" @@ -40,6 +34,8 @@ #define HIST_FILE_BASENAME ".umka_os.history" #define THREAD_STACK_SIZE 0x100000 +#define APP_MAX_MEM_SIZE 0x1000000 +#define UMKA_LDR_BASE ((void*)0x1000000) struct umka_os_ctx { struct umka_ctx *umka; @@ -117,7 +113,7 @@ dump_procs() { appdata_t *p_begin = kos_scheduler_current[i]; appdata_t *p = p_begin; do { - printf(" %p", (void*)p); + fprintf(stderr, " %p", (void*)p); p = p->in_schedule.next; } while (p != p_begin); putchar('\n'); @@ -125,20 +121,17 @@ dump_procs() { } int -load_app_host(const char *fname, void *base) { +load_app_host(const char *fname, struct app_hdr *app) { FILE *f = fopen(fname, "r"); if (!f) { - perror("Can't open app file"); + fprintf(stderr, "[!] can't open app file: %s", fname); exit(1); } - fread(base, 1, 0x100000, f); + fread(app, 1, APP_MAX_MEM_SIZE, f); fclose(f); - for (size_t i = 0; i < 0x64; i++) { - fprintf(stderr, "%2.2hx ", ((uint8_t*)base)[i]); - } - fprintf(stderr, "\n"); - + kos_thread_t start = (kos_thread_t)(app->menuet.start); + thread_start(0, start, THREAD_STACK_SIZE); return 0; } @@ -177,13 +170,13 @@ hw_int(int signo) { umka_sti(); } -int +static void * umka_display(void *arg) { (void)arg; if(SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Failed to initialize the SDL2 library\n"); - return -1; + return NULL; } char title[64]; @@ -199,7 +192,7 @@ umka_display(void *arg) { if(!window) { fprintf(stderr, "Failed to create window\n"); - return -1; + return NULL; } SDL_Surface *window_surface = SDL_GetWindowSurface(window); @@ -207,7 +200,7 @@ umka_display(void *arg) { if(!window_surface) { fprintf(stderr, "Failed to get the surface from the window\n"); - return -1; + return NULL; } void (*copy_display)(void *); @@ -229,7 +222,7 @@ umka_display(void *arg) { SDL_UpdateWindowSurface(window); sleep(1); } - return 0; + return NULL; } uint32_t @@ -249,7 +242,7 @@ umka_thread_cmd_runner() { } } -static int +static void * umka_monitor(void *arg) { (void)arg; run_test(os->shell); @@ -371,7 +364,7 @@ main(int argc, char *argv[]) { sa.sa_sigaction = handle_i40; sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO | SA_RESTART; + sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESTART; if (sigaction(SIGSEGV, &sa, NULL) == -1) { fprintf(stderr, "Can't install 0x40 interrupt handler!\n"); @@ -387,12 +380,20 @@ main(int argc, char *argv[]) { return 1; } - struct app_hdr *app = mmap(KOS_APP_BASE, 16*0x100000, PROT_READ | PROT_WRITE - | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (app == MAP_FAILED) { - perror("mmap failed"); + struct app_hdr *app_std = mmap(KOS_APP_BASE, APP_MAX_MEM_SIZE, PROT_READ + | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (app_std == MAP_FAILED) { + perror("mmap app_std failed"); exit(1); } + memset((void*)app_std, 0, APP_MAX_MEM_SIZE); + struct app_hdr *app_ldr = mmap(UMKA_LDR_BASE, APP_MAX_MEM_SIZE, PROT_READ + | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (app_ldr == MAP_FAILED) { + perror("mmap app_ldr failed"); + exit(1); + } + memset((void*)app_ldr, 0, APP_MAX_MEM_SIZE); kos_boot.bpp = UMKA_DEFAULT_DISPLAY_BPP; kos_boot.x_res = UMKA_DEFAULT_DISPLAY_WIDTH; @@ -403,8 +404,6 @@ main(int argc, char *argv[]) { os->shell->fin = fin; umka_stack_init(); -// load_app_host("../apps/board_cycle", app); - load_app_host("../apps/readdir", app); // load_app("/rd/1/loader"); struct vnet *vnet = vnet_init(VNET_TAP); @@ -452,17 +451,18 @@ main(int argc, char *argv[]) { thread_start(1, umka_thread_board, THREAD_STACK_SIZE); thread_start(1, umka_thread_cmd_runner, THREAD_STACK_SIZE); - kos_thread_t start = (kos_thread_t)(KOS_APP_BASE + app->menuet.start); - thread_start(0, start, THREAD_STACK_SIZE); + load_app_host("../apps/loader", UMKA_LDR_BASE); +// load_app_host("../apps/justawindow", KOS_APP_BASE); + load_app_host("../apps/asciivju", KOS_APP_BASE); dump_procs(); - thrd_t thrd_monitor; - thrd_create(&thrd_monitor, umka_monitor, NULL); + pthread_t thread_monitor; + pthread_create(&thread_monitor, NULL, umka_monitor, NULL); if (show_display) { - thrd_t thrd_display; - thrd_create(&thrd_display, umka_display, NULL); + pthread_t thread_display; + pthread_create(&thread_display, NULL, umka_display, NULL); } setitimer(ITIMER_REAL, &timeout, NULL); diff --git a/umka_os.us b/umka_os.us index 9df1605..1ae6838 100644 --- a/umka_os.us +++ b/umka_os.us @@ -1,4 +1,4 @@ -umka_set_boot_params --bpp 32 +umka_set_boot_params --bpp 32 --x_res 800 --y_res 600 umka_boot ramdisk_init ../img/kolibri.raw set_skin /sys/DEFAULT.SKN diff --git a/umka_shell.c b/umka_shell.c index 27d7b11..e439646 100644 --- a/umka_shell.c +++ b/umka_shell.c @@ -83,8 +83,8 @@ main(int argc, char **argv) { int reproducible = 0; struct optparse options; - int opt; optparse_init(&options, argv); + int opt; while ((opt = optparse(&options, "i:o:rc")) != -1) { switch (opt) { diff --git a/vnet.c b/vnet.c index 6ca6882..5a341e3 100644 --- a/vnet.c +++ b/vnet.c @@ -53,7 +53,7 @@ vnet_input(void *udata) { if (plen == -1) { plen = 0; // we have just allocated a buffer, so we have to submit it } -//if (plen != 0) + fprintf(stderr, "[vnet] read %i bytes\n", plen); for (int i = 0; i < plen; i++) { fprintf(stderr, " %2.2x", buf->data[i]); @@ -85,7 +85,6 @@ vnet_input_monitor(struct vnet *net) { struct vnet * vnet_init(enum vnet_type type) { -// printf("vnet_init\n"); struct vnet *vnet; switch (type) { case VNET_FILE: