From 58729b412a2c39cc60bd4b4987ee77b2a4efc4c2 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Wed, 4 Apr 2018 11:58:02 -0700 Subject: [PATCH] Add inital console font rendering --- Makefile | 2 +- assets/fonts/tamsyn8x16r.psf | Bin 0 -> 4677 bytes src/modules/main/font.c | 81 +++++++++++++++++++++++++++++++++++ src/modules/main/font.h | 44 ++++++++----------- src/modules/main/main.c | 33 ++++++++++++-- src/modules/main/screen.c | 42 ++++++++++++++++++ src/modules/main/screen.h | 30 +++++++++++++ 7 files changed, 201 insertions(+), 31 deletions(-) create mode 100644 assets/fonts/tamsyn8x16r.psf create mode 100644 src/modules/main/font.c create mode 100644 src/modules/main/screen.c create mode 100644 src/modules/main/screen.h diff --git a/Makefile b/Makefile index 13c723b..ef6deeb 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ VERSION ?= $(shell git describe --dirty --always) GITSHA ?= $(shell git rev-parse --short HEAD) KERNEL_FILENAME:= popcorn.bin -KERNEL_FONT := assets/fonts/tamsyn10x20r.psf +KERNEL_FONT := assets/fonts/tamsyn8x16r.psf MODULES := main diff --git a/assets/fonts/tamsyn8x16r.psf b/assets/fonts/tamsyn8x16r.psf new file mode 100644 index 0000000000000000000000000000000000000000..6fd82c17f4790afe97c764d6a70be95cd30b33a1 GIT binary patch literal 4677 zcmeHKYjaaY7!H{Xp3XRsVLDF6iS;x@0WVk(p=gZhF_xrKp%4T-YdG@`(`|h62ilaSiQ*0soIQ7CI z%ZKWL!fcI5w}wIf*uUTZ`P2(Soz-f!^MWKP6qt5;l>BKs??RgBuzgN+{1(H}-TZl; zI1fE0J9|#Qea8M-JX&Au&nP(;Pptm}Uh;)7JROEB){jj#s~amsl}IX8Wb*}!#Rlit z&2$j7g<(FOE(O-vj(X3m;EHMW@rK?}tJOMY)VsUqYOJ(-`Z7UaOa?(l5yEWNBq5s( zEn_j)$R(U0`E7PfbdOw)iX1pgE$4EEm`-Q3$uO)`^h_!0?pZVtMI|d71<>IhMSK0Gncm(tBp)Xdrz50r81nP=V@q|JIv{CSO=W5B}Gfn)q9yHNA`$z z-T6-o7Tb80ZvS)mztIk`M&>*7&Ff@ikiFkce`9jx%zP`T2y_N84&5}vcZ=H?4_nw~@lcfvQB)nWnDJMJ*_{UtR}%8wQB-j9N?0F3mR{D`4}!AA%%w_a zoWH1ATexgtt?K+!&Zy?>buI6&*SpxPd^E7AhxX!lRDM-+>!D*)3M_w2&!qK?rqi6W zS7z+FOgcSm`Bg3IX0g#eqF>`;F87>>`B?yi@%kHP zN{rZF$@H?t_Kg2-{j`7d*R6j_S2*LNW+M{&rxTh=P45U*i}jUt0l0j)_$I`3osL94 zh!g9dO6dZK*PqxFz-W1sAI`D@xWyZq&UCWq&fnQ1Q~fyC3K^ zqkRw4zK3bg!`UF^-4`hDVaj`$_2yyvR4TN$uWD~E=)w{Bvye}yG39RiW zu(p@PTp|Cy;A184(dlmzw~W7X+*Om~^-Zbxy!!(6(;qf_Uoif~*!mY^ogc;S_*H(A znEOSaPw{;)l`iQ&Af<{?N_vhlfY_&HaI?UOK?|29}!p%?Q7u z1E)4`glf&hYCN@R3;PE4_3WG2Pw3gzdfZC9i~R`uLH0FD1kIg5h;|e(8AV)!YcT~= zF%8$@dfb2;F&#Id12ZraH)9rV!EDSyC+6Z-+=dcvM;UjZf-Xe36II-WZp=dsb@bqF z%ttTo!2&Eq9~NOT?nOWD!~Ix-2k;;s!cshpNAM_?;V}$gIUdIocoI+HX*`2x@f@DV z3wRMPVGu841zy3ccnz;(C5EsHZ{SS~<1I9F6z3e8+tA#O<_;BWa~GPs(cHtp_oBIv zj|1$7R3dZ=m7?Y`H5}KkCn2jL??Bc--i5pec^|SC@&V*S$VZTMkdGnjA)i1#g?t9t z0QnrU5%L9O6XZ+CX2@5NEs(Dv-$1^FY=wLW`5y8EWE*5VWCvs?WEW&NWDn#=$X>`k y$bQHH$U(><$WM@;A%`KqKz@b%1~~#b3i%!K2jm#!Psm@8magic[i] != magic[i]) { + return 1; + } + } + + if (font == 0) + return 2; + + font->height = psf2->height; + font->width = psf2->width; + font->charsize = psf2->charsize; + font->count = psf2->length; + font->data = (uint8_t *)header + psf2->header_size; + return 0; +} + +int +font_draw( + struct font *f, + struct screen *s, + uint32_t glyph, + uint32_t color, + uint32_t x, + uint32_t y) +{ + const uint32_t height = f->height; + const uint32_t width = f->width; + const uint32_t bwidth = (width+7)/8; + uint8_t *data = f->data + (glyph * f->charsize); + + for (int dy = 0; dy < f->height; ++dy) { + for (int dx = 0; dx < bwidth; ++dx) { + uint8_t byte = data[dy * bwidth + dx]; + for (int i = 0; i < 8; ++i) { + if (dx*8 + i >= width) continue; + const uint8_t mask = 1 << (7-i); + uint32_t c = (byte & mask) ? color : 0; + screen_pixel(s, x + dx*8 + i, y + dy, c); + } + } + } + return 0; +} + diff --git a/src/modules/main/font.h b/src/modules/main/font.h index 788c81b..00fb8c8 100644 --- a/src/modules/main/font.h +++ b/src/modules/main/font.h @@ -1,32 +1,22 @@ #pragma once #include -/* PSF2 header format - * Taken from the Linux KBD documentation - * http://www.win.tue.nl/~aeb/linux/kbd/font-formats-1.html - */ +struct screen; -#define PSF2_MAGIC0 0x72 -#define PSF2_MAGIC1 0xb5 -#define PSF2_MAGIC2 0x4a -#define PSF2_MAGIC3 0x86 - -/* bits used in flags */ -#define PSF2_HAS_UNICODE_TABLE 0x01 - -/* max version recognized so far */ -#define PSF2_MAXVERSION 0 - -/* UTF8 separators */ -#define PSF2_SEPARATOR 0xFF -#define PSF2_STARTSEQ 0xFE - -struct psf2_header { - uint8_t magic[4]; - uint32_t version; - uint32_t headersize; // offset of bitmaps in file - uint32_t flags; - uint32_t length; // number of glyphs - uint32_t charsize; // number of bytes for each character - uint32_t height, width; // max dimensions of glyphs +struct font { + uint16_t height; + uint16_t width; + uint16_t charsize; + uint16_t count; + uint8_t *data; }; + +int font_init(void *header, struct font *font); + +int font_draw( + struct font *f, + struct screen *s, + uint32_t glyph, + uint32_t color, + uint32_t x, + uint32_t y); diff --git a/src/modules/main/main.c b/src/modules/main/main.c index cfdb333..874a329 100644 --- a/src/modules/main/main.c +++ b/src/modules/main/main.c @@ -1,6 +1,9 @@ #include #include +#include "font.h" +#include "screen.h" + void do_the_set_registers(); #pragma pack(push, 1) @@ -38,9 +41,33 @@ __attribute__((aligned(8))); void kernel_main(struct popcorn_data *header) { - uint32_t *p = header->frame_buffer; - uint32_t *end = p + (header->frame_buffer_size / sizeof(uint32_t)); - while (p < end) *p++ = header->rmask; + struct screen screen; + struct font font; + int status = 0; + + status = font_init(header->font, &font); + + status = screen_init( + header->frame_buffer, + header->hres, + header->vres, + header->rmask, + header->gmask, + header->bmask, + &screen); + + uint32_t color = header->gmask; + uint32_t perline = header->hres / font.width; + const char message[] = "Hello, I am text rendered by the kernel! :-D "; + for (int i=0; ihres * s->vres; + for (size_t i = 0; i < len; ++i) + s->data[i] = 0; + return 0; +} + +int +screen_init( + void *frame_buffer, + uint32_t hres, + uint32_t vres, + uint32_t rmask, + uint32_t gmask, + uint32_t bmask, + struct screen *s) +{ + s->data = frame_buffer; + s->hres = hres; + s->vres = vres; + s->rmask = rmask; + s->gmask = gmask; + s->bmask = bmask; + + return screen_fill(s, 0); +} + +int +screen_pixel( + struct screen *s, + uint32_t x, + uint32_t y, + uint32_t color) +{ + s->data[x + y*s->hres] = color; + return 0; +} diff --git a/src/modules/main/screen.h b/src/modules/main/screen.h new file mode 100644 index 0000000..e5708f1 --- /dev/null +++ b/src/modules/main/screen.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include + +struct screen { + uint32_t *data; + uint32_t hres; + uint32_t vres; + uint32_t rmask; + uint32_t gmask; + uint32_t bmask; +}; + +int screen_init( + void *frame_buffer, + uint32_t hres, + uint32_t vres, + uint32_t rmask, + uint32_t gmask, + uint32_t bmask, + struct screen *s); + +int screen_fill(struct screen *s, uint32_t color); + +int screen_pixel( + struct screen *s, + uint32_t x, + uint32_t y, + uint32_t color); +