started work on tty

This commit is contained in:
justuswolff
2026-03-19 15:41:08 +01:00
parent 233f956119
commit fa6c48ae7e
8 changed files with 163 additions and 81 deletions

View File

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

View File

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

View File

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

22
src/headers/tty.h Normal file
View File

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

View File

@@ -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<consolesAmount;i++) {
con_init(&consoles[i]);
}
kputstr("Hello JPOS, World!\n");
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
@@ -57,17 +41,16 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
VGA_switch(VGA_values);
kputstr("OK\n");
enum VGA_colors colors[] = {white,black,red,green,blue};
for (uint8_t y=0;y<5;y++) {
for (uint8_t y2=0;y2<40;y2++) {
for (uint16_t x=0;x<320;x++) {
VGA_fbuf[VGA_offset(x,y2+(y*40))] = colors[y];
}
for (uint16_t y=0;y<200;y++) {
VGA_setpix(x,y,(VGA_pixel){0xFF,0xFF,0xFF});
}
}
kputstr("Setting up stdout rendering: ");
FU_kupdbuf = &VGA_kstrrend;
for (uint8_t i=0;i<consolesAmount;i++) {
consoles[i].FU_kupdbuf = &VGA_kstrrend;
}
kputstr("OK\n");
}

View File

@@ -1,16 +1,21 @@
#include "../headers/graphics.h"
#include "../headers/tty.h"
void inline _VGA_renchar(uint8_t x, uint8_t y, char val) {
inline uint8_t _VGA_nearestmul(uint8_t val, uint8_t multiple) {
if (val%multiple == 0) {return val;}
return val + multiple - (val%multiple);
}
void inline _VGA_renchar(uint8_t x, uint8_t y, char val, uint8_t fcolor[3], uint8_t bcolor[3]) {
for (uint8_t px=0;px<8;px++) {
for (uint8_t py=0;py<8;py++) {
VGA_setpix(x*8+px,y*8+py,(VGA_basic8x8font[val][py] >> 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;
}

View File

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

39
src/kernel/tty.c Normal file
View File

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