Adds simple video driver.
This commit is contained in:
parent
b873c662c8
commit
f147ee1901
9 changed files with 153 additions and 62 deletions
Binary file not shown.
56
prototypes-rework/include/driver/video.hpp
Normal file
56
prototypes-rework/include/driver/video.hpp
Normal 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
|
@ -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;
|
||||||
|
|
25
prototypes-rework/include/picture.hpp
Normal file
25
prototypes-rework/include/picture.hpp
Normal 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;
|
||||||
|
};
|
39
prototypes-rework/include/vbe.hpp
Normal file
39
prototypes-rework/include/vbe.hpp
Normal 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));
|
||||||
|
|
||||||
|
}
|
12
prototypes-rework/libvideo/Makefile
Normal file
12
prototypes-rework/libvideo/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
##
|
||||||
|
# Build video library.
|
||||||
|
##
|
||||||
|
|
||||||
|
include ../config.mk
|
||||||
|
|
||||||
|
LIBRARY = libvideo.a
|
||||||
|
|
||||||
|
all: builddir $(LIBRARY)
|
||||||
|
|
||||||
|
include ../common.mk
|
||||||
|
include ../library.mk
|
12
prototypes-rework/libvideo/src/video.cpp
Normal file
12
prototypes-rework/libvideo/src/video.cpp
Normal 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue