Adds simple video driver.

This commit is contained in:
Felix Queißner 2016-06-26 15:21:36 +02:00
parent b873c662c8
commit f147ee1901
9 changed files with 153 additions and 62 deletions

Binary file not shown.

View file

@ -0,0 +1,56 @@
#pragma once
#include <stdint.h>
#include <vbe.hpp>
#include "picture.hpp"
class VideoScreen :
public Picture
{
private:
static Pixel outOfScreen;
private:
Pixel *mFramebuffer;
uint32_t mPitch;
public:
const uint32_t mWidth, mHeight;
public:
VideoScreen(vbe::ModeInfo const & modeInfo);
uint32_t width() const override {
return this->mWidth;
}
uint32_t height() const override {
return this->mHeight;
}
Pixel & operator() (uint32_t x, uint32_t y) override {
if(x >= this->mWidth || y >= this->mHeight) {
return VideoScreen::outOfScreen;
} else {
return this->scanline(y)[x];
}
}
Pixel const & operator() (uint32_t x, uint32_t y) const override {
if(x >= this->mWidth || y >= this->mHeight) {
return VideoScreen::outOfScreen;
} else {
return this->scanline(y)[x];
}
}
private:
Pixel * scanline(uint32_t y) {
return reinterpret_cast<Pixel*>(
reinterpret_cast<uint32_t>(this->mFramebuffer) + y * this->mPitch
);
}
Pixel const * scanline(uint32_t y) const {
return reinterpret_cast<Pixel*>(
reinterpret_cast<uint32_t>(this->mFramebuffer) + y * this->mPitch
);
}
};

View file

@ -19,6 +19,8 @@
#define MB_ASSERT_SIZE(type, len) static_assert(sizeof(type) == len, "multiboot::" #type " must be " #len " bytes large.") #define MB_ASSERT_SIZE(type, len) static_assert(sizeof(type) == len, "multiboot::" #type " must be " #len " bytes large.")
#include "vbe.hpp"
namespace multiboot namespace multiboot
{ {
template<typename T> template<typename T>
@ -156,7 +158,7 @@ namespace multiboot
const APMTable * apmTable; const APMTable * apmTable;
struct { struct {
uint32_t controlInfo; uint32_t controlInfo;
uint32_t modeInfo; vbe::ModeInfo const * modeInfo;
uint16_t mode; uint16_t mode;
uint16_t interfaceSegment; uint16_t interfaceSegment;
uint16_t interfaceOffset; uint16_t interfaceOffset;

View file

@ -0,0 +1,25 @@
#pragma once
#include <stdint.h>
struct Pixel
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} __attribute__((packed));
static inline Pixel COLOR(uint8_t r, uint8_t g, uint8_t b)
{
return Pixel { b, g, r, 0xFF };
}
class Picture
{
public:
virtual uint32_t width() const = 0;
virtual uint32_t height() const = 0;
virtual Pixel & operator() (uint32_t x, uint32_t y) = 0;
virtual Pixel const & operator() (uint32_t x, uint32_t y) const = 0;
};

View file

@ -0,0 +1,39 @@
#pragma once
#include <stddef.h>
#define VBE_FAR(name) uint32_t name;
namespace vbe
{
struct ModeInfo
{
uint16_t attributes;
uint8_t winA,winB;
uint16_t granularity;
uint16_t winsize;
uint16_t segmentA, segmentB;
VBE_FAR(realFctPtr);
uint16_t pitch; // bytes per scanline
struct {
uint16_t x;
uint16_t y;
} __attribute__ ((packed)) res;
uint8_t Wchar, Ychar;
uint8_t planes, bpp, banks;
uint8_t memoryModel, bankSize, imagePages;
uint8_t reserved0;
uint8_t redMask, redPosition;
uint8_t greenMask, greenPosition;
uint8_t blueMask, bluePosition;
uint8_t rsvMask, rsvPosition;
uint8_t directcolor_attributes;
uint32_t framebuffer;
uint32_t reserved1;
uint16_t reserved2;
} __attribute__((packed));
}

View file

@ -0,0 +1,12 @@
##
# Build video library.
##
include ../config.mk
LIBRARY = libvideo.a
all: builddir $(LIBRARY)
include ../common.mk
include ../library.mk

View file

@ -0,0 +1,12 @@
#include <driver/video.hpp>
Pixel VideoScreen::outOfScreen;
VideoScreen::VideoScreen(vbe::ModeInfo const & modeInfo) :
mFramebuffer((Pixel*)modeInfo.framebuffer),
mPitch(modeInfo.pitch),
mWidth(modeInfo.res.x),
mHeight(modeInfo.res.y)
{
}

View file

@ -5,7 +5,7 @@
include ../config.mk include ../config.mk
KERNEL = video.ker KERNEL = video.ker
LIBS = -lboot LIBS = -lboot -lvideo
all: builddir $(KERNEL) all: builddir $(KERNEL)

View file

@ -3,13 +3,7 @@
#include <multiboot.hpp> #include <multiboot.hpp>
#include <io.hpp> #include <io.hpp>
struct dummy; #include <driver/video.hpp>
// Symbols generated by linker, no useful content in there...
extern dummy kernelStartMarker;
extern dummy kernelEndMarker;
uint16_t * video = (uint16_t*)0xB8000;
// Prüft, ob man bereits schreiben kann // Prüft, ob man bereits schreiben kann
static uint8_t is_transmit_empty(uint16_t base) { static uint8_t is_transmit_empty(uint16_t base) {
@ -22,67 +16,18 @@ static void write_com(uint16_t base, uint8_t chr) {
outb(base,chr); outb(base,chr);
} }
#define VBE_FAR(name) uint32_t name;
struct ModeInfoBlock {
uint16_t attributes;
uint8_t winA,winB;
uint16_t granularity;
uint16_t winsize;
uint16_t segmentA, segmentB;
VBE_FAR(realFctPtr);
uint16_t pitch; // bytes per scanline
uint16_t Xres, Yres;
uint8_t Wchar, Ychar, planes, bpp, banks;
uint8_t memory_model, bank_size, image_pages;
uint8_t reserved0;
uint8_t red_mask, red_position;
uint8_t green_mask, green_position;
uint8_t blue_mask, blue_position;
uint8_t rsv_mask, rsv_position;
uint8_t directcolor_attributes;
uint32_t physbase; // your LFB (Linear Framebuffer) address ;)
uint32_t reserved1;
uint16_t reserved2;
} __attribute__((packed));
static ModeInfoBlock mib;
static void setpixel(int x, int y, uint32_t color)
{
uint8_t *fb = (uint8_t*)mib.physbase;
fb[mib.pitch * y + 4 * x + 2] = (color >> 0) & 0xFF;
fb[mib.pitch * y + 4 * x + 1] = (color >> 8) & 0xFF;
fb[mib.pitch * y + 4 * x + 0] = (color >> 16) & 0xFF;
}
extern "C" void init(multiboot::Structure const & data) extern "C" void init(multiboot::Structure const & data)
{ {
write_com(0x3F8, 'H'); write_com(0x3F8, 'H');
write_com(0x3F8, 'i'); write_com(0x3F8, 'i');
write_com(0x3F8, '\n'); write_com(0x3F8, '\n');
const char *msg = "You should not see this."; VideoScreen video(*data.vbe.modeInfo);
while(*msg) for(uint32_t y = 0; y < video.height(); y++)
{ {
*(video++) = *msg++ | 0x0700; for(uint32_t x = 0; x < video.width(); x++)
}
mib = *(ModeInfoBlock*)data.vbe.modeInfo;
for(int y = 0; y < mib.Yres; y++)
{
for(int x = 0; x < mib.Xres; x++)
{ {
uint32_t r = x % 256; video(x,y) = COLOR(255, 0, 0);
uint32_t g = y % 256;
uint32_t b = 0x00;
setpixel(x, y, r | (g << 8) | (b << 16));
} }
} }