diff --git a/Makefile b/Makefile index a30d3e7..a21b21c 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,7 @@ CFLAGS = -g -std=gnu11 -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exce CXXFLAGS = -g -m32 -fno-use-cxa-atexit -mgeneral-regs-only -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -fpermissive -fno-pie -fno-stack-protector -I. LDFLAGS = -DISK_IMG_FILES = build/kernel/kernel.bin build/program/program.bin build/hello/hello.bin \ - build/world/world.bin hello.txt alpha.txt +DISK_IMG_FILES = build/kernel/kernel.bin build/world/world.bin hello.txt alpha.txt KERNEL_CPP_SRCS = $(wildcard src/kernel/*.cpp) $(wildcard src/kernel/*/*.cpp) KERNEL_ASM_SRCS = $(wildcard src/kernel/*.asm) @@ -54,6 +53,7 @@ prepare: mkdir -p build/boot_stage2 mkdir -p build/kernel mkdir -p build/kernel/datatypes + mkdir -p build/kernel/stdio mkdir -p build/program mkdir -p build/hello mkdir -p build/world diff --git a/src/boot_stage2/main.c b/src/boot_stage2/main.c index 7077925..e2a77ae 100644 --- a/src/boot_stage2/main.c +++ b/src/boot_stage2/main.c @@ -146,9 +146,9 @@ void main() { // But first, we should load the kernel somewhere uint8_t* kernel_location = 0x542000; // Just load it at 0x524000 for now - mark_unavailble(kernel_location, 32768, bitmap); // Just treat the kernel as not growing beyond 32k for now. + mark_unavailble(kernel_location, 0x10000, bitmap); // Just treat the kernel as not growing beyond 32k for now. - map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 8); // Map 8 pages from 0x522000 to 0xc0000000; + map_many_4k_phys_to_virt(kernel_location, 0xc0000000, kernel_page_directory, kernel_page_tables, 0x10); // Map 8 pages from 0x522000 to 0xc0000000; map_4k_phys_to_virt((uint32_t)kernel_page_directory, 0xc0100000, kernel_page_directory, kernel_page_tables); // Map the page directory to 0xc0100000 map_many_4k_phys_to_virt(0x121000, 0xc0101000, kernel_page_directory, kernel_page_tables, 1024); // Map 1024 pages from 0x121000 to 0xc0101000 map_4k_phys_to_virt(0xb8000, 0xc0501000, kernel_page_directory, kernel_page_tables); // Map 0xb8000 (video) to 0xc0501000 @@ -159,7 +159,7 @@ void main() { memset(vm_bitmap, 0x20000, 0xff); - mark_unavailble(0xc0000000, 0x8000, vm_bitmap); + mark_unavailble(0xc0000000, 0x10000, vm_bitmap); mark_unavailble(0xc0100000, 0x1000, vm_bitmap); mark_unavailble(0xc0101000, 0x400000, vm_bitmap); mark_unavailble(0xc0501000, 0x1000, vm_bitmap); @@ -175,9 +175,9 @@ void main() { map_4k_phys_to_virt(0x8000, 0x8000, kernel_page_directory, kernel_page_tables); // Map the stack - map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 6); - map_many_4k_phys_to_virt(0x8a000, 0xc1000000, kernel_page_directory, kernel_page_tables, 6); - mark_unavailble(0x8a000, 0x6000, bitmap); + map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 16); + map_many_4k_phys_to_virt(0x8a000, 0xc1000000, kernel_page_directory, kernel_page_tables, 16); + mark_unavailble(0x8a000, 0x10000, bitmap); load_file("KERNEL BIN", kernel_location); diff --git a/src/common/common.c b/src/common/common.c index bc9b182..7b2f732 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -1,19 +1,11 @@ #include "common.h" void print(char* string) { - asm volatile ("mov $0, %%eax; mov %0, %%esi; int $0x7f" : : "m" (string) : "eax", "esi"); -} - -char getch() { - asm volatile ("mov $1, %%eax; int $0x7f" : : :); -} - -uint8_t getchPS2() { - asm volatile ("mov $2, %%eax; int $0x7f" : : :); -} - -void readfile(char* filename, uint8_t* buffer) { - asm volatile ("mov $3, %%eax; mov %0, %%esi; mov %1, %%edi; int $0x7f" : : "m" (filename), "m" (buffer) : "eax", "esi", "edi"); + char* c = string; + int i=0; + while (*(c++)) + i++; + write(i, 0, (uint8_t*)string); } void* localalloc(uint32_t size) { @@ -24,14 +16,22 @@ void localdelete(void* ptr) { asm volatile ("mov $5, %%eax; mov %0, %%esi; int $0x7f" : : "m" (ptr) : "esi"); } -uint32_t filesize(char* filename) { - asm volatile ("mov $6, %%eax; mov %0, %%esi; int $0x7f" : : "m" (filename) : "esi"); -} - uint32_t getPID() { asm volatile ("mov $8, %%eax; int $0x7f" : : :); } +int read(uint32_t count, void* filehanlder, uint8_t* buffer) { + asm volatile ("mov $10, %%eax; mov %0, %%ebx; mov %1, %%esi; mov %2, %%edi; int $0x7f" : : "m" (count), "m" (filehanlder), "m" (buffer): "ebx", "esi", "edi"); +} + +int write(uint32_t count, void* filehanlder, uint8_t* buffer) { + asm volatile ("mov $11, %%eax; mov %0, %%ebx; mov %1, %%esi; mov %2, %%edi; int $0x7f" : : "m" (count), "m" (filehanlder), "m" (buffer): "ebx", "esi", "edi"); +} + +void bindToKeyboard() { + asm volatile ("mov $12, %%eax; int $0x7f" : : :); +} + int int_to_decimal(unsigned int number, char* string_buffer) { for (int i=0; i<11; i++) string_buffer[i] = 0; diff --git a/src/common/common.h b/src/common/common.h index b71bb0c..168d576 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -4,8 +4,6 @@ #include "../kernel/types.h" void print(char* string); -char getch(); -uint8_t getchPS2(); void readfile(char* filename, uint8_t* buffer); void* localalloc(uint32_t size); void localdelete(void* ptr); @@ -13,6 +11,10 @@ uint32_t filesize(char* filename); uint32_t getPID(); +int read(uint32_t count, void* filehandler, uint8_t* buffer); +int write(uint32_t count, void* filehandler, uint8_t* buffer); +void bindToKeyboard(); + int int_to_decimal(unsigned int number, char* string_buffer); int int_to_hex(unsigned int number, char* string_buffer); diff --git a/src/hello/hello.c b/src/hello/hello.c index e2f46b5..717a8aa 100644 --- a/src/hello/hello.c +++ b/src/hello/hello.c @@ -5,7 +5,6 @@ int main() { uint32_t PID = getPID(); char intbuffer[32]; uint32_t index = int_to_decimal(PID, intbuffer); - uint32_t x = *(uint32_t*)0xdeadbeef; while (1) { counter++; if (counter == 312500) { diff --git a/src/kernel/datatypes/linkedlist.h b/src/kernel/datatypes/linkedlist.h index d72686e..a2d977f 100644 --- a/src/kernel/datatypes/linkedlist.h +++ b/src/kernel/datatypes/linkedlist.h @@ -22,6 +22,16 @@ namespace xnoe { xnoe::linkedlistelem* start; xnoe::linkedlistelem* end; + bool has(T t) { + xnoe::linkedlistelem* current = this->start; + while (start) { + if (start->elem == t) + return true; + } + + return false; + } + void append(T t) { xnoe::linkedlistelem* llelem = new xnoe::linkedlistelem(t); append(llelem); diff --git a/src/kernel/entry.asm b/src/kernel/entry.asm index 9b5da86..f800563 100644 --- a/src/kernel/entry.asm +++ b/src/kernel/entry.asm @@ -1,7 +1,7 @@ [BITS 32] _start: - mov esp, 0xc1005ffc + mov esp, 0xc100a000 jmp main extern main \ No newline at end of file diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 076b65b..c2755ff 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -136,63 +136,112 @@ void context_switch(frame_struct* frame) { // Set the current proc to valid Global::currentProcValid = true; - uint32_t* espVal; - asm ("mov %%esp, %0":"=a"(espVal):); - if (*espVal == 0) { + if (Global::currentProc->firstRun) { + Global::currentProc->firstRun = false; asm("add $4, %esp"); asm("ret"); } } } -extern uint8_t current_scancode; -extern char decoded; - void syscall(frame_struct* frame) { // Syscall ABI: - // 0: print: Print null terminated string (in esi: char*) - // 1: getch: Get current keyboard character ASCII (out eax: char) - // 2: getchPS2: Get current keyboard character PS/2 code (out eax: char) - // 3: readfile: Load file to location (in esi: char* filename; in edi: uint8_t* buffer) + // 0: X + // 1: X + // 2: X + // 3: X // 4: localalloc: LocalAlloc: Allocate under current process (in esi: size; out eax void* ptr) // 5: localdelete: LocalDelete: Deallocate under current process (in esi: pointer) - // 6: filesize: Get file size (in esi: char* filename; out eax size bytes) - // 7: fork: create process from filename (in esi: char* filename) + // 6: X + // 7: X // 8: getPID: returns the current process's PID (out eax: uint32_t) + // 9: getFileHandler :: char* path esi -> void* eax // Returns a file handlers for a specific file + // 10: read :: uint32_t count ebx -> void* filehandler esi -> uint8_t* outputbuffer edi -> int read // Reads from a file handler in to a buffer, returns successful read + // 11: write :: uint32_t count ebx -> void* filehandler esi -> uint8_t* inputbuffer edi -> int written // Reads from a buffer in to a file, returns successful written + // 12: bindToKeyboard :: void -> void // Binds the current process's stdout to the keyboard. + + // File handlers: + // 0: Stdout + // 1: Stdin + // 2..7: Reserved + // _: General use uint32_t rval = frame->eax; uint32_t esi = frame->esi; uint32_t edi = frame->edi; + + Process* currentProc = Global::currentProc; + switch (frame->eax) { case 0: - Global::kernel->terminal->printf("%s", (char*)esi); break; case 1: - rval = decoded; break; case 2: - rval = current_scancode; break; case 3: - load_file(esi, edi); break; case 4: - rval = Global::currentProc->allocate(esi); + rval = currentProc->allocate(esi); break; case 5: - Global::currentProc->deallocate(esi); + currentProc->deallocate(esi); break; case 6: - rval = file_size(esi); break; - case 7: { - Global::kernel->createProcess(esi); + case 7: + break; + case 8: + rval = currentProc->PID; + break; + + case 9: + break; + + case 10: { + if (esi == 1) { + ReadWriter* stdin = currentProc->stdin; + if (!stdin) + break; + + rval = stdin->read(frame->ebx, edi); + } else { + xnoe::Maybe fh = Global::kernel->FH->get(esi); + if (!fh.is_ok()) + break; + + ReadWriter* rw = fh.get(); + rval = rw->read(frame->ebx, edi); + } break; } - case 8: - rval = Global::currentProc->PID; + + case 11: { + if (esi == 0) { + ReadWriter* stdout = currentProc->stdout; + if (!stdout) + break; + + rval = stdout->write(frame->ebx, edi); + } else { + xnoe::Maybe fh = Global::kernel->FH->get(esi); + if (!fh.is_ok()) + break; + + ReadWriter* rw = fh.get(); + rval = rw->write(frame->ebx, edi); + } break; + } + + case 12: + if (currentProc->stdin) + break; + + currentProc->stdin = new CircularRWBuffer(currentProc->PID, 0); + Global::kernel->KBListeners.append(currentProc); + default: break; } diff --git a/src/kernel/idt.h b/src/kernel/idt.h index 761e143..cffb2b1 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -6,6 +6,7 @@ #include "global.h" #include "kernel.h" #include "gdt.h" +#include "stdio/circularrwbuffer.h" struct __attribute__((packed)) frame_struct { uint32_t edi; diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index c30c93e..49f23b0 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -29,6 +29,12 @@ Process* Kernel::createProcess(char* filename) { return p; } +Process* Kernel::createProcess(char* filename, ReadWriter* stdout) { + Process* p = this->createProcess(filename); + p->stdout = stdout; + return p; +} + void Kernel::destroyProcess(Process* p) { this->processes.remove(p); this->pid_map->remove(p->PID, p); diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index d597748..d808f68 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -14,14 +14,17 @@ public: Terminal* terminal; xnoe::hashtable* pid_map; // Map of PIDs -> Process*s + xnoe::hashtable* FH; // Map of File Handlers -> Read Writer xnoe::linkedlist processes; + xnoe::linkedlist KBListeners; Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base, uint32_t stack); void init_kernel(); Process* createProcess(char* filename); + Process* createProcess(char* filename, ReadWriter* stdout); void destroyProcess(Process* p); //void loadPrimaryStack(); }; diff --git a/src/kernel/keyboard.cpp b/src/kernel/keyboard.cpp index 163f579..134cfbb 100644 --- a/src/kernel/keyboard.cpp +++ b/src/kernel/keyboard.cpp @@ -1,8 +1,8 @@ #include "keyboard.h" char key_to_char[128] = { - 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0, + 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', @@ -11,8 +11,8 @@ char key_to_char[128] = { }; char key_to_char_caps[128] = { - 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0, + 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 0, '\\', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', @@ -21,8 +21,8 @@ char key_to_char_caps[128] = { }; char key_to_char_shift[128] = { - 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0, + 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', @@ -30,14 +30,12 @@ char key_to_char_shift[128] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; -uint8_t current_scancode = 0; -char decoded = 0; - bool caps_on = false; bool shift_on = false; void keyboard_interrupt(frame_struct* frame) { - current_scancode = inb(0x60); + uint8_t decoded = 0; + uint8_t current_scancode = inb(0x60); outb(0x20, 0x21); if ((current_scancode&0x7f) == 0x2a) shift_on = !(current_scancode&0x80); @@ -51,6 +49,15 @@ void keyboard_interrupt(frame_struct* frame) { decoded = key_to_char_caps[current_scancode&0x7f]; else decoded = key_to_char[current_scancode&0x7f]; + + if (current_scancode < 0x80) { + xnoe::linkedlist KBListeners = Global::kernel->KBListeners; + xnoe::linkedlistelem* current = KBListeners.start; + while (current) { + current->elem->stdin->write(1, &decoded); + current = current->next; + } + } } void init_keyboard() { diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 9fe80f4..1a73d97 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -46,8 +46,8 @@ int main() { Global::currentProc = &kernel; - Process* p1 = kernel.createProcess("WORLD BIN"); - kernel.createProcess("HELLO BIN"); + Process* p1 = kernel.createProcess("WORLD BIN", term); + //kernel.createProcess("HELLO BIN"); init_keyboard(); diff --git a/src/kernel/process.cpp b/src/kernel/process.cpp index 7735dac..845d117 100644 --- a/src/kernel/process.cpp +++ b/src/kernel/process.cpp @@ -35,6 +35,11 @@ Process::Process(uint32_t PID) Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename) : Allocator(new PageDirectory, new PageMap, (uint32_t)0, 3) { + this->stdout = 0; + this->stdin = 0; + + this->firstRun = true; + this->PID = PID; this->page_remaining = 0; this->last_page_pointer = 0; diff --git a/src/kernel/process.h b/src/kernel/process.h index 8a686dc..65fe9c1 100644 --- a/src/kernel/process.h +++ b/src/kernel/process.h @@ -10,6 +10,8 @@ #include "global.h" #include "atapio.h" +#include "stdio/readwriter.h" + struct AllocTracker { void* page_base; uint32_t page_size; @@ -37,6 +39,11 @@ public: void* kernelStackPtr; void* kernelStackPtrDefault; + ReadWriter* stdout; + ReadWriter* stdin; + + bool firstRun; + Process(uint32_t PID, void* stack, PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); Process(uint32_t PID); Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, char* filename); diff --git a/src/kernel/stdio/circularrwbuffer.cpp b/src/kernel/stdio/circularrwbuffer.cpp new file mode 100644 index 0000000..047ed62 --- /dev/null +++ b/src/kernel/stdio/circularrwbuffer.cpp @@ -0,0 +1,40 @@ +#include "circularrwbuffer.h" + +CircularRWBuffer::CircularRWBuffer(uint32_t reader, uint32_t writer) +: ReadWriter(0) { + this->giveReadPerm(reader); + this->giveWritePerm(writer); + + this->bufferSize = 3072; + this->buffer = new uint8_t[this->bufferSize]; + this->readPtr = 0; + this->writePtr = 0; +} + +int CircularRWBuffer::write(uint32_t count, uint8_t* buffer) { + int i=0; + while (i < count) { + this->buffer[this->writePtr] = buffer[i]; + + this->writePtr++; + if (this->writePtr == this->bufferSize) + this->writePtr = 0; + i++; + } + return i; +} + +int CircularRWBuffer::read(uint32_t count, uint8_t* buffer) { + int i=0; + while (i < count) { + if (this->readPtr == this->writePtr) + return 0; + buffer[i] = this->buffer[this->readPtr]; + + this->readPtr++; + if (this->readPtr == this->bufferSize) + this->readPtr = 0; + i++; + } + return i; +} \ No newline at end of file diff --git a/src/kernel/stdio/circularrwbuffer.h b/src/kernel/stdio/circularrwbuffer.h new file mode 100644 index 0000000..a179f40 --- /dev/null +++ b/src/kernel/stdio/circularrwbuffer.h @@ -0,0 +1,19 @@ +#ifndef CIRCULAR_RW_BUFFER_H +#define CIRCULAR_RW_BUFFER_H + +#include "readwriter.h" + +class CircularRWBuffer : public ReadWriter { +private: + uint8_t* buffer; + uint32_t readPtr; + uint32_t writePtr; + uint32_t bufferSize; +public: + CircularRWBuffer(uint32_t reader, uint32_t writer); + + int read(uint32_t count, uint8_t* buffer) override; + int write(uint32_t count, uint8_t* buffer) override; +}; + +#endif \ No newline at end of file diff --git a/src/kernel/stdio/readwriter.cpp b/src/kernel/stdio/readwriter.cpp new file mode 100644 index 0000000..b771ce9 --- /dev/null +++ b/src/kernel/stdio/readwriter.cpp @@ -0,0 +1,36 @@ +#include "readwriter.h" + +ReadWriter::ReadWriter(uint32_t owner) { + this->owner = owner; +} + +void ReadWriter::giveReadPerm(uint32_t PID) { + this->allowedRead.append(PID); +} + +void ReadWriter::giveWritePerm(uint32_t PID) { + this->allowedWrite.append(PID); +} + +int ReadWriter::read(uint32_t count, uint8_t* buffer){} +int ReadWriter::write(uint32_t count, uint8_t* buffer){} + +bool ReadWriter::canRead(uint32_t PID) { + if (this->owner == PID) + return true; + + if (this->allowedRead.has(PID)) + return true; + + return false; +} + +bool ReadWriter::canWrite(uint32_t PID) { + if (this->owner == PID) + return true; + + if (this->allowedWrite.has(PID)) + return true; + + return false; +} \ No newline at end of file diff --git a/src/kernel/stdio/readwriter.h b/src/kernel/stdio/readwriter.h new file mode 100644 index 0000000..65b81b8 --- /dev/null +++ b/src/kernel/stdio/readwriter.h @@ -0,0 +1,25 @@ +#ifndef READWRITER_H +#define READWRITER_H + +#include "../datatypes/linkedlist.h" +#include "../types.h" + +class ReadWriter { +private: + uint32_t owner; + xnoe::linkedlist allowedRead; + xnoe::linkedlist allowedWrite; + +public: + ReadWriter(uint32_t owner); + void giveReadPerm(uint32_t PID); + void giveWritePerm(uint32_t PID); + + virtual int read(uint32_t count, uint8_t* buffer); + virtual int write(uint32_t count, uint8_t* buffer); + uint32_t getOwner(); + bool canRead(uint32_t PID); + bool canWrite(uint32_t PID); +}; + +#endif \ No newline at end of file diff --git a/src/kernel/terminal.cpp b/src/kernel/terminal.cpp index 7c663dd..04b0551 100644 --- a/src/kernel/terminal.cpp +++ b/src/kernel/terminal.cpp @@ -31,7 +31,8 @@ void Terminal::update(){} void Terminal::update_cur(){} void Terminal::putchar_internal(uint32_t ptr, uint8_t c, uint8_t edata) {} -Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages) { +Terminal::Terminal(uint32_t width, uint32_t height, uint32_t pages) +: ReadWriter(0) { this->width = width; this->height = height; this->pages = pages; @@ -124,6 +125,18 @@ void Terminal::printf(const char* string, ...) { va_end(ptr); } +int Terminal::write(uint32_t count, uint8_t* buffer) { + char* buf = new char[count+1]; + for (int i=0;i -char key_to_char[128] = { - 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 0, - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0, - 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', - 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', - '1', '2', '3', '0', '.', 0, 0, 0, 0, 0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -char key_to_char_caps[128] = { - 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 0, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 0, - 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', '`', 0, '\\', - 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', - '1', '2', '3', '0', '.', 0, 0, 0, 0, 0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -char key_to_char_shift[128] = { - 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', 0, - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0, - 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', - 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', - '1', '2', '3', '0', '.', 0, 0, 0, 0, 0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - -bool caps_on = false; -bool shift_on = false; - -void readline(int max, char* buffer) { - int index = 0; - uint8_t current_scancode = getchPS2(); - - uint8_t char_print[2]; - char_print[0] = 0; - char_print[1] = 0; - - uint8_t scancode = 0; - while (scancode != 0x1c && index < max) { - scancode = current_scancode; - - char decoded = 0; - - if ((scancode&0x7f) == 0x2a) - shift_on = !(scancode&0x80); - - if (scancode == 0x3a) - caps_on ^= 1; - - if (shift_on) - decoded = key_to_char_shift[scancode&0x7f]; - else if (caps_on) - decoded = key_to_char_caps[scancode&0x7f]; - else - decoded = key_to_char[scancode&0x7f]; - - if (scancode == 0x0e) { - if (index > 0) { - buffer[--index] = 0; - print("\b"); - } - } else if (decoded && scancode < 0x80) { - buffer[index++] = decoded; - char_print[0] = decoded; - print(char_print); - } - - while (scancode == current_scancode) - current_scancode = getchPS2(); - } - print("\n"); -} - int main() { - print ("Hello from Ring 3!\n"); + bindToKeyboard(); + + print("Hello from Ring 3!\n"); - char buffer[128]; while (1) { - for (int i=0; i<128; i++) - buffer[i] = 0; - print(">>> "); - readline(128, buffer); - print("\nYou said: "); - print(buffer); - print("\n"); + char c; + if (read(1, 1, &c)) + write(1, 0, &c); } } \ No newline at end of file