From fa6c48ae7eb4230fb0b877b35210d1be57ae7a88 Mon Sep 17 00:00:00 2001 From: justuswolff Date: Thu, 19 Mar 2026 15:41:08 +0100 Subject: [PATCH] started work on tty --- makefile | 4 +- src/headers/graphics.h | 41 ++++++++++++--------- src/headers/registrar.h | 6 --- src/headers/tty.h | 22 +++++++++++ src/kernel/entry.c | 43 +++++++-------------- src/kernel/graphics.c | 82 +++++++++++++++++++++++++++++++---------- src/kernel/registrar.c | 7 ---- src/kernel/tty.c | 39 ++++++++++++++++++++ 8 files changed, 163 insertions(+), 81 deletions(-) delete mode 100644 src/headers/registrar.h create mode 100644 src/headers/tty.h delete mode 100644 src/kernel/registrar.c create mode 100644 src/kernel/tty.c diff --git a/makefile b/makefile index 984cd0e..431f544 100644 --- a/makefile +++ b/makefile @@ -3,14 +3,14 @@ build: prepare copygrub #nasm -felf32 src/kernel/driverdriver.asm -o build/drivdriv.o # driver code for drivers gcc -c src/kernel/entry.c -o build/kernel.o -ffreestanding -O2 -Wall -Wextra -m32 # kernel - gcc -c src/kernel/registrar.c -o build/registrar.o -ffreestanding -O2 -Wall -Wextra -m32 # registrar gcc -c src/kernel/stdlib.c -o build/stdlib.o -ffreestanding -O2 -Wall -Wextra -m32 # stdlib gcc -c src/kernel/graphics.c -o build/graphics.o -ffreestanding -O2 -Wall -Wextra -m32 # VGA graphics + gcc -c src/kernel/tty.c -o build/tty.o -ffreestanding -O2 -Wall -Wextra -m32 # tty gcc -c initrd/vga/main.c -o build/initrddir/vga_graph -ffreestanding -O2 -Wall -Wextra -m32 # initrd/vga driver tar -czf build/initrd build/initrddir/* # build initrd - gcc -z noexecstack -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/graphics.o build/boot.o build/kernel.o build/registrar.o build/stdlib.o -fno-pie -fno-pic -no-pie # link + gcc -z noexecstack -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/tty.o build/graphics.o build/boot.o build/kernel.o build/stdlib.o -fno-pie -fno-pic -no-pie # link cp build/linked build/grub/boot/kernel # copy kernel over to grub template cp build/initrd build/grub/boot/JPOS.initrd # copy initrd to grub template diff --git a/src/headers/graphics.h b/src/headers/graphics.h index f21234f..69e8a57 100644 --- a/src/headers/graphics.h +++ b/src/headers/graphics.h @@ -1,14 +1,25 @@ #pragma once #include "stddef.h" #include "stdlib.h" +#include "tty.h" + // these values are for 320*200*256 -enum VGA_colors { - black=0x00, - white=0x0F, - red=0x1F, - green=0x2F, - blue=0x3F, +typedef struct { + uint8_t r; + uint8_t g; + uint8_t b; +} VGA_pixel; +static const VGA_pixel VGA_colors_black = { + 0x00, + 0x00, + 0x00 }; +static const VGA_pixel VGA_colors_white = { + 0xFF, + 0xFF, + 0xFF +}; + static uint8_t VGA_basic8x8font[128][8] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 @@ -139,11 +150,9 @@ static uint8_t VGA_basic8x8font[128][8] = { { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F }; -static char VGA_charbuf[40][25]; -void inline VGA_setchar(uint8_t x, uint8_t y, char val) { - VGA_charbuf[x][y] = val; -} -void VGA_renderchar(); +static uint8_t VGA_palette[256][3]; +void VGA_setchar(virtualConsole* con, uint8_t x, uint8_t y, char val); +void VGA_renderchar(virtualConsole* con); static uint8_t* VGA_fbuf = (unsigned char*)0xA0000; static uint8_t VGA_values[] = { // THIS. THIS IS CANCER. // MISC @@ -167,12 +176,10 @@ static uint8_t VGA_values[] = { // THIS. THIS IS CANCER. 0x41,0x00,0x0F,0x00,0x00 }; void VGA_switch(uint8_t *regs); -size_t inline VGA_offset(uint16_t x, uint16_t y) { +inline size_t VGA_offset(uint16_t x, uint16_t y) { return x+(y*320); } void VGA_setcol(uint8_t index, uint8_t r, uint8_t g, uint8_t b); -void VGA_setpal(uint8_t* palette); -void inline VGA_setpix(uint16_t x, uint16_t y, enum VGA_colors color) { - VGA_fbuf[VGA_offset(x,y)] = color; -} -void VGA_kstrrend(char* buf, uint16_t count); \ No newline at end of file +void VGA_setpal(uint8_t palette[256][3]); +void VGA_setpix(uint16_t x, uint16_t y, VGA_pixel pix); +void VGA_kstrrend(virtualConsole* con); \ No newline at end of file diff --git a/src/headers/registrar.h b/src/headers/registrar.h deleted file mode 100644 index bdd4f5a..0000000 --- a/src/headers/registrar.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "stddef.h" - -typedef void (*FU_kupdbuf_t)(char*, uint16_t); -extern void* FU_kupdbuf; -void FUINV_kupdbuf(char* buf, uint16_t count); diff --git a/src/headers/tty.h b/src/headers/tty.h new file mode 100644 index 0000000..b81eaf4 --- /dev/null +++ b/src/headers/tty.h @@ -0,0 +1,22 @@ +#pragma once +#include "stddef.h" + +typedef struct { + void* FU_kupdbuf; + char kstdout[8192]; + uint16_t kstdout_count; + uint8_t FU_forecolor[3]; + uint8_t FU_backcolor[3]; + char charbuf[40][25]; +} virtualConsole; +typedef void (*FU_kupdbuf_t)(virtualConsole*); + +#define consolesAmount 12 +static virtualConsole consoles[consolesAmount]; +static uint8_t currentConsole = 0; + +void con_kputchar(virtualConsole* con, char x); +void con_kputstr(virtualConsole* con, char* x); +void con_init(virtualConsole* con); +void kputchar(char x); +void kputstr(char* x); \ No newline at end of file diff --git a/src/kernel/entry.c b/src/kernel/entry.c index 0e65dd0..1f124d7 100644 --- a/src/kernel/entry.c +++ b/src/kernel/entry.c @@ -1,8 +1,8 @@ #include "../headers/stddef.h" #include "../headers/multiboot2.h" -#include "../headers/registrar.h" #include "../headers/stdlib.h" #include "../headers/graphics.h" +#include "../headers/tty.h" struct multiboot_info { uint32_t total_size; @@ -22,28 +22,12 @@ uint32_t findtag(uint32_t type, struct multiboot_info* info) { return 0; // failsafe } -// kernel stdout -void* FU_kupdbuf = 0x00; -char kstdout[8192] = {}; -uint16_t kstdout_count = 0; -void kputchar(char x) { - if (kstdout_count == 8192) { - for (uint32_t i=0;i<8191;i++) { - kstdout[i] = kstdout[i+1]; - } - kstdout_count --; - } - kstdout[kstdout_count++] = x; - FUINV_kupdbuf(kstdout, kstdout_count); -} -void kputstr(char* x) { - while (*x != 0) { - kputchar(*x++); - } - //kputchar('\n'); -} - void kernel_main(struct multiboot_info* header, uint32_t magic) { + // init all consoles + for (uint8_t i=0;i> px) & 1 ? white : black); + VGA_setpix(x*8+px,y*8+py,(VGA_basic8x8font[val][py] >> px) & 1 ? *(VGA_pixel*)fcolor : *(VGA_pixel*)bcolor); } } } -void VGA_renderchar() { +void VGA_renderchar(virtualConsole* con) { for (uint8_t x=0;x<40;x++) { for (uint8_t y=0;y<25;y++) { - _VGA_renchar(x, y, VGA_charbuf[x][y]); + _VGA_renchar(x, y, con->charbuf[x][y], con->FU_forecolor, con->FU_backcolor); } } } @@ -60,16 +65,32 @@ void VGA_switch(uint8_t *regs) { regs++; } - // set palette - VGA_setcol(0x00, 0x00, 0x00, 0x00); // black - VGA_setcol(0x0F, 0xFF, 0xFF, 0xFF); // white - VGA_setcol(0x1F, 0xFF, 0x00, 0x00); // red - VGA_setcol(0x2F, 0x00, 0xFF, 0x00); // green - VGA_setcol(0x3F, 0x00, 0x00, 0xFF); // blue - // unblank display inb(0x3DA); outb(0x3C0, 0x20); + + // generate palette + uint8_t r,g,b; + r=0;g=0;b=0; + + for (uint8_t i=0;i<216;i++) { + VGA_palette[i][0] = r; + VGA_palette[i][1] = g; + VGA_palette[i][2] = b; + + if (r == 0xFF) { + r = 0x00; + if (g == 0xFF) { + g = 0; + b += 0x33; + } else { + g += 0x33; + } + } else { + r += 0x33; + } + } + VGA_setpal(VGA_palette); } void VGA_setcol(uint8_t index, uint8_t r, uint8_t g, uint8_t b) { outb(0x3C8, index); @@ -77,14 +98,19 @@ void VGA_setcol(uint8_t index, uint8_t r, uint8_t g, uint8_t b) { outb(0x3C9, g); outb(0x3C9, b); } -void VGA_setpal(uint8_t* palette) { - outb(0x3C8, 0); - - for(int i = 0; i < 256 * 3; i++) { - outb(0x3C9, palette[i]); +void VGA_setpal(uint8_t palette[256][3]) { + for (uint8_t i=0;i<255;i++) { + VGA_setcol(i,palette[i][0],palette[i][1],palette[i][2]); + VGA_setpix(i,0,(VGA_pixel){0x00,0xFF,0x00}); } } -void VGA_kstrrend(char* buf, uint16_t count) { +void VGA_setchar(virtualConsole* con, uint8_t x, uint8_t y, char val) { + con->charbuf[x][y] = val; +} +void VGA_kstrrend(virtualConsole* con) { + size_t count = con->kstdout_count; + char* buf = con->kstdout; + while (count > (40*25)) { count -= (40*25); buf += (40*25); @@ -105,10 +131,28 @@ void VGA_kstrrend(char* buf, uint16_t count) { continue; } - VGA_setchar(x,y,val); + VGA_setchar(con,x,y,val); x++; } - VGA_renderchar(); + VGA_renderchar(con); +} +void VGA_setpix(uint16_t x, uint16_t y, VGA_pixel pix) { + uint16_t i; + // first we round each r, g and b value to the nearest multiple of 0x33 + uint8_t color[3] = {pix.r, pix.g, pix.b}; + color[0] = _VGA_nearestmul(color[0], 0x33); + color[1] = _VGA_nearestmul(color[1], 0x33); + color[2] = _VGA_nearestmul(color[2], 0x33); + // then find the matching index in palette + for (i=0;i<256;i++) { + if (VGA_palette[i][0] == color[0] && + VGA_palette[i][1] == color[1] && + VGA_palette[i][2] == color[2] + ) { + break; + } + } + VGA_fbuf[VGA_offset(x,y)] = i; } \ No newline at end of file diff --git a/src/kernel/registrar.c b/src/kernel/registrar.c deleted file mode 100644 index 862da87..0000000 --- a/src/kernel/registrar.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "../headers/registrar.h" - -void FUINV_kupdbuf(char* buf, uint16_t count) { - if (FU_kupdbuf != 0x00) { - ((FU_kupdbuf_t)FU_kupdbuf)(buf, count); - } -} \ No newline at end of file diff --git a/src/kernel/tty.c b/src/kernel/tty.c new file mode 100644 index 0000000..c7202b0 --- /dev/null +++ b/src/kernel/tty.c @@ -0,0 +1,39 @@ +#include "../headers/tty.h" +#include "../headers/graphics.h" + +void con_dummyrend(virtualConsole* con) {} +void con_kputchar(virtualConsole* con, char x) { + if (con->kstdout_count == 8192) { + for (uint32_t i=0;i<8191;i++) { + con->kstdout[i] = con->kstdout[i+1]; + } + con->kstdout_count --; + } + con->kstdout[con->kstdout_count++] = x; + if (&consoles[currentConsole] == con) { // current console + if (con->FU_kupdbuf != 0x00) { + ((FU_kupdbuf_t)con->FU_kupdbuf)(con); + } + } +} +void con_kputstr(virtualConsole* con, char* x) { + while (*x != 0) { + con_kputchar(con, *x++); + } +} +void con_init(virtualConsole* con) { + con->kstdout_count = 0; + con->FU_kupdbuf = 0x00; + con->FU_forecolor[0] = 0xFF; + con->FU_forecolor[1] = 0xFF; + con->FU_forecolor[2] = 0xFF; + con->FU_backcolor[0] = 0x00; + con->FU_backcolor[1] = 0x00; + con->FU_backcolor[2] = 0x00; +} +void kputchar(char x) { + con_kputchar(&consoles[currentConsole], x); +} +void kputstr(char* x) { + con_kputstr(&consoles[currentConsole], x); +} \ No newline at end of file