started work on tty
This commit is contained in:
4
makefile
4
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
|
||||
|
||||
@@ -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);
|
||||
@@ -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
22
src/headers/tty.h
Normal 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);
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
void kernel_main(struct multiboot_info* header, uint32_t magic) {
|
||||
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");
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
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_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;
|
||||
|
||||
for(int i = 0; i < 256 * 3; i++) {
|
||||
outb(0x3C9, palette[i]);
|
||||
}
|
||||
}
|
||||
void VGA_kstrrend(char* buf, uint16_t count) {
|
||||
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;
|
||||
}
|
||||
@@ -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
39
src/kernel/tty.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user