Update keyboard driver, add start of file handlers, stdio.

This commit is contained in:
Xnoe 2022-01-13 13:36:24 +00:00
parent fc2c73225b
commit 55a5bea35a
Signed by: xnoe
GPG Key ID: 45AC398F44F0DAFE
23 changed files with 301 additions and 153 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -22,6 +22,16 @@ namespace xnoe {
xnoe::linkedlistelem<T>* start;
xnoe::linkedlistelem<T>* end;
bool has(T t) {
xnoe::linkedlistelem<T>* current = this->start;
while (start) {
if (start->elem == t)
return true;
}
return false;
}
void append(T t) {
xnoe::linkedlistelem<T>* llelem = new xnoe::linkedlistelem<T>(t);
append(llelem);

View File

@ -1,7 +1,7 @@
[BITS 32]
_start:
mov esp, 0xc1005ffc
mov esp, 0xc100a000
jmp main
extern main

View File

@ -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<ReadWriter*> 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<ReadWriter*> 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;
}

View File

@ -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;

View File

@ -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);

View File

@ -14,14 +14,17 @@ public:
Terminal* terminal;
xnoe::hashtable<uint32_t, Process*>* pid_map; // Map of PIDs -> Process*s
xnoe::hashtable<void*, ReadWriter*>* FH; // Map of File Handlers -> Read Writer
xnoe::linkedlist<Process*> processes;
xnoe::linkedlist<Process*> 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();
};

View File

@ -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<Process*> KBListeners = Global::kernel->KBListeners;
xnoe::linkedlistelem<Process*>* current = KBListeners.start;
while (current) {
current->elem->stdin->write(1, &decoded);
current = current->next;
}
}
}
void init_keyboard() {

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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<uint32_t> allowedRead;
xnoe::linkedlist<uint32_t> 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

View File

@ -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<count;i++) {
buf[i] = buffer[i];
}
buf[count] = 0;
printf(buf);
delete buf;
}
int Terminal::read(uint32_t count, uint8_t* buffer) {}
void Terminal::clear_screen() {
for (int i=0; i < width * height * pages; i++) {
buffer[i] = 0;

View File

@ -8,7 +8,9 @@
#include "strings.h"
#include "io.h"
class Terminal {
#include "stdio/readwriter.h"
class Terminal: public ReadWriter {
private:
virtual void update();
virtual void update_cur();
@ -36,6 +38,9 @@ public:
void printf(const char* string, ...);
int write(uint32_t count, uint8_t* buffer) override;
int read(uint32_t count, uint8_t* buffer) override;
void clear_screen();
void set_curpos(int x, int y);

View File

@ -2,6 +2,7 @@
_start:
call main
int 0x80
_loop:
jmp _loop
extern main

View File

@ -1,94 +1,14 @@
#include "../common/common.h"
#include <stdbool.h>
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);
}
}