diff --git a/shell.c b/shell.c index 4aa2c3a..6b04653 100644 --- a/shell.c +++ b/shell.c @@ -54,6 +54,8 @@ enum { UMKA_CMD_NONE, UMKA_CMD_SET_MOUSE_DATA, + UMKA_CMD_WAIT_FOR_IDLE, + UMKA_CMD_SYS_CSLEEP, UMKA_CMD_SYS_PROCESS_INFO, UMKA_CMD_SYS_GET_MOUSE_POS_SCREEN, UMKA_CMD_SYS_LFN, @@ -65,7 +67,7 @@ enum { SHELL_CMD_STATUS_DONE, }; -struct cmd_set_mouse_data { +struct cmd_set_mouse_data_arg { uint32_t btn_state; int32_t xmoving; int32_t ymoving; @@ -73,36 +75,82 @@ struct cmd_set_mouse_data { int32_t hscroll; }; -struct cmd_sys_lfn { +struct cmd_set_mouse_data_ret { + char stub; +}; + +struct cmd_set_mouse_data { + struct cmd_set_mouse_data_arg arg; + struct cmd_set_mouse_data_ret ret; +}; + +struct cmd_sys_lfn_arg { f70or80_t f70or80; f7080s1arg_t *bufptr; f7080ret_t *r; }; -struct cmd_ret_sys_lfn { +struct cmd_sys_lfn_ret { f7080ret_t status; }; -struct cmd_sys_process_info { +struct cmd_sys_lfn { + struct cmd_sys_lfn_arg arg; + struct cmd_sys_lfn_ret ret; +}; + +struct cmd_sys_process_info_arg { int32_t pid; void *param; }; -struct cmd_ret_sys_get_mouse_pos_screen { +struct cmd_sys_process_info_ret { + char stub; +}; + +struct cmd_sys_process_info { + struct cmd_sys_process_info_arg arg; + struct cmd_sys_process_info_ret ret; +}; + +struct cmd_sys_get_mouse_pos_screen_arg { + char stub; +}; + +struct cmd_sys_get_mouse_pos_screen_ret { struct point16s pos; }; +struct cmd_sys_get_mouse_pos_screen { + struct cmd_sys_get_mouse_pos_screen_arg arg; + struct cmd_sys_get_mouse_pos_screen_ret ret; +}; + +struct cmd_sys_csleep_arg { + uint32_t csec; +}; + +struct cmd_sys_csleep_ret { + char stub; +}; + +struct cmd_sys_csleep { + struct cmd_sys_csleep_arg arg; + struct cmd_sys_csleep_ret ret; +}; + struct umka_cmd { atomic_int status; uint32_t type; union { + // internal funcs struct cmd_set_mouse_data set_mouse_data; + // syscalls + struct cmd_sys_csleep sys_csleep; + struct cmd_sys_process_info sys_process_info; struct cmd_sys_lfn sys_lfn; - } arg; - union { - struct cmd_ret_sys_get_mouse_pos_screen sys_get_mouse_pos_screen; - struct cmd_ret_sys_lfn sys_lfn; - } ret; + struct cmd_sys_get_mouse_pos_screen sys_get_mouse_pos_screen; + }; }; struct umka_cmd umka_cmd_buf[SHELL_CMD_BUF_LEN]; @@ -118,32 +166,7 @@ typedef struct { } func_table_t; void -shell_run_cmd_sync(struct shell_ctx *ctx) { - struct umka_cmd *cmd = umka_cmd_buf; - if (atomic_load_explicit(&cmd->status, memory_order_acquire) != SHELL_CMD_STATUS_READY) { - fprintf(ctx->fout, "[!] command is not ready: %d: %u\n", cmd - umka_cmd_buf, cmd->type); - return; - } - switch (cmd->type) { - case UMKA_CMD_SET_MOUSE_DATA: { - struct cmd_set_mouse_data *c = &cmd->arg.set_mouse_data; - kos_set_mouse_data(c->btn_state, c->xmoving, c->ymoving, c->vscroll, - c->hscroll); - break; - } - case UMKA_CMD_SYS_LFN: { - struct cmd_sys_lfn *c = &cmd->arg.sys_lfn; - umka_sys_lfn(c->bufptr, c->r, c->f70or80); - break; - } - default: - fprintf(ctx->fout, "[!] unknown command: %u\n", cmd->type); - break; - } - atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_DONE, - memory_order_release); - pthread_cond_signal(&ctx->cmd_done); -} +shell_run_cmd_sync(struct shell_ctx *ctx); static void shell_run_cmd(struct shell_ctx *ctx) { @@ -535,7 +558,7 @@ cmd_umka_boot(struct shell_ctx *ctx, int argc, char **argv) { if (*ctx->running != UMKA_RUNNING_NEVER) { char *stack = malloc(UMKA_DEFAULT_THREAD_STACK_SIZE); char *stack_top = stack + UMKA_DEFAULT_THREAD_STACK_SIZE; - size_t tid = umka_new_sys_threads(1, thread_cmd_runner, stack_top, ctx); + size_t tid = umka_new_sys_threads(0, thread_cmd_runner, stack_top, ctx); (void)tid; } } @@ -582,6 +605,54 @@ cmd_umka_set_boot_params(struct shell_ctx *ctx, int argc, char **argv) { } } +static void +cmd_csleep(struct shell_ctx *ctx, int argc, char **argv) { + const char *usage = \ + "usage: csleep\n"; + if (argc != 2) { + fputs(usage, ctx->fout); + return; + } + struct umka_cmd *cmd = umka_cmd_buf; + struct cmd_sys_csleep_arg *c = &cmd->sys_csleep.arg; + cmd->type = UMKA_CMD_SYS_CSLEEP; + c->csec = strtoul(argv[1], NULL, 0); + atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, + memory_order_release); + shell_run_cmd(ctx); + atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, + memory_order_release); +} + +static uint32_t +umka_wait_for_idle_test(void) { + return (uint32_t)(atomic_load_explicit(&idle_reached, memory_order_acquire)); +} + +static void +umka_wait_for_idle(void) { + atomic_store_explicit(&idle_reached, 0, memory_order_release); + kos_wait_events(umka_wait_for_idle_test, NULL); +} + +static void +cmd_wait_for_idle(struct shell_ctx *ctx, int argc, char **argv) { + (void)argv; + const char *usage = \ + "usage: wait_for_idle\n"; + if (argc != 1) { + fputs(usage, ctx->fout); + return; + } + struct umka_cmd *cmd = umka_cmd_buf; + cmd->type = UMKA_CMD_WAIT_FOR_IDLE; + atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, + memory_order_release); + shell_run_cmd(ctx); + atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, + memory_order_release); +} + static void cmd_i40(struct shell_ctx *ctx, int argc, char **argv) { (void)ctx; @@ -707,8 +778,9 @@ cmd_ramdisk_init(struct shell_ctx *ctx, int argc, char **argv) { } fseek(f, 0, SEEK_END); size_t fsize = ftell(f); - if (fsize > 2880*512) { - fprintf(ctx->fout, "[!] file '%s' is too big, max size is 1474560 bytes\n", fname); + if (fsize > RAMDISK_MAX_LEN) { + fprintf(ctx->fout, "[!] file '%s' is too big, max size is %d bytes\n", + fname, RAMDISK_MAX_LEN); return; } rewind(f); @@ -1206,7 +1278,7 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { uint32_t btn_state = lbheld + (rbheld << 1) + (mbheld << 2) + (yabs << 30) + (xabs << 31); struct umka_cmd *cmd = umka_cmd_buf; - struct cmd_set_mouse_data *c = &cmd->arg.set_mouse_data; + struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg; cmd->type = UMKA_CMD_SET_MOUSE_DATA; c->btn_state = btn_state; c->xmoving = xmoving; @@ -1215,9 +1287,7 @@ cmd_mouse_move(struct shell_ctx *ctx, int argc, char **argv) { c->hscroll = hscroll; atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_READY, memory_order_release); - COVERAGE_ON(); shell_run_cmd(ctx); - COVERAGE_OFF(); atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_EMPTY, memory_order_release); @@ -2357,10 +2427,15 @@ cmd_scrot(struct shell_ctx *ctx, int argc, char **argv) { lfb32 = malloc(4*kos_display.width*kos_display.height); copy_display_to_rgb888(lfb32); - uint32_t *p = lfb32; + uint8_t *from = (uint8_t*)lfb32; for (size_t y = 0; y < kos_display.height; y++) { for (size_t x = 0; x < kos_display.width; x++) { - *p++ |= 0xff000000; + uint32_t p = 0; + p += (uint32_t)from[y*kos_display.width*4+x*4 + 0] << 16; + p += (uint32_t)from[y*kos_display.width*4+x*4 + 1] << 8; + p += (uint32_t)from[y*kos_display.width*4+x*4 + 2] << 0; + p += 0xff000000; + ((uint32_t*)from)[y*kos_display.width+x] = p; } } @@ -2435,7 +2510,7 @@ ls_all(struct shell_ctx *ctx, f7080s1arg_t *fX0, f70or80_t f70or80) { BDFE_LEN_UNICODE; while (true) { struct umka_cmd *cmd = umka_cmd_buf; - struct cmd_sys_lfn *c = &cmd->arg.sys_lfn; + struct cmd_sys_lfn_arg *c = &cmd->sys_lfn.arg; cmd->type = UMKA_CMD_SYS_LFN; c->f70or80 = f70or80; c->bufptr = fX0; @@ -4050,10 +4125,12 @@ func_table_t cmd_cmds[] = { { "set_system_lang", cmd_set_system_lang }, { "set_window_caption", cmd_set_window_caption }, { "set_window_colors", cmd_set_window_colors }, + { "csleep", cmd_csleep }, { "stat70", cmd_stat70 }, { "stat80", cmd_stat80 }, { "var", cmd_var }, { "check_for_event", cmd_check_for_event }, + { "wait_for_idle", cmd_wait_for_idle }, { "window_redraw", cmd_window_redraw }, { "write_text", cmd_write_text }, { "switch_to_thread", cmd_switch_to_thread }, @@ -4061,6 +4138,49 @@ func_table_t cmd_cmds[] = { { NULL, NULL }, }; +void +shell_run_cmd_sync(struct shell_ctx *ctx) { + struct umka_cmd *cmd = umka_cmd_buf; + if (atomic_load_explicit(&cmd->status, memory_order_acquire) != SHELL_CMD_STATUS_READY) { + fprintf(ctx->fout, "[!] command is not ready: %d: %u\n", cmd - umka_cmd_buf, cmd->type); + return; + } + switch (cmd->type) { + case UMKA_CMD_WAIT_FOR_IDLE: { + COVERAGE_ON(); + umka_wait_for_idle(); + COVERAGE_OFF(); + break; + } + case UMKA_CMD_SYS_CSLEEP: { + struct cmd_sys_csleep_arg *c = &cmd->sys_csleep.arg; + COVERAGE_ON(); + umka_sys_csleep(c->csec); + COVERAGE_OFF(); + break; + } + case UMKA_CMD_SET_MOUSE_DATA: { + struct cmd_set_mouse_data_arg *c = &cmd->set_mouse_data.arg; + COVERAGE_ON(); + kos_set_mouse_data(c->btn_state, c->xmoving, c->ymoving, c->vscroll, + c->hscroll); + COVERAGE_OFF(); + break; + } + case UMKA_CMD_SYS_LFN: { + struct cmd_sys_lfn_arg *c = &cmd->sys_lfn.arg; + umka_sys_lfn(c->bufptr, c->r, c->f70or80); + break; + } + default: + fprintf(ctx->fout, "[!] unknown command: %u\n", cmd->type); + break; + } + atomic_store_explicit(&cmd->status, SHELL_CMD_STATUS_DONE, + memory_order_release); + pthread_cond_signal(&ctx->cmd_done); +} + static void cmd_help(struct shell_ctx *ctx, int argc, char **argv) { const char *usage = \ diff --git a/test/016_#f01_#draw_all.ref.png b/test/016_#f01_#draw_all.ref.png index fb90073..d0f54c2 100644 Binary files a/test/016_#f01_#draw_all.ref.png and b/test/016_#f01_#draw_all.ref.png differ diff --git a/test/044_#f01_#draw_winmap.ref.png b/test/044_#f01_#draw_winmap.ref.png index d780417..a44eb16 100644 Binary files a/test/044_#f01_#draw_winmap.ref.png and b/test/044_#f01_#draw_winmap.ref.png differ diff --git a/test/051_#draw_#cursor_all.ref.png b/test/051_#draw_#cursor_all.ref.png index 90668f3..a63c855 100644 Binary files a/test/051_#draw_#cursor_all.ref.png and b/test/051_#draw_#cursor_all.ref.png differ diff --git a/test/066_#f01_#draw_#draw16bit_all.ref.png b/test/066_#f01_#draw_#draw16bit_all.ref.png index f2d3090..d59c5ee 100644 Binary files a/test/066_#f01_#draw_#draw16bit_all.ref.png and b/test/066_#f01_#draw_#draw16bit_all.ref.png differ diff --git a/test/067_#f01_#draw_#draw24bit_all.ref.png b/test/067_#f01_#draw_#draw24bit_all.ref.png index fb90073..d0f54c2 100644 Binary files a/test/067_#f01_#draw_#draw24bit_all.ref.png and b/test/067_#f01_#draw_#draw24bit_all.ref.png differ diff --git a/umka.asm b/umka.asm index c4b86b1..7441fa8 100644 --- a/umka.asm +++ b/umka.asm @@ -10,7 +10,7 @@ if HOST eq windows else if HOST eq linux format ELF else - error "Your OS is not supported" + error "Your HOST is not supported" end if ; win32: @@ -51,7 +51,7 @@ macro pubsym name, marg1, marg2 { public name end if else - error "Your OS is not supported" + error "Your HOST is not supported" end if } @@ -61,17 +61,22 @@ macro pubsym name, marg1, marg2 { ; linux: ; extrn name -> extrn name ; extrn name, 20 -> extrn name -macro extrn name, [argsize] { +macro extrn name, argsize, asname { + if asname eq + __asname equ name + else + __asname equ asname + end if if HOST eq windows - if argsize eqtype 20 - extrn '_' # `name # '@' # `argsize as name + if argsize > 0 + extrn '_' # `name # '@' # `argsize as __asname else extrn '_' # `name as name end if else if HOST eq linux extrn name else - error "Your OS is not supported" + error "Your HOST is not supported" end if } @@ -84,6 +89,7 @@ UMKA_OS = 3 UMKA_MEMORY_BYTES = 256 SHL 20 +public idle_reached pubsym irq_serv.irq_10, 'kos_irq_serv_irq10' pubsym idts, 'kos_idts' pubsym attach_int_handler, 'kos_attach_int_handler', 12 @@ -241,7 +247,7 @@ macro diff16 msg,blah2,blah3 { ; fasm doesn't align on 65536, but ld script does section '.bss.aligned65k' writeable align 65536 else - error "Your OS is not supported" + error "Your HOST is not supported" end if bss_base: end if @@ -497,9 +503,9 @@ endp proc kos_time_to_epoch c uses ebx esi edi ebp, _time mov esi, [_time] call fsCalculateTime - xor edx, edx + xor edx, edx add eax, UNIXTIME_TO_KOS_OFFSET - adc edx, 0 + adc edx, 0 ret endp @@ -806,11 +812,12 @@ endp pubsym skin_udata proc idle uses ebx esi edi +extrn "pause" as libc_pause sti @@: -; DEBUGF 1, "1 idle\n" - movi eax, SYS_PAUSE - int 0x80 + mov [idle_reached], 1 + sfence + call libc_pause jmp @b ret @@ -841,33 +848,6 @@ proc _page_fault_handler ret endp -proc s2ys_msg_board - cmp cl, 0x0d - jz @f -if HOST eq windows - extrn putchar - pushad - push ecx - call putchar - pop ecx - popad -else if HOST eq linux - pushad - mov eax, SYS_WRITE - mov ebx, STDOUT - push ecx - mov ecx, esp - mov edx, 1 - int 0x80 - pop ecx - popad -else - error "Your OS is not supported" -end if -@@: - ret -endp - proc delay_ms ret @@ -1075,11 +1055,12 @@ else if HOST eq linux ; fasm doesn't align on 65536, but ld script does section '.data.aligned65k' writeable align 65536 else - error "Your OS is not supported" + error "Your HOST is not supported" end if umka umka_ctx fpu_owner dd ? +idle_reached dd ? uglobal align 64 diff --git a/umka.h b/umka.h index 70d4d06..ac61f56 100644 --- a/umka.h +++ b/umka.h @@ -21,6 +21,7 @@ #define UMKA_PATH_MAX 4096 #define UMKA_DEFAULT_THREAD_STACK_SIZE 0x10000 +#define RAMDISK_MAX_LEN (2880*512) // TODO: Cleanup #ifndef _WIN32 @@ -576,13 +577,15 @@ disk_del(disk_t *disk); void hash_oneshot(void *ctx, void *data, size_t len); +extern atomic_int idle_reached; + extern uint8_t xfs_user_functions[]; extern uint8_t ext_user_functions[]; extern uint8_t fat_user_functions[]; extern uint8_t exfat_user_functions[]; extern uint8_t ntfs_user_functions[]; -extern uint8_t kos_ramdisk[2880*512]; +extern char kos_ramdisk[RAMDISK_MAX_LEN]; disk_t * kos_ramdisk_init(void); @@ -1238,7 +1241,7 @@ umka_sys_write_text(size_t x, size_t y, uint32_t color, int asciiz, } static inline void -umka_sys_delay(size_t cs) { +umka_sys_csleep(size_t cs) { __asm__ __inline__ __volatile__ ( "call i40" : diff --git a/umka_os.c b/umka_os.c index 7bcba9e..d6d090f 100644 --- a/umka_os.c +++ b/umka_os.c @@ -218,7 +218,7 @@ umka_thread_board(void) { if (c.status) { fprintf(os->fboardlog, "%c", c.value); } else { - umka_sys_delay(50); + umka_sys_csleep(50); } } }