Restored support for JSSortix using very ugly hacks. :(

This commit is contained in:
Jonas 'Sortie' Termansen 2011-09-08 11:10:41 +02:00
parent 3859e1f566
commit cc61176e5b
13 changed files with 135 additions and 104 deletions

View File

@ -19,11 +19,11 @@ ISOFILE:=builds/$(DEBNAME).iso
INITRDDIR:=initrd INITRDDIR:=initrd
INITRD=sortix/sortix.initrd INITRD=sortix/sortix.initrd
all: $(INITRD)
suball: suball:
(for D in $(MODULES); do $(MAKE) all $(MFLAGS) --directory $$D || exit 1; done) (for D in $(MODULES); do $(MAKE) all $(MFLAGS) --directory $$D || exit 1; done)
all: $(INITRD)
clean: clean:
rm -f $(INITRD) rm -f $(INITRD)
(for D in $(MODULES); do $(MAKE) clean $(MFLAGS) --directory $$D || exit 1; done) (for D in $(MODULES); do $(MAKE) clean $(MFLAGS) --directory $$D || exit 1; done)

View File

@ -31,6 +31,11 @@ char direction[buffersize];
uint16_t animal = '%' | (COLOR8_RED<<8); uint16_t animal = '%' | (COLOR8_RED<<8);
uint16_t snake = ' ' | (COLOR8_GREEN<<12); uint16_t snake = ' ' | (COLOR8_GREEN<<12);
const int defaultspeed = 75;
const int speedincrease = -5;
const int maxspeed = 40;
volatile int speed;
// HACK: Sortix has no random number generator yet! // HACK: Sortix has no random number generator yet!
int random_seed=1337; int random_seed=1337;
int rand(int max) int rand(int max)
@ -43,7 +48,7 @@ int rand(int max)
void Clear() void Clear()
{ {
// Reset the game data. // Reset the game data.
for ( int i = 0; i < buffersize; i++ ) { frame->text[i] = 0; direction[i] = -1; } for ( int i = 0; i < buffersize; i++ ) { frame->text[i] = ' '; direction[i] = -1; }
} }
void Reset() void Reset()
@ -66,6 +71,8 @@ void Reset()
tailmax = 3; tailmax = 3;
frame->text[animaly * width + animalx] = animal; frame->text[animaly * width + animalx] = animal;
speed = defaultspeed;
} }
int Init() int Init()
@ -125,7 +132,7 @@ void Update()
// Move the tail, if needed. // Move the tail, if needed.
if ( taillen == tailmax ) if ( taillen == tailmax )
{ {
frame->text[taily * width + tailx] = 0; taillen--; frame->text[taily * width + tailx] = ' '; taillen--;
switch ( direction[taily * width + tailx] ) switch ( direction[taily * width + tailx] )
{ {
case 0: tailx--; break; case 0: tailx--; break;
@ -144,6 +151,7 @@ void Update()
tailmax++; tailmax++;
animalx = 2 + rand(width-4); animalx = 2 + rand(width-4);
animaly = 2 + rand(height-4); animaly = 2 + rand(height-4);
if ( maxspeed < speed ) { speed += speedincrease; }
} }
frame->text[animaly * width + animalx] = animal; frame->text[animaly * width + animalx] = animal;
@ -167,11 +175,10 @@ int main(int argc, char* argv[])
int result = Init(); int result = Init();
if ( result != 0 ) { return result; } if ( result != 0 ) { return result; }
// Update the game every 300th milisecond. // Update the game every once in a while.
while ( true ) while ( true )
{ {
const int sleepms = 75; Thread::USleep(speed * 1000);
Thread::USleep(sleepms * 1000);
Update(); Update();
} }

1
sortix/.gitignore vendored
View File

@ -5,3 +5,4 @@
*.so *.so
*.a *.a
*.initrd *.initrd
*.out

View File

@ -3,7 +3,8 @@ ifndef CPU
endif endif
ifeq ($(CPU),x86) ifeq ($(CPU),x86)
X86FAMILY=1 BUILDID=x86
X86FAMILY=1
CPUDEFINES=-DPLATFORM_X86 CPUDEFINES=-DPLATFORM_X86
CPUFLAGS=-m32 CPUFLAGS=-m32
CPULDFLAGS=-melf_i386 CPULDFLAGS=-melf_i386
@ -13,7 +14,8 @@ ifeq ($(CPU),x86)
endif endif
ifeq ($(CPU),x64) ifeq ($(CPU),x64)
X86FAMILY=1 BUILDID=x64
X86FAMILY=1
CPUDEFINES=-DPLATFORM_X64 CPUDEFINES=-DPLATFORM_X64
CPUFLAGS=-m64 -ffreestanding -mcmodel=large -mno-red-zone CPUFLAGS=-m64 -ffreestanding -mcmodel=large -mno-red-zone
CPULDFLAGS=-melf64-little -z max-page-size=0x1000 CPULDFLAGS=-melf64-little -z max-page-size=0x1000
@ -34,13 +36,10 @@ endif
DIRS=. x64 x86 x86-family DIRS=. x64 x86 x86-family
DEFINES:=-DSORTIX_KERNEL $(CPUDEFINES) DEFINES:=-DSORTIX_KERNEL $(CPUDEFINES)
DEFINES:=$(DEFINES) -DPLATFORM_VIRTUAL_MEMORY ifeq ($(JSSORTIX),1)
DEFINES:=$(DEFINES) -DPLATFORM_KERNEL_HEAP DEFINES:=$(DEFINES) -DPLATFORM_SERIAL -DJSSORTIX
#DEFINES:=$(DEFINES) -DPLATFORM_SERIAL BUILDID:=$(BUILDID)-js
#DEFINES:=$(DEFINES) -DPLATFORM_HTP endif
#DEFINES:=$(DEFINES) -DCONWAY
#DEFINES:=$(DEFINES) -DPONG
DEFINES:=$(DEFINES) -DINITRD
CPPFLAGSRELEASE=-s -O3 CPPFLAGSRELEASE=-s -O3
CPPFLAGSDEBUG= CPPFLAGSDEBUG=
CPPFLAGS=-I.. -I. $(CPUDEFINES) $(CPUFLAGS) -std=gnu++0x -Wall -Wextra -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector $(DEFINES) $(CPPFLAGSRELEASE) CPPFLAGS=-I.. -I. $(CPUDEFINES) $(CPUFLAGS) -std=gnu++0x -Wall -Wextra -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector $(DEFINES) $(CPPFLAGSRELEASE)
@ -76,9 +75,9 @@ all: sortix.bin
jssortix: jssortix.bin jssortix: jssortix.bin
jssortix.bin: $(JSOBJS) sortix-x86-js.tmp: $(OBJS)
ld -melf_i386 -Ttext 100000 -o jssortix.out $(JSOBJS) ld -melf_i386 -Ttext 100000 -o sortix-x86-js-internal.out $(OBJS)
objcopy -O binary jssortix.out jssortix.bin objcopy -O binary sortix-x86-js-internal.out $@
# x64 compilation # x64 compilation
x64/boot.o: x64/boot.s x64/boot.o: x64/boot.s
@ -101,7 +100,7 @@ sortix-x86.tmp: $(OBJS)
# general rules # general rules
sortix.bin: sortix-$(CPU).tmp sortix.bin: sortix-$(BUILDID).tmp
cp -vu $< $@ cp -vu $< $@
%.o: %.cpp %.o: %.cpp
@ -113,15 +112,6 @@ sortix.bin: sortix-$(CPU).tmp
%.o: %.asm %.o: %.asm
nasm $(CPUNASMFLAGS) $< -o $@ nasm $(CPUNASMFLAGS) $< -o $@
%-js.o: %.cpp
g++ -c $< -o $@ $(CPPFLAGS) -DJSSORTIX
%-js.o: %.s
as $(CPUASFLAGS) $< -o $@
%-js.o: %.asm
nasm $(CPUNASMFLAGS) $< -o $@
clean: clean:
for D in $(DIRS); do rm -fv $$D/*.o $$D/*.bin $$D/*.out $$D/*.tmp; done for D in $(DIRS); do rm -fv $$D/*.o $$D/*.bin $$D/*.out $$D/*.tmp; done

View File

@ -60,7 +60,7 @@ namespace Sortix
? exceptions[regs->int_no] : "Unknown"; ? exceptions[regs->int_no] : "Unknown";
// Halt and catch fire if we are the kernel. // Halt and catch fire if we are the kernel.
if ( (regs->cs & (0x4-1)) == 0 ) if ( (regs->cs & (0x4-1)) == 0 || regs->int_no == 13 )
{ {
PanicF("Unhandled CPU Exception id %zu '%s' at eip=0x%zx " PanicF("Unhandled CPU Exception id %zu '%s' at eip=0x%zx "
"(cr2=0x%p, err_code=0x%p)", regs->int_no, message, "(cr2=0x%p, err_code=0x%p)", regs->int_no, message,

View File

@ -115,6 +115,7 @@ namespace Sortix
Log::Print(" / \\ / \\ \n"); Log::Print(" / \\ / \\ \n");
Log::Print(" /_____________\\ /____________\\ \n"); Log::Print(" /_____________\\ /____________\\ \n");
Log::Print(" \n"); Log::Print(" \n");
Log::Print(" BOOTING OPERATING SYSTEM... ");
} }
void DoWelcome() void DoWelcome()
@ -124,22 +125,6 @@ namespace Sortix
#endif #endif
DoMaxsiLogo(); DoMaxsiLogo();
#ifdef PLATFORM_SERIAL
#ifdef PONG
Log::Print(" = THE SORTIX KERNEL - PONG EDITION = ");
#elif defined(CONWAY)
Log::Print(" = THE SORTIX KERNEL - CONWAY'S GAME OF LIFE EDITION = ");
#else
Log::Print(" ");
#endif
Log::Print(" ");
Log::Print(" ");
Log::Print(" ");
Log::Print(" ");
Log::Print(" ");
Log::Print(" ");
#endif
} }
extern "C" void KernelInit(unsigned long Magic, multiboot_info_t* BootInfo) extern "C" void KernelInit(unsigned long Magic, multiboot_info_t* BootInfo)
@ -197,7 +182,7 @@ namespace Sortix
uint8_t* initrd = NULL; uint8_t* initrd = NULL;
size_t initrdsize = 0; size_t initrdsize = 0;
#ifdef INITRD #ifndef JSSORTIX
uint8_t** modules = (uint8_t**) BootInfo->mods_addr; uint8_t** modules = (uint8_t**) BootInfo->mods_addr;
for ( uint32_t I = 0; I < BootInfo->mods_count; I++ ) for ( uint32_t I = 0; I < BootInfo->mods_count; I++ )
{ {
@ -205,9 +190,13 @@ namespace Sortix
initrd = modules[2*I+0]; initrd = modules[2*I+0];
break; break;
} }
#else
// TODO: UGLY HACK because JSVM doesn't support multiboot yet!
initrd = (uint8_t*) 0x180000UL;
initrdsize = 0x80000; // 512 KiB
#endif
if ( initrd == NULL ) { PanicF("No initrd provided"); } if ( initrd == NULL ) { PanicF("No initrd provided"); }
#endif
// Initialize the GDT and TSS structures. // Initialize the GDT and TSS structures.
GDT::Init(); GDT::Init();
@ -217,16 +206,12 @@ namespace Sortix
if ( BootInfo == NULL ) { Panic("kernel.cpp: The bootinfo structure was NULL. Are your bootloader multiboot compliant?"); } if ( BootInfo == NULL ) { Panic("kernel.cpp: The bootinfo structure was NULL. Are your bootloader multiboot compliant?"); }
#ifdef PLATFORM_VIRTUAL_MEMORY
// Initialize virtual memory. TODO: This is not fully working yet. // Initialize virtual memory. TODO: This is not fully working yet.
VirtualMemory::Init(); VirtualMemory::Init();
#ifdef PLATFORM_KERNEL_HEAP
// Initialize the kernel heap. // Initialize the kernel heap.
Maxsi::Memory::Init(); Maxsi::Memory::Init();
#endif
#endif
// Initialize the keyboard. // Initialize the keyboard.
Keyboard::Init(); Keyboard::Init();

View File

@ -42,6 +42,7 @@ namespace Sortix
void SetLEDs(uint8_t Toggle); void SetLEDs(uint8_t Toggle);
void OnIRQ1(CPU::InterruptRegisters* Regs); void OnIRQ1(CPU::InterruptRegisters* Regs);
void SysReceieveKeystroke(CPU::InterruptRegisters* R); void SysReceieveKeystroke(CPU::InterruptRegisters* R);
bool QueueKeystroke(uint32_t keystroke);
} }
} }

View File

@ -223,11 +223,9 @@ namespace Sortix
addr_t KernelStackPage = Page::Get(); addr_t KernelStackPage = Page::Get();
if ( KernelStackPage == 0 ) { Panic("scheduler.cpp: could not allocate kernel interrupt stack for tss!"); } if ( KernelStackPage == 0 ) { Panic("scheduler.cpp: could not allocate kernel interrupt stack for tss!"); }
#ifdef PLATFORM_VIRTUAL_MEMORY
uintptr_t MapTo = 0x80000000; uintptr_t MapTo = 0x80000000;
VirtualMemory::MapKernel(MapTo, (uintptr_t) KernelStackPage); VirtualMemory::MapKernel(MapTo, (uintptr_t) KernelStackPage);
#endif
GDT::SetKernelStack((size_t*) (MapTo+4096)); GDT::SetKernelStack((size_t*) (MapTo+4096));
} }
@ -236,7 +234,6 @@ namespace Sortix
// simply awaits an IRQ0 and then we shall be scheduling. // simply awaits an IRQ0 and then we shall be scheduling.
void MainLoop() void MainLoop()
{ {
Log::PrintF("Waiting for IRQ0\n");
// Simply wait for the next IRQ0 and then the OS will run. // Simply wait for the next IRQ0 and then the OS will run.
while ( true ) { } while ( true ) { }
} }
@ -253,43 +250,25 @@ namespace Sortix
// TODO: We only support stacks of up to one page! // TODO: We only support stacks of up to one page!
if ( 4096 < StackSize ) { StackSize = 4096; } if ( 4096 < StackSize ) { StackSize = 4096; }
#ifndef PLATFORM_KERNEL_HEAP
// TODO: Use the proper memory management systems using new and delete instead of these hacks!
// TODO: These allocations might NOT be thread safe!
void* ThreadPage = Page::Get();
if ( ThreadPage == NULL ) { return NULL; }
#endif
// Allocate a stack for this thread. // Allocate a stack for this thread.
size_t StackLength = StackSize / sizeof(size_t); size_t StackLength = StackSize / sizeof(size_t);
addr_t PhysStack = Page::Get(); addr_t PhysStack = Page::Get();
if ( PhysStack == 0 ) if ( PhysStack == 0 )
{ {
#ifndef PLATFORM_KERNEL_HEAP
Page::Put(ThreadPage);
#endif
return NULL; return NULL;
} }
// Create a new thread data structure. // Create a new thread data structure.
Thread* thread = new Thread* thread = new Thread(Process, AllocatedThreadId++, PhysStack, StackLength);
#ifndef PLATFORM_KERNEL_HEAP
(ThreadPage)
#endif
Thread(Process, AllocatedThreadId++, PhysStack, StackLength);
#ifdef PLATFORM_X86 #ifdef PLATFORM_X86
#ifdef PLATFORM_VIRTUAL_MEMORY
uintptr_t StackPos = 0x80000000UL; uintptr_t StackPos = 0x80000000UL;
uintptr_t MapTo = StackPos - 4096UL; uintptr_t MapTo = StackPos - 4096UL;
addr_t OldAddrSpace = VirtualMemory::SwitchAddressSpace(Process->GetAddressSpace()); addr_t OldAddrSpace = VirtualMemory::SwitchAddressSpace(Process->GetAddressSpace());
VirtualMemory::MapUser(MapTo, PhysStack); VirtualMemory::MapUser(MapTo, PhysStack);
#else
uintptr_t StackPos = (uintptr_t) PhysStack + 4096;
#endif
size_t* Stack = (size_t*) StackPos; size_t* Stack = (size_t*) StackPos;
#ifdef PLATFORM_X86 #ifdef PLATFORM_X86
@ -311,10 +290,8 @@ namespace Sortix
// Mark the thread as running, which adds it to the scheduler's linked list. // Mark the thread as running, which adds it to the scheduler's linked list.
thread->SetState(Thread::State::RUNNABLE); thread->SetState(Thread::State::RUNNABLE);
#ifdef PLATFORM_VIRTUAL_MEMORY
// Avoid side effects by restoring the old address space. // Avoid side effects by restoring the old address space.
VirtualMemory::SwitchAddressSpace(OldAddrSpace); VirtualMemory::SwitchAddressSpace(OldAddrSpace);
#endif
return thread; return thread;
} }
@ -390,7 +367,8 @@ namespace Sortix
#ifdef PLATFORM_X86 #ifdef PLATFORM_X86
if ( currentThread != NoopThread ) // TODO: HACK: Find a more accurate way to test for kernel code.
if ( R->eip >= 0x400000UL )
{ {
uint32_t RPL = 0x3; uint32_t RPL = 0x3;
@ -460,11 +438,7 @@ namespace Sortix
// TODO: What do we do with the result parameter? // TODO: What do we do with the result parameter?
Thread->~Thread(); Thread->~Thread();
//Log::PrintF("<ExitedThread debug=\"2\" thread=\"%p\"/>\n", Thread); //Log::PrintF("<ExitedThread debug=\"2\" thread=\"%p\"/>\n", Thread);
#ifndef PLATFORM_KERNEL_HEAP
Page::Put((addr_t) Thread);
#else
delete Thread; delete Thread;
#endif
//Log::PrintF("<ExitedThread debug=\"3\" thread=\"%p\"/>\n", Thread); //Log::PrintF("<ExitedThread debug=\"3\" thread=\"%p\"/>\n", Thread);
if ( Thread == currentThread ) { currentThread = NULL; } if ( Thread == currentThread ) { currentThread = NULL; }

View File

@ -25,8 +25,10 @@
#include "platform.h" #include "platform.h"
#include <libmaxsi/string.h> #include <libmaxsi/string.h>
#include "log.h" #include "log.h"
#include "vga.h"
#include "uart.h" #include "uart.h"
#include "serialterminal.h" #include "serialterminal.h"
#include "vgaterminal.h"
namespace Sortix namespace Sortix
{ {
@ -46,7 +48,12 @@ namespace Sortix
size_t Print(void* /*user*/, const char* string, size_t stringlen) 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); UART::Write(string, stringlen);
#endif
return stringlen; return stringlen;
} }
} }

View File

@ -29,6 +29,13 @@
#include "scheduler.h" #include "scheduler.h"
#include "log.h" #include "log.h"
#ifdef PLATFORM_SERIAL
#include <libmaxsi/keyboard.h>
#include "keyboard.h"
#include "vga.h"
#include "uart.h"
#endif
#if !defined(PLATFORM_X86_FAMILY) #if !defined(PLATFORM_X86_FAMILY)
#error No time subsystem is available for this CPU #error No time subsystem is available for this CPU
#endif #endif
@ -72,6 +79,8 @@ namespace Sortix
} }
bool didUglyIRQ0Hack; bool didUglyIRQ0Hack;
bool isEsc;
bool isEscDepress;
void Init() void Init()
{ {
@ -86,10 +95,47 @@ namespace Sortix
didUglyIRQ0Hack = false; didUglyIRQ0Hack = false;
RequestIQR0(); RequestIQR0();
isEsc = isEscDepress = false;
} }
void OnIRQ0(CPU::InterruptRegisters* Regs) 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 ) { SigInt(); 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);
#endif
Ticks++; Ticks++;
// Let the scheduler switch to the next task. // Let the scheduler switch to the next task.

View File

@ -24,6 +24,7 @@
#include "platform.h" #include "platform.h"
#include <libmaxsi/string.h> #include <libmaxsi/string.h>
#include <libmaxsi/memory.h>
#ifdef PLATFORM_SERIAL #ifdef PLATFORM_SERIAL
#include "vga.h" #include "vga.h"
#endif #endif
@ -216,15 +217,11 @@ namespace Sortix
void RenderVGA(const VGA::Frame* Frame) void RenderVGA(const VGA::Frame* Frame)
{ {
#if 0
// Set the cursor to (0,0)
const char InitMessage[] = { String::ASCII_ESCAPE, '[', 'H' };
UART::Write(InitMessage, sizeof(InitMessage));
const uint16_t* Source = Frame->Data; const uint16_t* Source = Frame->Data;
nat LastColor = 1337; nat LastColor = 1337;
nat SkippedSince = 0; nat SkippedSince = 0;
bool posundefined = true;
for ( nat Y = 0; Y < Frame->Height; Y++) for ( nat Y = 0; Y < Frame->Height; Y++)
{ {
@ -237,33 +234,42 @@ namespace Sortix
if ( Element == OldElement ) { continue; } if ( Element == OldElement ) { continue; }
VGALastFrame.Data[Index] = Element;
// Update the position if we skipped some characters. // Update the position if we skipped some characters.
if ( Index - SkippedSince > 8 ) if ( Index - SkippedSince > 8 || posundefined )
{ {
const nat LineId = Y + 1; const nat LineId = Y + 1;
const nat ColumnId = X + 1; const nat ColumnId = X + 1;
if ( ColumnId > 1 ) if ( ColumnId > 1 )
{ {
const char Message[] = { String::ASCII_ESCAPE, '[', '0' + LineId / 10, '0' + LineId % 10, ';', '0' + ColumnId / 10, '0' + ColumnId % 10, 'H' }; UART::WriteChar('\e');
UART::Write(Message, sizeof(Message)); UART::WriteChar('[');
UART::WriteChar('0' + LineId / 10);
UART::WriteChar('0' + LineId % 10);
UART::WriteChar(';');
UART::WriteChar('0' + ColumnId / 10);
UART::WriteChar('0' + ColumnId % 10);
UART::WriteChar('H');
} }
else else
{ {
const char Message[] = { String::ASCII_ESCAPE, '[', '0' + LineId / 10, '0' + LineId % 10, 'H' }; UART::WriteChar('\e');
UART::Write(Message, sizeof(Message)); UART::WriteChar('[');
UART::WriteChar('0' + LineId / 10);
UART::WriteChar('0' + LineId % 10);
UART::WriteChar('H');
} }
SkippedSince = Index; SkippedSince = Index;
posundefined = false;
} }
for ( nat Pos = SkippedSince; Pos <= Index; Pos++ ) for ( nat Pos = SkippedSince; Pos <= Index; Pos++ )
{ {
Element = Source[Pos]; Element = Source[Pos];
OldElement = VGALastFrame.Data[Pos];
nat NewColor = ConversionTable[ (Element >> 12) & 0xF ] << 3 | ConversionTable[ (Element >> 8) & 0xF ]; nat NewColor = (ConversionTable[ (Element >> 12) & 0xF ] << 3) | (ConversionTable[ (Element >> 8) & 0xF ]);
// Change the color if we need to. // Change the color if we need to.
if ( LastColor != NewColor ) if ( LastColor != NewColor )
@ -272,26 +278,41 @@ namespace Sortix
nat OldBGColor = LastColor / 8; nat OldBGColor = LastColor / 8;
nat FGColor = NewColor % 8; nat FGColor = NewColor % 8;
nat BGColor = NewColor / 8; nat BGColor = NewColor / 8;
if ( LastColor == 1337 ) { OldFGColor = 9; OldBGColor = 9; }
if ( (OldFGColor != FGColor) && (OldBGColor != BGColor) ) if ( (OldFGColor != FGColor) && (OldBGColor != BGColor) )
{ {
const char Message[] = { String::ASCII_ESCAPE, '[', '3', '0' + FGColor, ';', '4', '0' + BGColor, 'm' }; UART::WriteChar('\e');
UART::Write(Message, sizeof(Message)); UART::WriteChar('[');
UART::WriteChar('3');
UART::WriteChar('0' + FGColor);
UART::WriteChar(';');
UART::WriteChar('4');
UART::WriteChar('0' + BGColor);
UART::WriteChar('m');
} }
else if ( OldFGColor != FGColor ) else if ( OldFGColor != FGColor )
{ {
const char Message[] = { String::ASCII_ESCAPE, '[', '3', '0' + FGColor, 'm' }; UART::WriteChar('\e');
UART::Write(Message, sizeof(Message)); UART::WriteChar('[');
UART::WriteChar('3');
UART::WriteChar('0' + FGColor);
UART::WriteChar('m');
} }
else if ( OldBGColor != BGColor ) else if ( OldBGColor != BGColor )
{ {
const char Message[] = { String::ASCII_ESCAPE, '[', '4', '0' + BGColor, 'm' }; UART::WriteChar('\e');
UART::Write(Message, sizeof(Message)); UART::WriteChar('[');
UART::WriteChar('4');
UART::WriteChar('0' + BGColor);
UART::WriteChar('m');
} }
LastColor = NewColor; LastColor = NewColor;
} }
VGALastFrame.Data[Pos] = Element;
Element &= 0x7F; Element &= 0x7F;
// Filter away any non-printable characters. // Filter away any non-printable characters.
@ -303,7 +324,6 @@ namespace Sortix
SkippedSince = Index + 1; SkippedSince = Index + 1;
} }
} }
#endif
} }
#endif #endif
} }

View File

@ -119,7 +119,7 @@ isr_common_stub:
popa ; Pops edi,esi,ebp... popa ; Pops edi,esi,ebp...
add esp, 8 ; Cleans up the pushed error code and pushed ISR number add esp, 8 ; Cleans up the pushed error code and pushed ISR number
sti ;sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
; In isr.c ; In isr.c
@ -155,7 +155,7 @@ irq_common_stub:
popa ; Pops edi,esi,ebp... popa ; Pops edi,esi,ebp...
add esp, 8 ; Cleans up the pushed error code and pushed ISR number add esp, 8 ; Cleans up the pushed error code and pushed ISR number
sti ;sti
iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP

View File

@ -4,7 +4,7 @@
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
// Reset the terminal's color and the rest of it. // Reset the terminal's color and the rest of it.
printf("\e[m\e[J"); printf("\r\e[m\e[J");
const char* programname = "sh"; const char* programname = "sh";
const char* newargv[] = { programname }; const char* newargv[] = { programname };