added proper VGA graphics

This commit is contained in:
justuswolff
2026-03-14 23:17:48 +01:00
parent 8d19f45da2
commit 233f956119
8 changed files with 337 additions and 126 deletions

View File

@@ -1,16 +1,16 @@
build: prepare copygrub
nasm -felf32 src/bootload/boot.asm -o build/boot.o # entrypoint for grub
nasm -felf32 src/kernel/driverdriver.asm -o build/drivdriv.o # driver code for drivers
#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 # 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 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 -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/boot.o build/kernel.o build/registrar.o build/drivdriv.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/graphics.o build/boot.o build/kernel.o build/registrar.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

178
src/headers/graphics.h Normal file
View File

@@ -0,0 +1,178 @@
#pragma once
#include "stddef.h"
#include "stdlib.h"
// these values are for 320*200*256
enum VGA_colors {
black=0x00,
white=0x0F,
red=0x1F,
green=0x2F,
blue=0x3F,
};
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
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space)
{ 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!)
{ 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (")
{ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#)
{ 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($)
{ 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%)
{ 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&)
{ 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (')
{ 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (()
{ 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ())
{ 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*)
{ 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,)
{ 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.)
{ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/)
{ 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0)
{ 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1)
{ 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2)
{ 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3)
{ 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4)
{ 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5)
{ 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6)
{ 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7)
{ 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8)
{ 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9)
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:)
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (;)
{ 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<)
{ 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=)
{ 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>)
{ 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?)
{ 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@)
{ 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A)
{ 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B)
{ 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C)
{ 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D)
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E)
{ 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F)
{ 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G)
{ 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H)
{ 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I)
{ 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J)
{ 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K)
{ 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L)
{ 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M)
{ 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N)
{ 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O)
{ 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P)
{ 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q)
{ 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R)
{ 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S)
{ 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T)
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U)
{ 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V)
{ 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W)
{ 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X)
{ 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y)
{ 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z)
{ 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([)
{ 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\)
{ 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (])
{ 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_)
{ 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`)
{ 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a)
{ 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b)
{ 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c)
{ 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d)
{ 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e)
{ 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f)
{ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g)
{ 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h)
{ 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i)
{ 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j)
{ 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k)
{ 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l)
{ 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m)
{ 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n)
{ 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o)
{ 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p)
{ 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q)
{ 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r)
{ 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s)
{ 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v)
{ 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w)
{ 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x)
{ 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y)
{ 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z)
{ 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({)
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|)
{ 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (})
{ 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_fbuf = (unsigned char*)0xA0000;
static uint8_t VGA_values[] = { // THIS. THIS IS CANCER.
// MISC
0x63,
// SEQ
0x03, 0x01, 0x0F, 0x00, 0x0E,
// CRTC
0x5F,0x4F,0x50,0x82,0x54,0x80,0xBF,0x1F,
0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
0x9C,0x0E,0x8F,0x28,0x40,0x96,0xB9,0xA3,
0xFF,
// GC
0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0F,0xFF,
// AC
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x41,0x00,0x0F,0x00,0x00
};
void VGA_switch(uint8_t *regs);
size_t inline 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);

View File

@@ -1,11 +1,11 @@
#define uint8_t unsigned char
#define uint16_t unsigned short
#define uint32_t unsigned int
#define uint64_t unsigned long
//#define uint64_t unsigned long
#define int8_t signed char
#define int16_t signed short
#define int32_t signed int
#define int64_t signed long
#//define int64_t signed long
#define size_t uint64_t
#define size_t uint32_t

View File

@@ -4,3 +4,15 @@
uint32_t strlen32(char* str);
void strrev32(char* str);
uint8_t uitoa32(uint32_t x, char* str);
void memcopy(void* dest, void* src, size_t size);
static inline void outb(uint16_t port, uint8_t val) {
__asm__ volatile ( "outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
}
static inline uint8_t inb(uint16_t port) {
uint8_t ret;
__asm__ volatile ( "inb %w1, %b0"
: "=a"(ret)
: "Nd"(port)
: "memory");
return ret;
}

View File

@@ -1,5 +1,6 @@
section .text:
[BITS 32]
global DRIV_storage
DRIV_storage:
resb 16384 ; 16 KiB for driver code/functions
DRIV_storage_end:

View File

@@ -2,40 +2,8 @@
#include "../headers/multiboot2.h"
#include "../headers/registrar.h"
#include "../headers/stdlib.h"
#include "../headers/graphics.h"
uint32_t basevga_postooffset(uint16_t x, uint16_t y) {
volatile uint8_t VGA_MAX_COLS = 80*2;
return (y*VGA_MAX_COLS)+(x*2);
}
void basevga_writestdout(char* buf, uint16_t count) {
volatile char *video = (volatile char*)0xB8000;
volatile uint8_t VGA_MAX_ROWS = 25;
volatile uint8_t VGA_MAX_COLS = 80;
uint8_t x = 0;
uint8_t y = 0;
for (uint32_t i=0;i<count;i++) {
if (buf[i] == '\n') {
y ++;
x = 0;
}
uint32_t offset = basevga_postooffset(x,y);
if (buf[i] != '\n') {
x ++;
}
if (x > VGA_MAX_ROWS) {
x = 0;
y ++;
}
if (y > VGA_MAX_COLS) {
y = 0;
}
video[offset] = buf[i];
video[offset+1] = 15;
}
}
struct multiboot_info {
uint32_t total_size;
uint32_t reserved;
@@ -55,7 +23,7 @@ uint32_t findtag(uint32_t type, struct multiboot_info* info) {
}
// kernel stdout
void* FU_kupdbuf = basevga_writestdout; // register basevga_writestdout as kupdbuf function
void* FU_kupdbuf = 0x00;
char kstdout[8192] = {};
uint16_t kstdout_count = 0;
void kputchar(char x) {
@@ -75,63 +43,8 @@ void kputstr(char* x) {
//kputchar('\n');
}
// basic tar parsing code for the initrd
struct tar_header {
char filename[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char chksum[8];
char typeflag[1];
};
uint32_t tar_getsize(const char *in) {
uint32_t size = 0;
uint32_t j;
uint32_t count = 1;
for (j = 11; j > 0; j--, count *= 8)
size += ((in[j - 1] - '0') * count);
return size;
}
uint32_t tar_parse(uint64_t address, struct tar_header* headers[]) {
uint32_t i;
for (i = 0;;i++) {
struct tar_header* header = (struct tar_header*)address;
if (header->filename[i] == '\0') { // end of archive
break;
}
uint32_t size = tar_getsize(header->size);
headers[i] = header;
address += ((size / 512) + 1) * 512;
if (size % 512) {
address += 512;
}
}
return i;
}
// stuff for drivers
struct driver_state_info {
void* addr;
uint32_t size;
uint8_t inuse;
};
struct driver_state_info driversinfo[32];
void loaddriv(void* addr) {
}
void kernel_main(struct multiboot_info* header, uint32_t magic) {
kputstr("Hello JPOS, World!\n");
while (1) {}
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) {
kputstr("Invalid magic from bootloader.\n");
@@ -140,33 +53,21 @@ void kernel_main(struct multiboot_info* header, uint32_t magic) {
kputstr("Got past magic check.\n");
// load drivers
kputstr("Entering Graphics mode: ");
VGA_switch(VGA_values);
kputstr("OK\n");
// find boot modules tag
struct multiboot_tag_module* bootmodules = (struct multiboot_tag_module*)&header->tags[findtag(3, header)];
if (bootmodules->type != 3) {kputstr("Boot module failure.\n");return;}
kputstr("Reading ramdisk...\n");
char temp[10];
uitoa32(bootmodules->mod_end-bootmodules->mod_start, temp);
kputstr("Ramdisk size: ");
kputstr(temp);
kputchar('\n');
struct tar_header* rd_headers[32];
uint8_t rd_header_count = tar_parse(bootmodules->mod_start, rd_headers);
uitoa32(rd_header_count, temp);
kputstr("Ramdisk modules: ");
kputstr(temp);
kputchar('\n');
kputstr((char*)&rd_headers[0]);
for (uint8_t i=0;i<rd_header_count;i++) {
kputstr(" ");
kputstr(rd_headers[i]->filename);
kputchar('\n');
// TODO: actually load ramdisk stuff, first I'd like to enter 64 bit mode.
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];
}
}
}
kputstr("End of Ramdisk\n");
kputstr("Setting up stdout rendering: ");
FU_kupdbuf = &VGA_kstrrend;
kputstr("OK\n");
}

114
src/kernel/graphics.c Normal file
View File

@@ -0,0 +1,114 @@
#include "../headers/graphics.h"
void inline _VGA_renchar(uint8_t x, uint8_t y, char val) {
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);
}
}
}
void VGA_renderchar() {
for (uint8_t x=0;x<40;x++) {
for (uint8_t y=0;y<25;y++) {
_VGA_renchar(x, y, VGA_charbuf[x][y]);
}
}
}
void VGA_switch(uint8_t *regs) {
uint8_t i;
// MISC
outb(0x3C2, *regs);
regs++;
// SEQUENCER
for (i = 0; i < 5; i++) {
outb(0x3C4, i);
outb(0x3C5, *regs);
regs++;
}
// Unlock CRTC registers
outb(0x3D4, 0x03);
outb(0x3D5, inb(0x3D5) | 0x80);
outb(0x3D4, 0x11);
outb(0x3D5, inb(0x3D5) & ~0x80);
regs[0x03] |= 0x80;
regs[0x11] &= ~0x80;
// CRTC
for (i = 0; i < 25; i++) {
outb(0x3D4, i);
outb(0x3D5, *regs);
regs++;
}
// GRAPHICS CONTROLLER
for (i = 0; i < 9; i++) {
outb(0x3CE, i);
outb(0x3CF, *regs);
regs++;
}
// ATTRIBUTE CONTROLLER
for (i = 0; i < 21; i++) {
inb(0x3DA);
outb(0x3C0, i);
outb(0x3C0, *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);
}
void VGA_setcol(uint8_t index, uint8_t r, uint8_t g, uint8_t b) {
outb(0x3C8, index);
outb(0x3C9, r);
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_kstrrend(char* buf, uint16_t count) {
while (count > (40*25)) {
count -= (40*25);
buf += (40*25);
}
uint16_t x = 0;
uint16_t y = 0;
for (uint16_t i=0;i<count;i++) {
if (x >= 40) {
x = 0;
y ++;
}
char val = buf[i];
if (val == '\n') {
x = 0;
y ++;
continue;
}
VGA_setchar(x,y,val);
x++;
}
VGA_renderchar();
}

View File

@@ -23,3 +23,8 @@ uint8_t uitoa32(uint32_t x, char* str) {
strrev32(str);
return i;
}
void memcopy(void* dest, void* src, size_t size) {
for (size_t i=0;i<size;i++) {
((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
}
}