diff --git a/kernel.c b/kernel.c index 47eb95a..e7e70c7 100644 --- a/kernel.c +++ b/kernel.c @@ -109,16 +109,25 @@ void ensure_v86env() { error_screen[i] = 0x0f00 | (error_screen[i] & 0x00FF); } +__attribute((__no_caller_saved_registers__)) +extern void return_prev_task(); void error_environment() { ensure_v86env(); union V86Regs_t regs; FARPTR v86_entry = i386LinearToFp(v86TextMode); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s); - printStr("Oh noes!!! System error! ;c Press E for a fun recovery :3", &error_screen[80]); + char str0[] = "Oh noes!!! System error! ;c "; + printStr(str0, &error_screen[80]); + printStr("Press E for a fun recovery :3", &error_screen[80+sizeof(str0)]); + printStr("Press R to return to previous task", &error_screen[160+sizeof(str0)]); uint16_t *vga_text = ((uint16_t*)0xB8000); for (int i = 0; i < 80*50; i++) vga_text[i] = error_screen[i]; - while ((get_scancode() & 0xff) != KEY_E); + for(;;) { + uint8_t key = get_scancode() & 0xff; + if (key == KEY_E) break; + if (key == KEY_R) return_prev_task(); + } v86_entry = i386LinearToFp(v86TransFlag); enter_v86(0x8000, 0xFF00, FP_SEG(v86_entry), FP_OFF(v86_entry), ®s); } @@ -203,6 +212,7 @@ void PrintFileList() { vga_text = nextLine(vga_text) + 3; } } +extern void create_child(uint32_t esp, uint32_t eip); void FileSelect() { fileCount = 5; uint16_t *vga_text = (uint16_t *)0xb8000; @@ -235,7 +245,7 @@ void FileSelect() { if (fileHovered < 0) fileHovered = fileCount - 1; break; case 0x14: // t - RunTests(vga_text); + create_child(0x3C0000, (uintptr_t)RunTests); SetCursorDisabled(); DrawScreen(); reload = 1; diff --git a/task.nasm b/task.nasm index 61696d9..657df10 100644 --- a/task.nasm +++ b/task.nasm @@ -7,6 +7,20 @@ ret global task_ptr task_ptr: equ (0x310000-4) + +; extern void create_child(uint32_t esp, uint32_t eip); +global create_child +create_child: +mov eax, [esp] ; return address +lea ecx, [esp+4] ; return stack, minus address +call save_current_task +xchg bx,bx +mov eax, [esp+8] ; new eip +mov esp, [esp+4] ; new esp +push return_prev_task ; if child returns, return to prev task +push eax +ret + ; return address in EAX ; return stack in ECX ; we can modify EAX, ECX, EDX @@ -34,6 +48,7 @@ mov esp, edx pop edx ret +; FIXME System will crash if last task is invalid global return_prev_task return_prev_task: mov ecx, eax ; save return value for later diff --git a/tests.c b/tests.c index 71fa2f4..79e2247 100644 --- a/tests.c +++ b/tests.c @@ -117,7 +117,8 @@ void TestFAT() { } } -void RunTests(uint16_t *vga_text) { +void RunTests() { + uint16_t *vga_text = (uint16_t*)0xb8000; uint8_t key; vga_text += printStr("V86 Test... ", vga_text); //asm ("xchgw %bx, %bx"); diff --git a/tests.h b/tests.h index fff34b2..1d7b5ee 100644 --- a/tests.h +++ b/tests.h @@ -5,4 +5,4 @@ #include "v86defs.h" #include "kbd.h" -void RunTests(uint16_t *vga_text); +void RunTests();