Add inital console font rendering
This commit is contained in:
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ VERSION ?= $(shell git describe --dirty --always)
|
|||||||
GITSHA ?= $(shell git rev-parse --short HEAD)
|
GITSHA ?= $(shell git rev-parse --short HEAD)
|
||||||
|
|
||||||
KERNEL_FILENAME:= popcorn.bin
|
KERNEL_FILENAME:= popcorn.bin
|
||||||
KERNEL_FONT := assets/fonts/tamsyn10x20r.psf
|
KERNEL_FONT := assets/fonts/tamsyn8x16r.psf
|
||||||
|
|
||||||
MODULES := main
|
MODULES := main
|
||||||
|
|
||||||
|
|||||||
BIN
assets/fonts/tamsyn8x16r.psf
Normal file
BIN
assets/fonts/tamsyn8x16r.psf
Normal file
Binary file not shown.
81
src/modules/main/font.c
Normal file
81
src/modules/main/font.c
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
#include "font.h"
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
/* PSF2 header format
|
||||||
|
* Taken from the Linux KBD documentation
|
||||||
|
* http://www.win.tue.nl/~aeb/linux/kbd/font-formats-1.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
const static uint8_t magic[] = {0x72, 0xb5, 0x4a, 0x86};
|
||||||
|
|
||||||
|
/* bits used in flags */
|
||||||
|
enum psf2_flags {
|
||||||
|
psf2_has_unicode = 0x00000001
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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 header_size; // 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
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
font_init(void *header, struct font *font)
|
||||||
|
{
|
||||||
|
struct psf2_header *psf2 = (struct psf2_header *)header;
|
||||||
|
for (int i = 0; i < sizeof(magic); ++i) {
|
||||||
|
if (psf2->magic[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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,32 +1,22 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* PSF2 header format
|
struct screen;
|
||||||
* Taken from the Linux KBD documentation
|
|
||||||
* http://www.win.tue.nl/~aeb/linux/kbd/font-formats-1.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PSF2_MAGIC0 0x72
|
struct font {
|
||||||
#define PSF2_MAGIC1 0xb5
|
uint16_t height;
|
||||||
#define PSF2_MAGIC2 0x4a
|
uint16_t width;
|
||||||
#define PSF2_MAGIC3 0x86
|
uint16_t charsize;
|
||||||
|
uint16_t count;
|
||||||
/* bits used in flags */
|
uint8_t *data;
|
||||||
#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
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "font.h"
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
void do_the_set_registers();
|
void do_the_set_registers();
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
@@ -38,9 +41,33 @@ __attribute__((aligned(8)));
|
|||||||
void
|
void
|
||||||
kernel_main(struct popcorn_data *header)
|
kernel_main(struct popcorn_data *header)
|
||||||
{
|
{
|
||||||
uint32_t *p = header->frame_buffer;
|
struct screen screen;
|
||||||
uint32_t *end = p + (header->frame_buffer_size / sizeof(uint32_t));
|
struct font font;
|
||||||
while (p < end) *p++ = header->rmask;
|
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; i<sizeof(message); ++i) {
|
||||||
|
font_draw(
|
||||||
|
&font,
|
||||||
|
&screen,
|
||||||
|
message[i],
|
||||||
|
color,
|
||||||
|
(i % perline) * font.width + 10,
|
||||||
|
(i / perline) * font.height + 10);
|
||||||
|
}
|
||||||
|
|
||||||
do_the_set_registers(header);
|
do_the_set_registers(header);
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/modules/main/screen.c
Normal file
42
src/modules/main/screen.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#include "font.h"
|
||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
screen_fill(struct screen *s, uint32_t color)
|
||||||
|
{
|
||||||
|
const size_t len = s->hres * 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;
|
||||||
|
}
|
||||||
30
src/modules/main/screen.h
Normal file
30
src/modules/main/screen.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
Reference in New Issue
Block a user