diff --git a/.gitignore b/.gitignore index 8db6706..eb3a9e2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ *.sector *.o img.d/ -build/ \ No newline at end of file +build/ +isr.S \ No newline at end of file diff --git a/src/program/hello.c b/src/hello/hello.c similarity index 88% rename from src/program/hello.c rename to src/hello/hello.c index 717a8aa..e2f46b5 100644 --- a/src/program/hello.c +++ b/src/hello/hello.c @@ -5,6 +5,7 @@ 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/program/hello.ld b/src/hello/hello.ld similarity index 71% rename from src/program/hello.ld rename to src/hello/hello.ld index 8503d53..0ccfd55 100644 --- a/src/program/hello.ld +++ b/src/hello/hello.ld @@ -1,14 +1,14 @@ OUTPUT_FORMAT(binary) OUTPUT_ARCH(i386:i386) -OUTPUT(build/program/hello.bin) +OUTPUT(build/hello/hello.bin) SECTIONS { . = 0x8020; .text : { build/program_code_entry.o(.text) - build/program/hello.o(.text) + build/hello/hello.o(.text) build/common/common.o(.text) } } \ No newline at end of file diff --git a/src/kernel/gen_isr_asm.sh b/src/kernel/gen_isr_asm.sh new file mode 100755 index 0000000..0329ee6 --- /dev/null +++ b/src/kernel/gen_isr_asm.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env zsh + +test -f isr.S && rm isr.S +cp isr.S.base isr.S + +for i ({0..255}); do + cat >> isr.S << EOF +isr$i: + push ebp + mov ebp, esp + push $i + jmp catchall +EOF +done + +x="" +for i ({0..255}); do + if [ $i = 255 ]; then + x="$x isr$i" + else + x="$x isr$i," + fi +done + +echo "isrs dd $x" >> isr.S \ No newline at end of file diff --git a/src/kernel/global.cpp b/src/kernel/global.cpp index 42304ab..96f76cf 100644 --- a/src/kernel/global.cpp +++ b/src/kernel/global.cpp @@ -5,6 +5,7 @@ namespace Global { Kernel* kernel = 0; Process* currentProc = 0; tss_struct* tss = 0; + bool currentProcValid = true; } void* operator new (uint32_t size) { diff --git a/src/kernel/global.h b/src/kernel/global.h index c1bba8c..a35a93a 100644 --- a/src/kernel/global.h +++ b/src/kernel/global.h @@ -13,6 +13,7 @@ namespace Global { extern Kernel* kernel; extern Process* currentProc; extern tss_struct* tss; + extern bool currentProcValid; } void* operator new (uint32_t size); diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 87d00b7..bfd3bd8 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -2,7 +2,11 @@ GateEntry idt[256]; -void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type, uint8_t privilege) { +void(*gates[256])(frame_struct*); + +extern void(*isrs[256])(void); + +void set_entry(uint8_t interrupt_number, uint16_t code_segment, void(*handler)(), uint8_t type, uint8_t privilege) { uint32_t handler_addr = (uint32_t)handler; uint16_t* handler_halves = (uint16_t*)&handler_addr; idt[interrupt_number] = (GateEntry) { @@ -17,28 +21,41 @@ void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, u }; } -__attribute__((interrupt)) void interrupt_20(interrupt_frame* frame) { -// printf("Interrupt 20 received!!\n"); - outb(0x20, 0x20); -} - -__attribute__((interrupt)) void page_fault(interrupt_frame* frame, uint32_t err_code) { +void page_fault(frame_struct* frame, uint32_t err_code) { uint32_t problem_address; asm("mov %%cr2, %0" : "=a" (problem_address) :); - printf("(EIP %x): Page Fault at %x\n", frame->eip, problem_address); - while (1) asm("hlt"); + Global::kernel->terminal->printf("(EIP %x): Page Fault at %x\n", frame->eip, problem_address); + if (frame->cs & 3 == 0) { + Global::kernel->terminal->printf("[FATAL] Kernel Page Fault!!!\n"); + while (1) asm("hlt"); + } else { + // Print an error message. + Global::kernel->terminal->printf("PID %d Terminated due to page fault!\n", Global::currentProc->PID); + // We are currently in the kernel stack for the current process so we need to load the main kernel stack in to esp. + //Global::kernel->loadPrimaryStack(); + + asm volatile ("mov %0, %%esp" ::"m"(Global::kernel->stack)); + + // We can now safely delete the current process + Global::kernel->destroyProcess(Global::currentProc); + + // We want to load the kernel's page directory too. + //Global::kernel->PD->select(); + + //Global::currentProcValid = false; + asm ("int $0x20"); // Call context switch. + while (1) asm("hlt"); + } } -__attribute__((interrupt)) void ignore_interrupt(interrupt_frame* frame) { - outb(0x20, 0x20); -} +void ignore_interrupt(frame_struct* frame) {} -__attribute__((interrupt)) void gpf(interrupt_frame* frame, uint32_t err_code) { +void gpf(frame_struct* frame, uint32_t err_code) { printf("General Protection Fault %x\n", err_code); while (1) asm("hlt"); } -__attribute__((interrupt)) void context_switch(interrupt_frame* frame) { +void context_switch(frame_struct* frame) { // When any interrupt occurs (including context_switch), SS:ESP is set to // the values of SS0:ESP0 in Global::tss // @@ -53,80 +70,86 @@ __attribute__((interrupt)) void context_switch(interrupt_frame* frame) { // to iret asm ("cli"); // Disable interrupts whilst handling the context switch. - asm ("pusha"); // Push registers to the stack - //asm ("pushf"); // Push flags to the stack - Process* currentProc = Global::currentProc; + // Restore eax + asm ("mov %0, %%eax"::"r"(frame->eax)); + + Process* currentProc = 0; Process* nextProc = 0; - // Write current esp to currentProc->kernelStackPtr - asm ("mov %%esp, %0" : "=a" (currentProc->kernelStackPtr):); + if (Global::currentProcValid) { + currentProc = Global::currentProc; + // Write current esp to currentProc->kernelStackPtr + asm ("mov %%esp, %0" : "=a" (currentProc->kernelStackPtr):); + } - if (currentProc) { + if (currentProc || !Global::currentProcValid) { xnoe::linkedlist* processes = &Global::kernel->processes; // This cursed bit of code first determines if the processes list is longer than 1 and if it is // - Determines if it has 2 or more elements // - If it has two, swap the first and last, update prev and next of each to be null or the other item // - If it has more than two, add the start to the end then set start to the second element - if (processes->start->next != 0) { - if (processes->end->prev == processes->start) { - xnoe::linkedlistelem* tmp = processes->start; - processes->start = processes->end; - processes->end = tmp; + if (processes->start) { + if (processes->start->next != 0) { + if (processes->end->prev == processes->start) { + xnoe::linkedlistelem* tmp = processes->start; + processes->start = processes->end; + processes->end = tmp; - processes->start->prev = 0; - processes->end->next = 0; - processes->end->prev = processes->start; - processes->start->next = processes->end; - } else { - processes->end->next = processes->start; - processes->start = processes->start->next; - processes->start->prev = 0; - xnoe::linkedlistelem* tmp = processes->end; - processes->end = processes->end->next; - processes->end->next = 0; - processes->end->prev = tmp; + processes->start->prev = 0; + processes->end->next = 0; + processes->end->prev = processes->start; + processes->start->next = processes->end; + } else { + processes->end->next = processes->start; + processes->start = processes->start->next; + processes->start->prev = 0; + xnoe::linkedlistelem* tmp = processes->end; + processes->end = processes->end->next; + processes->end->next = 0; + processes->end->prev = tmp; + } } } // Get the next process. - nextProc = processes->start->elem; + if (processes->start) + nextProc = processes->start->elem; + + if (nextProc == 0) { + Global::kernel->terminal->printf("[FATAL] No more processes! Halting!\n"); + while (1) asm ("hlt"); + } Global::currentProc = nextProc; - //uint32_t cESP; - //asm volatile ("mov %%esp, %0" : "=a" (cESP) :); - //currentProc->esp = cESP; // Store the current ESP of the current process process. - - outb(0x20, 0x20); - // Select the next processes page directory asm volatile ("mov %0, %%cr3" : : "r" (nextProc->PD->phys_addr)); // Restore kernelStackPtr of the new process. asm volatile ("mov %0, %%esp" : : "m" (Global::kernel->processes.start->elem->kernelStackPtr)); // At this point interrupts are disabled till iret so we can safely set - // Global::tss->esp0 - // to the new Process's kernelStackPtrDefault + // Global::tss->esp0 to the new Process's kernelStackPtrDefault Global::tss->esp0 = Global::kernel->processes.start->elem->kernelStackPtrDefault; - //asm ("popf"); // Pop flags - asm ("popa"); // Restore registers - asm ("mov -0xc(%ebp), %eax"); // Restore the initial eax - // Clear the garbage that was on the stack from previous switch_context call. - asm ("mov %ebp, %esp"); - asm ("pop %ebp"); // Pop EBP + // Set the current proc to valid + Global::currentProcValid = true; - asm ("iret"); // Manually perform iret. + uint32_t* espVal; + asm ("mov %%esp, %0":"=a"(espVal):); + if (*espVal == 0) { + asm("add $4, %esp"); + asm("ret"); + } } } extern uint8_t current_scancode; extern char decoded; -__attribute__((interrupt)) void syscall(interrupt_frame* frame) { +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) @@ -138,17 +161,11 @@ __attribute__((interrupt)) void syscall(interrupt_frame* frame) { // 7: fork: create process from filename (in esi: char* filename) // 8: getPID: returns the current process's PID (out eax: uint32_t) - uint32_t* ebp; - asm("mov %%ebp, %0" : "=a" (ebp) :); - uint32_t eax = *(ebp-4); - uint32_t rval = eax; + uint32_t rval = frame->eax; - uint32_t syscall_number; - uint32_t esi; - uint32_t edi; - asm("mov %%esi, %0" : "=a" (esi) :); - asm("mov %%edi, %0" : "=a" (edi) :); - switch (eax) { + uint32_t esi = frame->esi; + uint32_t edi = frame->edi; + switch (frame->eax) { case 0: Global::kernel->terminal->printf("%s", (char*)esi); break; @@ -181,22 +198,25 @@ __attribute__((interrupt)) void syscall(interrupt_frame* frame) { break; } - asm volatile ("mov %0, %%eax" : : "m" (rval)); - asm ("mov %ebp, %esp"); - asm ("pop %ebp"); - asm ("iret"); + frame->eax = rval; } void init_idt() { idt_desc desc = {.size = 256 * sizeof(GateEntry) - 1, .offset = (uint32_t)idt}; asm volatile("lidt %0" : : "m" (desc)); + for (int i=0; i<256; i++) - set_entry(i, 0x08, &ignore_interrupt, 0x8E); + set_entry(i, 0x08, isrs[i], 0xE); + + for (int i=0; i<256; i++) + gates[i] = &ignore_interrupt; - set_entry(0x20, 0x08, &context_switch, 0xE); - set_entry(0xD, 0x08, &gpf, 0xE); - set_entry(0xE, 0x08, &page_fault, 0xE); - set_entry(0x7f, 0x08, &syscall, 0xE, 3); + gates[0x20] = &context_switch; + gates[0xd] = &gpf; + gates[0xe] = &page_fault; + gates[0x7f] = &syscall; + + idt[0x7f].privilege = 3; outb(0x20, 0x11); outb(0xA0, 0x11); diff --git a/src/kernel/idt.h b/src/kernel/idt.h index 3f3ea5e..9d5f48b 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -7,14 +7,28 @@ #include "kernel.h" #include "gdt.h" -struct interrupt_frame { - uint32_t eip; - uint16_t cs; - uint16_t _ignored0; - uint32_t eflags; +struct __attribute__((packed)) frame_struct { + uint32_t edi; + uint32_t esi; + uint32_t ebp; + uint32_t oesp; + uint32_t ebx; + uint32_t edx; + uint32_t ecx; + uint32_t eax; + uint32_t eip; + uint16_t cs; + uint16_t _ignored0; + uint32_t eflags; + uint16_t ss; + uint16_t _ignored1; + uint32_t esp; }; + +extern void(*gates[256])(frame_struct*); + extern void load_idt(); -void set_entry(uint8_t interrupt_number, uint16_t code_segment, void* handler, uint8_t type, uint8_t privilege = 0); +void set_entry(uint8_t interrupt_number, uint16_t code_segment, void(*handler)(), uint8_t type, uint8_t privilege = 0); void init_idt(); void enable_idt(); @@ -27,11 +41,11 @@ struct __attribute__((packed)) GateEntry{ uint8_t privilege : 2; uint8_t present : 1; uint16_t offset_high; -} ; +}; struct __attribute__((packed)) idt_desc { uint16_t size; uint32_t offset; -} ; +}; #endif \ No newline at end of file diff --git a/src/kernel/io.cpp b/src/kernel/io.cpp index ae78e65..6d600ea 100644 --- a/src/kernel/io.cpp +++ b/src/kernel/io.cpp @@ -1,19 +1,21 @@ #include "io.h" -void outb(uint16_t portnumber, uint8_t data) { - asm volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber)); -} -uint8_t inb(uint16_t portnumber) { - uint8_t result; - asm volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber)); - return result; -} +extern "C" { + void outb(uint16_t portnumber, uint8_t data) { + asm volatile("outb %0, %1" : : "a" (data), "Nd" (portnumber)); + } + uint8_t inb(uint16_t portnumber) { + uint8_t result; + asm volatile("inb %1, %0" : "=a" (result) : "Nd" (portnumber)); + return result; + } -void outw(uint16_t portnumber, uint16_t data) { - asm volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber)); -} -uint16_t inw(uint16_t portnumber) { - uint16_t result; - asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber)); - return result; + void outw(uint16_t portnumber, uint16_t data) { + asm volatile("outw %0, %1" : : "a" (data), "Nd" (portnumber)); + } + uint16_t inw(uint16_t portnumber) { + uint16_t result; + asm volatile("inw %1, %0" : "=a" (result) : "Nd" (portnumber)); + return result; + } } \ No newline at end of file diff --git a/src/kernel/io.h b/src/kernel/io.h index 8df8ec6..a6a2919 100644 --- a/src/kernel/io.h +++ b/src/kernel/io.h @@ -3,10 +3,12 @@ #include "types.h" -void outb(uint16_t portnumber, uint8_t data); -uint8_t inb(uint16_t portnumber); +extern "C" { + void outb(uint16_t portnumber, uint8_t data); + uint8_t inb(uint16_t portnumber); -void outw(uint16_t portnumber, uint16_t data); -uint16_t inw(uint16_t portnumber); + void outw(uint16_t portnumber, uint16_t data); + uint16_t inw(uint16_t portnumber); +} #endif \ No newline at end of file diff --git a/src/kernel/isr.S.base b/src/kernel/isr.S.base new file mode 100644 index 0000000..f22c79a --- /dev/null +++ b/src/kernel/isr.S.base @@ -0,0 +1,52 @@ +[BITS 32] + +global isrs + +global catchall_return + +catchall: ; At this point the gate number has been pushed to the stack + pushad ; Pushed 32 bytes + mov eax, [esp+32] + mov ebx, gates + mov eax, [ebx+4*eax] + push esp + call eax + +catchall_return: + add esp, 4 + + push 0x20 + push 0x20 + call outb + add esp, 8 + + popad + mov esp, ebp + pop ebp + iret + +extern gates ; (void(*)(frame_struct))* +extern outb + +; struct frame_struct __attribute__((packed)) { +; popad +; uint32_t edi; +; uint32_t esi; +; uint32_t ebp; +; uint32_t esp; +; uint32_t ebx; +; uint32_t edx; +; uint32_t ecx; +; uint32_t eax; +; +; interrupt +; uint32_t eip; +; uint32_t cs; +; uint32_t eflags; +; uint32_t esp; +; uint32_t ss; +; +; if it's an error +; uint32_t err_code; +; } + diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 698d880..5fedaed 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -1,6 +1,6 @@ #include "kernel.h" -Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base) +Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base, uint32_t stack) : Process(0, 0x8a000, page_directory, phys, virt, virt_alloc_base) { this->currentPID = 1; @@ -9,6 +9,8 @@ Kernel::Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint Global::currentProc = 0; + this->stack = stack; + //this->processes.append(this); } @@ -30,5 +32,8 @@ void Kernel::destroyProcess(Process* p) { this->processes.remove(p); this->pid_map->remove(p->PID, p); delete p; - while (1); -} \ No newline at end of file +} + +//void Kernel::loadPrimaryStack() { +// asm volatile("mov %0, %%esp"::"m"(this->stack - 64)); +//} \ No newline at end of file diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 68eff3c..3cbd618 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -9,18 +9,20 @@ class Kernel : public Process { public: uint32_t currentPID; + uint32_t stack; Terminal* terminal; xnoe::hashtable* pid_map; // Map of PIDs -> Process*s xnoe::linkedlist processes; - Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base); + Kernel(PageDirectory* page_directory, PageMap* phys, PageMap* virt, uint32_t virt_alloc_base, uint32_t stack); void init_kernel(); Process* createProcess(char* filename); void destroyProcess(Process* p); + //void loadPrimaryStack(); }; #endif \ No newline at end of file diff --git a/src/kernel/keyboard.cpp b/src/kernel/keyboard.cpp index 6c1fc07..163f579 100644 --- a/src/kernel/keyboard.cpp +++ b/src/kernel/keyboard.cpp @@ -36,7 +36,7 @@ char decoded = 0; bool caps_on = false; bool shift_on = false; -__attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame) { +void keyboard_interrupt(frame_struct* frame) { current_scancode = inb(0x60); outb(0x20, 0x21); if ((current_scancode&0x7f) == 0x2a) @@ -54,7 +54,8 @@ __attribute__((interrupt)) void keyboard_interrupt(struct interrupt_frame* frame } void init_keyboard() { - set_entry(0x21, 0x08, &keyboard_interrupt, 0x8E); + //set_entry(0x21, 0x08, &keyboard_interrupt, 0x8E); + gates[0x21] = &keyboard_interrupt; while (inb(0x64) & 1) { inb(0x60); diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 23f29f2..9fe80f4 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -27,7 +27,7 @@ int main() { PageMap phys_pm(0xc0600000); PageMap virt_pm(0xc0620000); - Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000); + Kernel kernel = Kernel(&kernel_pd, &phys_pm, &virt_pm, 0xc0000000, 0xc1006000); kernel.init_kernel(); init_atapio(); @@ -47,6 +47,7 @@ int main() { Global::currentProc = &kernel; Process* p1 = kernel.createProcess("WORLD BIN"); + kernel.createProcess("HELLO BIN"); init_keyboard(); diff --git a/src/kernel/process.cpp b/src/kernel/process.cpp index 797b4d3..a0dd0ad 100644 --- a/src/kernel/process.cpp +++ b/src/kernel/process.cpp @@ -1,5 +1,7 @@ #include "process.h" +extern void(*catchall_return)(); + AllocTracker::AllocTracker(void* base, uint32_t size, uint32_t count) : page_base(base), page_size(size), alloc_count(count) {} xnoe::Maybe*> Process::get_alloc_tracker(uint32_t address) { @@ -68,8 +70,6 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha uint32_t rEBP = stack32; - stack32 -= 21; - stack32--; *stack32 = 0; // EAX stack32--; @@ -87,6 +87,13 @@ Process::Process(uint32_t PID, PageDirectory* inherit, uint32_t inheritBase, cha stack32--; *stack32 = 0; // EDI + stack32--; + + stack32--; + *stack32 = &catchall_return; // cachall_return + + stack32--; + this->kernelStackPtr = stack32; load_file(filename, program_data); diff --git a/src/kernel/terminal.cpp b/src/kernel/terminal.cpp index 52bfe59..7c663dd 100644 --- a/src/kernel/terminal.cpp +++ b/src/kernel/terminal.cpp @@ -58,6 +58,20 @@ void Terminal::printf(const char* string, ...) { this->cur_y++; } + if (current == '\b') { + if (this->cur_x > 0) { + this->cur_x--; + } else { + this->cur_y--; + this->cur_x = this->width-1; + } + + int mem_pos = this->cur_y * this->width + this->cur_x; + + this->putchar(mem_pos, ' '); + continue; + } + if (this->cur_x == this->width) { this->cur_x = 0; this->cur_y++; diff --git a/src/program/world.c b/src/world/world.c similarity index 92% rename from src/program/world.c rename to src/world/world.c index 01a0f8f..6ccfe90 100644 --- a/src/program/world.c +++ b/src/world/world.c @@ -2,7 +2,7 @@ #include char key_to_char[128] = { - 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, 0, + 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, @@ -12,7 +12,7 @@ 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, + 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, @@ -22,7 +22,7 @@ char key_to_char_caps[128] = { }; char key_to_char_shift[128] = { - 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, 0, + 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, @@ -54,12 +54,6 @@ void readline(int max, char* buffer) { if (scancode == 0x3a) caps_on ^= 1; - /*if (scancode == 0x0e && index > 0) { - set_curpos_raw(get_curpos()-1); - non_moving_put(' '); - buffer[--index] = 0; - }*/ - if (shift_on) decoded = key_to_char_shift[scancode&0x7f]; else if (caps_on) @@ -67,7 +61,12 @@ void readline(int max, char* buffer) { else decoded = key_to_char[scancode&0x7f]; - if (decoded && scancode < 0x80) { + 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); diff --git a/src/program/world.ld b/src/world/world.ld similarity index 71% rename from src/program/world.ld rename to src/world/world.ld index 055bbc1..db6a260 100644 --- a/src/program/world.ld +++ b/src/world/world.ld @@ -1,14 +1,14 @@ OUTPUT_FORMAT(binary) OUTPUT_ARCH(i386:i386) -OUTPUT(build/program/world.bin) +OUTPUT(build/world/world.bin) SECTIONS { . = 0x8020; .text : { build/program_code_entry.o(.text) - build/program/world.o(.text) + build/world/world.o(.text) build/common/common.o(.text) } } \ No newline at end of file