diff --git a/Makefile b/Makefile index ff90bb0..ee896a8 100644 --- a/Makefile +++ b/Makefile @@ -49,8 +49,8 @@ bin/shade.iso: bin/shade.bin rm src/iso/boot/shade.bin bin/shade.bin: $(sboot_object_files) $(kernel_object_files) $(libc_object_files) - echo "#ifndef VERSION_H" > include/shade/version.h - echo "#define VERSION_H" >> include/shade/version.h + echo "#ifndef SHADE_VERSION_H" > include/shade/version.h + echo "#define SHADE_VERSION_H" >> include/shade/version.h echo "// This file was autogenerated by the shadeOS build system. It should not be modified." >> include/shade/version.h echo "#define SHADE_OS_KERNEL_VERSION \"$(version)\"" >> include/shade/version.h echo "#define SHADE_OS_KERNEL \"$(stream)\"" >> include/shade/version.h diff --git a/bin/shade.bin b/bin/shade.bin index 612328a..a20093f 100755 Binary files a/bin/shade.bin and b/bin/shade.bin differ diff --git a/bin/shade.iso b/bin/shade.iso index a7b2e85..564e088 100644 Binary files a/bin/shade.iso and b/bin/shade.iso differ diff --git a/include/shade/cansid.h b/include/shade/cansid.h index 946f76d..0358806 100644 --- a/include/shade/cansid.h +++ b/include/shade/cansid.h @@ -1,5 +1,5 @@ -#ifndef CANSID_H -#define CANSID_H +#ifndef SHADE_CANSID_H +#define SHADE_CANSID_H typedef struct { enum { diff --git a/include/shade/kmsg.h b/include/shade/kmsg.h index 9f57212..104513a 100644 --- a/include/shade/kmsg.h +++ b/include/shade/kmsg.h @@ -1,10 +1,28 @@ -#ifndef KMSG_H -#define KMSG_H +#ifndef SHADE_KMSG_H +#define SHADE_KMSG_H #include +/** + * @brief [ ok ] + * + * @param format + * @param ... + */ void kmsg_ok(char* format, ...); +/** + * @brief [ warn ] + * + * @param format + * @param ... + */ void kmsg_warn(char* format, ...); +/** + * @brief [ fail ] + * + * @param format + * @param ... + */ void kmsg_fail(char* format, ...); #endif \ No newline at end of file diff --git a/include/shade/platform/drivers/keyboard.h b/include/shade/platform/drivers/keyboard.h index 1b7cdec..3a3077c 100644 --- a/include/shade/platform/drivers/keyboard.h +++ b/include/shade/platform/drivers/keyboard.h @@ -1,5 +1,5 @@ -#ifndef KEYBOARD_H -#define KEYBOARD_H +#ifndef SHADE_KEYBOARD_H +#define SHADE_KEYBOARD_H void init_keyboard(); diff --git a/include/shade/platform/drivers/vga_text_mode.h b/include/shade/platform/drivers/vga_text_mode.h index abf8f2a..67da5a8 100644 --- a/include/shade/platform/drivers/vga_text_mode.h +++ b/include/shade/platform/drivers/vga_text_mode.h @@ -1,5 +1,8 @@ -#ifndef PRINT_H -#define PRINT_H +#ifndef SHADE_PRINT_H +#define SHADE_PRINT_H + +#include + #define REG_SCREEN_CTRL 0x3d4 #define REG_SCREEN_DATA 0x3d5 @@ -48,4 +51,6 @@ void kernel_msg_ok(char* msg); void init_state(); +tty_driver_t vga_text_mode_get_driver(); + #endif \ No newline at end of file diff --git a/include/shade/platform/gdt.h b/include/shade/platform/gdt.h index 4ad3f8a..664ab29 100644 --- a/include/shade/platform/gdt.h +++ b/include/shade/platform/gdt.h @@ -1,5 +1,5 @@ -#ifndef GDT_H -#define GDT_H +#ifndef SHADE_GDT_H +#define SHADE_GDT_H #define KERNEL_CODE 0x08 #define KERNEL_DATA 0x10 diff --git a/include/shade/platform/interrupts/idt.h b/include/shade/platform/interrupts/idt.h index b3b328e..4043214 100644 --- a/include/shade/platform/interrupts/idt.h +++ b/include/shade/platform/interrupts/idt.h @@ -1,5 +1,5 @@ -#ifndef IDT_H -#define IDT_H +#ifndef SHADE_IDT_H +#define SHADE_IDT_H #include #include diff --git a/include/shade/platform/interrupts/isr.h b/include/shade/platform/interrupts/isr.h index eb6ec96..af36ee2 100644 --- a/include/shade/platform/interrupts/isr.h +++ b/include/shade/platform/interrupts/isr.h @@ -1,5 +1,5 @@ -#ifndef ISR_H -#define ISR_H +#ifndef SHADE_ISR_H +#define SHADE_ISR_H #include diff --git a/include/shade/platform/interrupts/pic.h b/include/shade/platform/interrupts/pic.h index d83689e..d5e5532 100644 --- a/include/shade/platform/interrupts/pic.h +++ b/include/shade/platform/interrupts/pic.h @@ -1,5 +1,5 @@ -#ifndef PIC_H -#define PIC_H +#ifndef SHADE_PIC_H +#define SHADE_PIC_H #include diff --git a/include/shade/platform/ports.h b/include/shade/platform/ports.h index b5b0524..f406401 100644 --- a/include/shade/platform/ports.h +++ b/include/shade/platform/ports.h @@ -1,5 +1,5 @@ -#ifndef PORTS_H -#define PORTS_H +#ifndef SHADE_PORTS_H +#define SHADE_PORTS_H unsigned char inb(unsigned short port); void outb(unsigned short port, unsigned char data); diff --git a/include/shade/tty.h b/include/shade/tty.h new file mode 100644 index 0000000..ad39e3d --- /dev/null +++ b/include/shade/tty.h @@ -0,0 +1,137 @@ +#ifndef SHADE_TTY_H +#define SHADE_TTY_H + +#include +#include + +/** + * @brief A type to represent a tty driver + * + */ +typedef struct tty_driver_struct { + int max_rows; + int max_cols; + + void (*putchar) (char c, int x, int y, char style); + void (*setcurxy) (int x, int y); +} tty_driver_t; + +/** + * @brief A type to represent a tty + * + */ +typedef struct tty_struct { + // size information + int rows; + int cols; + + // cursor information + int cursor_row; + int cursor_col; + + // stateful information + cansid_state cansid; + + // buffers + tty_ochar_t output_buffer[65536]; + char input_buffer[1024]; + + // driver + tty_driver_t driver; + + // flags + bool active; +} tty_t; + +/** + * @brief A type to represent a printable char + * + */ +typedef struct tty_ochar_struct { + char character; + char style; +} tty_ochar_t; + +tty_t ttys[10]; +int active_tty; + +/** + * @brief Create a new tty_t with the provided driver + * + * @param driver + * @return tty_t + */ +tty_t tty_new(tty_driver_t driver); + +/** + * @brief Switch the screen to the provided tty - clear screen and flip to that tty + * + * @param index + */ +void tty_switch(int index); + +/** + * @brief Print the specified char c on the tty tty, at the current cursor location + * + * @param tty + * @param c + * @see tty_mvpchar + */ +void tty_pchar(int tty, char c); +/** + * @brief Print the specified char t to the tty tty, but move the cursor to x, y first. + * + * @param tty + * @param c + * @param x + * @param y + * @see tty_pchar + */ +void tty_mvpchar(int tty, char c, int x, int y); + +// tty_pnl family +/** + * @brief Print a newline at the current cursor location on the tty tty. + * + * @param tty + * @see tty_mvpnl + */ +void tty_pnl(int tty); +/** + * @brief Move to the specified cursor location and print a newline. + * + * @param tty + * @param c + * @param x + * @param y + * @see tty_pnl + */ +void tty_mvpnl(int tty, int x, int y); + +// tty_clr family +/** + * @brief Clear the entire screen of the specified tty. Uses tty_clrl internally. + * + * @param tty + * @see tty_clrl + */ +void tty_clr(int tty); +/** + * @brief Clear the specified line of the specified tty. + * + * @param tty + * @param line + * @see tty_clr + */ +void tty_clrl(int tty, int line); + +/** + * @brief Set the cursor position on the specified tty to the specified position. + * + * @param tty + * @param x + * @param y + */ +void tty_setcurxy(int tty, int x, int y); + +#endif \ No newline at end of file diff --git a/include/shade/util.h b/include/shade/util.h index 9985e39..fce4514 100644 --- a/include/shade/util.h +++ b/include/shade/util.h @@ -1,10 +1,25 @@ -#ifndef UTIL_H -#define UTIL_H +#ifndef SHADE_UTIL_H +#define SHADE_UTIL_H #define IS_DIGIT(x) (x == '0' || x == '1' || x == '2' || x == '3' || x == '4' || x == '5' || x == '6' || x == '7' || x == '8' || x == '9') #define IS_HEX(x) (IS_DIGIT(x) || x == 'a' || x == 'b' || x == 'c' || x == 'd' || x == 'e' || x == 'f') +/** + * @brief Copy nbytes bytes from source to dest + * + * @param source + * @param dest + * @param nbytes + */ void memcpy(char *source, char *dest, int nbytes); + +/** + * @brief Set len bytes from dest to val + * + * @param dest + * @param val + * @param len + */ void memset(char *dest, char val, int len); #endif \ No newline at end of file diff --git a/include/shade/version.h b/include/shade/version.h index d1f2ec2..00c3dc9 100644 --- a/include/shade/version.h +++ b/include/shade/version.h @@ -1,9 +1,9 @@ -#ifndef VERSION_H -#define VERSION_H +#ifndef SHADE_VERSION_H +#define SHADE_VERSION_H // This file was autogenerated by the shadeOS build system. It should not be modified. #define SHADE_OS_KERNEL_VERSION "0.1.1-alpha" #define SHADE_OS_KERNEL "shade-development" -#define SHADE_OS_BUILD "20b96b2" -#define SHADE_OS_COMPILE_DATE "Sun May 15 07:01:51 PM EDT 2022" +#define SHADE_OS_BUILD "02abf37" +#define SHADE_OS_COMPILE_DATE "Tue May 17 08:32:53 AM EDT 2022" #define SHADE_OS_CODENAME "willow" #endif diff --git a/obj/kernel/kernel.o b/obj/kernel/kernel.o index 300f5fc..56ff092 100644 Binary files a/obj/kernel/kernel.o and b/obj/kernel/kernel.o differ diff --git a/src/kernel/platform/drivers/vga_text_mode.c b/src/kernel/platform/drivers/vga_text_mode.c index f8173b5..5f79c50 100644 --- a/src/kernel/platform/drivers/vga_text_mode.c +++ b/src/kernel/platform/drivers/vga_text_mode.c @@ -107,22 +107,24 @@ void set_cursor_pos(int col, int row) { outb(REG_SCREEN_DATA, (unsigned char)(offset & 0xff)); } -void kernel_msg_ok(char* msg) { - char ok_p1[] = "[ "; - char ok_p2[] = "OK "; - char ok_p3[] = "] "; - - print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); - print_str(ok_p1); - - print_set_color(PRINT_COLOR_GREEN, PRINT_COLOR_BLACK); - print_str(ok_p2); - - print_set_color(PRINT_COLOR_WHITE, PRINT_COLOR_BLACK); - print_str(ok_p3); - print_str(msg); -} - void init_state() { state = cansid_init(); +} + +void putchar(char c, int x, int y, char style) { + struct Char* buffer = (struct Char*) 0xb8000; + struct Char cr = (struct Char) { + character: c, + color: style, + }; + buffer[x + 25 * y] = cr; +} + +tty_driver_t vga_text_mode_get_driver() { + tty_driver_t ttyd; + ttyd.max_cols = 25; + ttyd.max_rows = 80; + ttyd.putchar = putchar; + ttyd.setcurxy = set_cursor_pos; + return ttyd; } \ No newline at end of file diff --git a/src/kernel/tty.c b/src/kernel/tty.c new file mode 100644 index 0000000..67fb223 --- /dev/null +++ b/src/kernel/tty.c @@ -0,0 +1,82 @@ +#include +#include + +// Initialize a new tty_t object with the specified driver +tty_t tty_new(tty_driver_t driver) { + tty_t tty; + tty.active = false; + tty.cansid = cansid_init(); + tty.cols = driver.max_cols; + tty.cursor_col = 0; + tty.cursor_row = 0; + tty.driver = driver; + tty.rows = driver.max_rows; + return tty; +} + +void tty_switch(int index); + +// private function: print the contents of a tty's output buffer to the screen +void _tty_flip(int tty, bool clear) { + // clear the screen if required (used in tty_switch) + if (clear) tty_clr(tty); + // iterate over every (known) character in the tty output buffer + for (int x = 0; x < ttys[tty].cols; x++) { + for (int y = 0; y < ttys[tty].rows; y++) { + // get the tty_ochar_t + tty_ochar_t cr = ttys[tty].output_buffer[x + ttys[tty].cols + y]; + // and print it with the driver + ttys[tty].driver.putchar(cr.character, x, y, cr.style); + } + } + // and update the real cursor position + ttys[tty].driver.setcurxy(ttys[tty].cursor_col, ttys[tty].cursor_row); +} + +// tty_pchar family +void tty_pchar(int tty, char c) { + if (c == 0) { + return; + } + + if (c == '\n') { + tty_pnl(tty); + return; + } + + if (ttys[tty].cursor_col > ttys[tty].cols) { + tty_pnl(tty); + } + + color_char ccr = cansid_process(&ttys[tty].cansid, c); + + tty_ochar_t cr; + cr.character = ccr.ascii; + cr.style = ccr.style; + ttys[tty].output_buffer[ttys[tty].cursor_col + ttys[tty].cols * ttys[tty].cursor_row] = cr; + + ttys[tty].cursor_col++; + tty_setcurxy(tty, ttys[tty].cursor_col, ttys[tty].cursor_row); + + // if tty is selected, flip + if (tty == active_tty) _tty_flip(tty, false); +} + +void tty_mvpchar(int tty, char c, int x, int y) { + tty_setcurxy(tty, x, y); + tty_pchar(tty, c); +} + +// tty_pnl family +void tty_pnl(int tty); +void tty_mvpnl(int tty, int x, int y); + +// tty_clr family +void tty_clr(int tty); // clear entire screen +void tty_clrl(int tty, int line); // clear a line + +void tty_setcurxy(int tty, int x, int y) { + ttys[tty].cursor_col = x; + ttys[tty].cursor_row = y; + ttys[tty].driver.setcurxy(x, y); +} \ No newline at end of file