diff --git a/exception_handler.c b/exception_handler.c index 91fcc99..a171e1c 100644 --- a/exception_handler.c +++ b/exception_handler.c @@ -5,7 +5,8 @@ __attribute__ ((interrupt)) void print_handler(struct interrupt_frame *frame, ulong error_code){ - printString("EXCEPTION", RED, BLACK, 0, 6); + printStringDetails("EXCEPTION", RED, BLACK, 0, 20); + printInt(error_code, RED, BLACK, 11, 20); (void) frame; (void) error_code; } diff --git a/irq_handler.c b/irq_handler.c index a6316dd..f881c17 100644 --- a/irq_handler.c +++ b/irq_handler.c @@ -11,8 +11,10 @@ __attribute__((interrupt)) void keyboard_handler(struct interrupt_frame *frame) char c = 0; if (inb(0x60) != c) { c = inb(0x60); - if (c > 0) - printChar(c, RED, BLACK, 0, 8); + if (c > 0){ + printChar(c); + printChar('\n'); + } } (void)frame; } @@ -21,6 +23,6 @@ __attribute__((interrupt)) void timer_handler(struct interrupt_frame *frame) { static int timeCnt = 0; EOIIrq(IRQ_TIMER); - printInt(timeCnt++, RED, BLACK, 0, 9); + printInt(timeCnt++, RED, BLACK, 20, VGA_HEIGHT -1 ); (void)frame; } diff --git a/klibc.c b/klibc.c new file mode 100644 index 0000000..e0aea0c --- /dev/null +++ b/klibc.c @@ -0,0 +1,11 @@ +#include "klibc.h" + +void *memcpy(void *dst, const void *src, size_t n) +{ + char *dstChar = dst; + const char *srcChar = src; + for (size_t i = 0; i < n; i++) { + *(dstChar++) = *(srcChar++); + } + return dst; +} diff --git a/klibc.h b/klibc.h new file mode 100644 index 0000000..02b3479 --- /dev/null +++ b/klibc.h @@ -0,0 +1,4 @@ +#pragma once +#include "types.h" + +void *memcpy(void *dest, const void *src, size_t n ); diff --git a/main.c b/main.c index 8fc016e..c9e52c7 100644 --- a/main.c +++ b/main.c @@ -8,18 +8,6 @@ #include "types.h" #include "vga.h" -char getScancode() -{ - char c = 0; - do { - if (inb(0x60) != c) { - c = inb(0x60); - if (c > 0) - return c; - } - } while (1); -} - void cpuid(int code, uint32_t *a, uint32_t *d) { asm volatile("cpuid" : "=a"(*a), "=d"(*d) : "0"(code) : "ebx", "ecx"); @@ -27,25 +15,23 @@ void cpuid(int code, uint32_t *a, uint32_t *d) void kmain() { - const short color = GREEN; - clearScreen(BLACK); - printString("Setting up IDT", color, BLACK, 0, 0); + initVGA(BLACK, GREEN); + printString("Setting up IDT\n"); gdtSetup(); idtSetup(); - printString("Setting up IRQ", color, BLACK, 0, 1); irqSetup(); initPit(100); - printString("Setting up IRQ handlers", color, BLACK, 0, 1); + printString("Setting up IRQ handlers\n"); irqSetRoutine(IRQ_KEYBOARD, keyboard_handler); irqSetRoutine(IRQ_TIMER, timer_handler); - printString("Enabling HW interrupts", color, BLACK, 0, 2); + printString("Enabling HW interrupts\n"); exceptionSetRoutine(EXCEPTION_DOUBLE_FAULT, print_handler); // Enabling the HW interrupts asm volatile("sti\n"); int count = 0; while (1) { - printInt(count++, color, BLACK, 0, 6); + printInt(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1); } - printString("exiting", color, BLACK, 0, 4); + printString("exiting\n"); } diff --git a/types.h b/types.h index 5f664c5..f816264 100644 --- a/types.h +++ b/types.h @@ -37,3 +37,11 @@ typedef __s64 int64_t; typedef enum { FALSE=0, TRUE } bool_t; #define NULL ((void*)0) + +#if __x86_64__ +typedef unsigned long size_t; +typedef long ssize_t; +#else +typedef unsigned int size_t; +typedef int ssize_t; +#endif diff --git a/vga.c b/vga.c index df3beba..b8714e6 100644 --- a/vga.c +++ b/vga.c @@ -1,4 +1,21 @@ #include "vga.h" +#include "io.h" +#include "klibc.h" +#include "tools.h" + +static uint vgaBgColor; +static uint vgaColor; +static uint line, col; + +int initVGA(uint bgColor, uint color) +{ + vgaBgColor = bgColor; + vgaColor = color; + clearScreen(bgColor); + line = 0; + col = 0; + return 0; +} void clearScreen(uint bgColor) { @@ -17,7 +34,7 @@ void printInt(int integer, uint color, uint bgColor, int startX, int startY) int x = startX; int i = 0, k = 0; if (integer < 0) { - printChar('-', color, bgColor, x++, startY); + printCharDetails('-', color, bgColor, x++, startY); } while (integer != 0) { int digit = integer % 10; @@ -25,24 +42,63 @@ void printInt(int integer, uint color, uint bgColor, int startX, int startY) integer = integer / 10; } for (k = i - 1; k >= 0; k--) { - printChar(num[k] + '0', color, bgColor, x++, startY); + printCharDetails(num[k] + '0', color, bgColor, x++, startY); } } -void printChar(const char str, uint color, uint bgColor, int startX, int startY) +void printCharDetails(const char str, uint color, uint bgColor, int startX, int startY) { volatile short *vga = (short *)VGA_ADDR; long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8; - vga[80 * startY + startX] = colorAttr | str; + vga[VGA_WIDTH * startY + startX] = colorAttr | str; } -void printString(const char *str, uint color, uint bgColor, int startX, int startY) +void vgaScrollUp(void) +{ + long int colorAttr = vgaBgColor << 12; + volatile short *vga = (short *)VGA_ADDR; + for (int i = 1; i < VGA_HEIGHT - 2; i++) { // last line is status line. Do not scroll it + memcpy((void *)&vga[VGA_WIDTH * (i - 1)], (void *)&vga[VGA_WIDTH * i], + VGA_WIDTH * sizeof(short)); + } + for(int i = 0; i < VGA_WIDTH; i++){ + vga[(VGA_HEIGHT - 1) * VGA_WIDTH + i] = colorAttr; + } +} + +void printString(const char *str) { + while (*str) { + printChar(*(str++)); + } + +} + +void printChar(const char str) +{ + if (str == '\n') { + line++; + col = 0; + } + if (col == VGA_WIDTH) { + col = 0; + line++; + } + if (line >= VGA_HEIGHT) { + vgaScrollUp(); + line--; + } + if(str == '\n') + return; + printCharDetails(str, vgaColor, vgaBgColor, col++, line); +} + +void printStringDetails(const char *str, uint color, uint bgColor, int startX, int startY) { volatile short *vga = (short *)VGA_ADDR; int i = 0; long int colorAttr = (bgColor << 4 | (color & 0x0f)) << 8; while (*str) { - vga[80 * startY + startX + i] = colorAttr | *str; + vga[VGA_WIDTH * startY + startX + i] = colorAttr | *str; str++; i++; } diff --git a/vga.h b/vga.h index 62881f8..70dbde9 100644 --- a/vga.h +++ b/vga.h @@ -16,7 +16,11 @@ #define VGA_WIDTH 80 #define VGA_HEIGHT 25 +int initVGA(uint bgColor, uint color); void clearScreen(uint bgColor); void printInt(int integer, uint color, uint bgColor, int startX, int startY); -void printChar(char str, uint color, uint bgColor, int startX, int startY); -void printString(const char *str, uint color, uint bgColor, int startX, int startY); +void printCharDetails(char str, uint color, uint bgColor, int startX, int startY); +void printStringDetails(const char *str, uint color, uint bgColor, int startX, int startY); +void printString(const char *str); +void printChar(const char str); +void vgaScrollUp(void);