Restored support for JSSortix using very ugly hacks. :(
This commit is contained in:
parent
3859e1f566
commit
cc61176e5b
13 changed files with 135 additions and 104 deletions
4
Makefile
4
Makefile
|
@ -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)
|
||||||
|
|
|
@ -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
1
sortix/.gitignore
vendored
|
@ -5,3 +5,4 @@
|
||||||
*.so
|
*.so
|
||||||
*.a
|
*.a
|
||||||
*.initrd
|
*.initrd
|
||||||
|
*.out
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 };
|
||||||
|
|
Loading…
Reference in a new issue