diff --git a/sortix/elf.cpp b/sortix/elf.cpp index 6e0e02cc..7c770cce 100644 --- a/sortix/elf.cpp +++ b/sortix/elf.cpp @@ -58,8 +58,8 @@ namespace Sortix size_t neededfilelen = phtbloffset + numprogheaders * phsize; if ( filelen < neededfilelen ) { return 0; } - // Reset the current address space. - process->ResetAddressSpace(); + // Prepare the process for execution (clean up address space, etc.) + process->ResetForExecute(); // Flush the TLB such that no stale information from the last // address space is used when creating the new one. diff --git a/sortix/process.cpp b/sortix/process.cpp index 4b5a182a..05b7397f 100644 --- a/sortix/process.cpp +++ b/sortix/process.cpp @@ -28,6 +28,7 @@ #include #include "thread.h" #include "process.h" +#include "device.h" #include "scheduler.h" #include "memorymanagement.h" #include "initrd.h" @@ -241,7 +242,17 @@ namespace Sortix void Process::ResetForExecute() { // TODO: Delete all threads and their stacks. - // TODO: Unmap any process memory segments. + + ResetAddressSpace(); + + // HACK: Don't let VGA buffers survive executes. + // Real Solution: Don't use VGA buffers in this manner. + for ( int i = 0; i < 32; i++ ) + { + Device* dev = descriptors.Get(i); + if ( !dev ) { continue; } + if ( dev->IsType(Device::VGABUFFER) ) { descriptors.Free(i); } + } } int Process::Execute(const char* programname, int argc, const char* const* argv, CPU::InterruptRegisters* regs) diff --git a/sortix/serialterminal.cpp b/sortix/serialterminal.cpp index b701f43e..42ac91dc 100644 --- a/sortix/serialterminal.cpp +++ b/sortix/serialterminal.cpp @@ -24,11 +24,14 @@ #include "platform.h" #include +#include #include "log.h" #include "vga.h" +#include "keyboard.h" #include "uart.h" #include "serialterminal.h" #include "vgaterminal.h" +#include "scheduler.h" namespace Sortix { @@ -37,23 +40,102 @@ namespace Sortix void Reset() { // Set the cursor to (0,0) and clear the screen. - const char InitMessage[] = "\e[m\e[2J\e[H"; + const char InitMessage[] = "\e[37m\e[40m\e[2J\e[H"; UART::Write(InitMessage, Maxsi::String::Length(InitMessage)); } + size_t numvgaframes = 0; + + bool isEsc; + bool isEscDepress; + void Init() { + numvgaframes = 0; Reset(); + + isEsc = isEscDepress = false; + } + + void OnTick() + { + // TODO: Yeah, this is a bad hack. + int c; + while ( (c=UART::TryPopChar()) != -1 ) + { + using namespace Maxsi::Keyboard; + + if ( !isEsc && c == '\e' ) { isEsc = true; continue; } + if ( isEsc && c == '\e' ) { isEsc = false; } + if ( isEsc && c == '[' ) { continue; } + if ( isEsc && c == ']' ) { isEscDepress = true; continue; } + if ( isEsc && !isEscDepress && c == 'A' ) { Keyboard::QueueKeystroke(UP); } + if ( isEsc && !isEscDepress && c == 'B' ) { Keyboard::QueueKeystroke(DOWN); } + if ( isEsc && !isEscDepress && c == 'C' ) { Keyboard::QueueKeystroke(RIGHT); } + if ( isEsc && !isEscDepress && c == 'D' ) { Keyboard::QueueKeystroke(LEFT); } + if ( isEsc && isEscDepress && c == 'A' ) { Keyboard::QueueKeystroke(UP | DEPRESSED); } + if ( isEsc && isEscDepress && c == 'B' ) { Keyboard::QueueKeystroke(DOWN | DEPRESSED); } + if ( isEsc && isEscDepress && c == 'C' ) { Keyboard::QueueKeystroke(RIGHT | DEPRESSED); } + if ( isEsc && isEscDepress && c == 'D' ) { Keyboard::QueueKeystroke(LEFT | DEPRESSED); } + if ( isEsc ) { isEsc = false; isEscDepress = false; continue; } + if ( c == '\e' ) { c = ESC; } + if ( c == ('\e' | (1<<7)) ) { c = ESC | DEPRESSED; } + if ( c == 'c' - 'a'+1 ) { Scheduler::SigIntHack(); continue; } + if ( c == 'o' - 'a'+1 ) { Keyboard::QueueKeystroke(CTRL); Keyboard::QueueKeystroke('O'); Keyboard::QueueKeystroke(CTRL | DEPRESSED); continue; } + if ( c == 'r' - 'a'+1 ) { Keyboard::QueueKeystroke(CTRL); Keyboard::QueueKeystroke('R'); Keyboard::QueueKeystroke(CTRL | DEPRESSED); continue; } + if ( c == 'x' - 'a'+1 ) { Keyboard::QueueKeystroke(CTRL); Keyboard::QueueKeystroke('X'); Keyboard::QueueKeystroke(CTRL | DEPRESSED); continue; } + if ( c == 127 ) { c = '\b'; } + if ( c & (1<<7) ) + { + c &= ~(1<<7); c |= DEPRESSED; + } + Keyboard::QueueKeystroke(c); + } + +#ifdef PLATFORM_SERIAL + // TODO: But this hack may be worse. + if ( numvgaframes ) + { + UART::RenderVGA((VGA::Frame*) 0xB8000); + } +#endif + } + + void OnVGAFrameCreated() + { + if ( numvgaframes++ == 0 ) + { + UART::WriteChar('\e'); + UART::WriteChar('['); + UART::WriteChar('l'); + } + } + + void OnVGAFrameDeleted() + { + if ( --numvgaframes == 0 ) + { + Reset(); + UART::WriteChar('\e'); + UART::WriteChar('['); + UART::WriteChar('h'); + } } size_t Print(void* /*user*/, const char* string, size_t stringlen) { -#ifdef JSSORTIX - VGATerminal::Print(NULL, string, stringlen); - UART::RenderVGA((VGA::Frame*) 0xB8000); -#else - UART::Write(string, stringlen); + if ( numvgaframes ) + { + VGATerminal::Print(NULL, string, stringlen); +#ifdef PLATFORM_SERIAL + UART::RenderVGA((VGA::Frame*) 0xB8000); #endif + } + else + { + UART::Write(string, stringlen); + } + return stringlen; } } diff --git a/sortix/serialterminal.h b/sortix/serialterminal.h index be83e550..84aa8e09 100644 --- a/sortix/serialterminal.h +++ b/sortix/serialterminal.h @@ -31,6 +31,9 @@ namespace Sortix { void Init(); void Reset(); + void OnTick(); + void OnVGAFrameCreated(); + void OnVGAFrameDeleted(); size_t Print(void* user, const char* string, size_t stringlen); } } diff --git a/sortix/time.cpp b/sortix/time.cpp index 49dd0ce8..b0f03f58 100644 --- a/sortix/time.cpp +++ b/sortix/time.cpp @@ -32,10 +32,7 @@ #include "sound.h" #ifdef PLATFORM_SERIAL -#include -#include "keyboard.h" -#include "vga.h" -#include "uart.h" +#include "serialterminal.h" #endif #if !defined(PLATFORM_X86_FAMILY) @@ -86,8 +83,6 @@ namespace Sortix } bool didUglyIRQ0Hack; - bool isEsc; - bool isEscDepress; void Init() { @@ -102,45 +97,12 @@ namespace Sortix didUglyIRQ0Hack = false; RequestIQR0(); - - isEsc = isEscDepress = false; } void OnIRQ0(CPU::InterruptRegisters* Regs) { #ifdef PLATFORM_SERIAL - // TODO: Yeah, this is a bad hack. - int c; - while ( (c=UART::TryPopChar()) != -1 ) - { - using namespace Maxsi::Keyboard; - - if ( !isEsc && c == '\e' ) { isEsc = true; continue; } - if ( isEsc && c == '\e' ) { isEsc = false; } - if ( isEsc && c == '[' ) { continue; } - if ( isEsc && c == ']' ) { isEscDepress = true; continue; } - if ( isEsc && !isEscDepress && c == 'A' ) { Keyboard::QueueKeystroke(UP); } - if ( isEsc && !isEscDepress && c == 'B' ) { Keyboard::QueueKeystroke(DOWN); } - if ( isEsc && !isEscDepress && c == 'C' ) { Keyboard::QueueKeystroke(RIGHT); } - if ( isEsc && !isEscDepress && c == 'D' ) { Keyboard::QueueKeystroke(LEFT); } - if ( isEsc && isEscDepress && c == 'A' ) { Keyboard::QueueKeystroke(UP | DEPRESSED); } - if ( isEsc && isEscDepress && c == 'B' ) { Keyboard::QueueKeystroke(DOWN | DEPRESSED); } - if ( isEsc && isEscDepress && c == 'C' ) { Keyboard::QueueKeystroke(RIGHT | DEPRESSED); } - if ( isEsc && isEscDepress && c == 'D' ) { Keyboard::QueueKeystroke(LEFT | DEPRESSED); } - if ( isEsc ) { isEsc = false; isEscDepress = false; continue; } - if ( c == '\e' ) { c = ESC; } - if ( c == ('\e' | (1<<7)) ) { c = ESC | DEPRESSED; } - if ( c == 3 ) { Scheduler::SigIntHack(); continue; } - if ( c == 127 ) { c = '\b'; } - if ( c & (1<<7) ) - { - c &= ~(1<<7); c |= DEPRESSED; - } - Keyboard::QueueKeystroke(c); - } - - // TODO: But this hack may be worse. - UART::RenderVGA((VGA::Frame*) 0xB8000); + SerialTerminal::OnTick(); #endif ticks++; diff --git a/sortix/vga.cpp b/sortix/vga.cpp index 80747c88..21dce5e5 100644 --- a/sortix/vga.cpp +++ b/sortix/vga.cpp @@ -29,6 +29,7 @@ #include "scheduler.h" #include "syscall.h" #include "process.h" +#include "serialterminal.h" using namespace Maxsi; @@ -109,8 +110,6 @@ namespace Sortix frame->physical = page; frame->userframe = userframe; - frame->Refer(); - return mapto; } @@ -199,10 +198,12 @@ namespace Sortix userframe = NULL; physical = 0; onscreen = false; + SerialTerminal::OnVGAFrameCreated(); } DevVGAFrame::~DevVGAFrame() { + SerialTerminal::OnVGAFrameDeleted(); if ( process != NULL ) { ASSERT(CurrentProcess() == process); } if ( userframe != NULL ) { Memory::UnmapUser((addr_t) userframe); Memory::InvalidatePage((addr_t) userframe); } if ( physical != 0 ) { Page::Put(physical); }