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.")
|
||||
|
||||
#include "vbe.hpp"
|
||||
|
||||
namespace multiboot
|
||||
{
|
||||
template<typename T>
|
||||
|
@ -156,7 +158,7 @@ namespace multiboot
|
|||
const APMTable * apmTable;
|
||||
struct {
|
||||
uint32_t controlInfo;
|
||||
uint32_t modeInfo;
|
||||
vbe::ModeInfo const * modeInfo;
|
||||
uint16_t mode;
|
||||
uint16_t interfaceSegment;
|
||||
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
|
||||
|
||||
KERNEL = video.ker
|
||||
LIBS = -lboot
|
||||
LIBS = -lboot -lvideo
|
||||
|
||||
all: builddir $(KERNEL)
|
||||
|
||||
|
|
|
@ -3,13 +3,7 @@
|
|||
#include <multiboot.hpp>
|
||||
#include <io.hpp>
|
||||
|
||||
struct dummy;
|
||||
|
||||
// Symbols generated by linker, no useful content in there...
|
||||
extern dummy kernelStartMarker;
|
||||
extern dummy kernelEndMarker;
|
||||
|
||||
uint16_t * video = (uint16_t*)0xB8000;
|
||||
#include <driver/video.hpp>
|
||||
|
||||
// Prüft, ob man bereits schreiben kann
|
||||
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);
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
write_com(0x3F8, 'H');
|
||||
write_com(0x3F8, 'i');
|
||||
write_com(0x3F8, '\n');
|
||||
|
||||
const char *msg = "You should not see this.";
|
||||
while(*msg)
|
||||
VideoScreen video(*data.vbe.modeInfo);
|
||||
for(uint32_t y = 0; y < video.height(); y++)
|
||||
{
|
||||
*(video++) = *msg++ | 0x0700;
|
||||
}
|
||||
|
||||
mib = *(ModeInfoBlock*)data.vbe.modeInfo;
|
||||
|
||||
for(int y = 0; y < mib.Yres; y++)
|
||||
for(uint32_t x = 0; x < video.width(); x++)
|
||||
{
|
||||
for(int x = 0; x < mib.Xres; x++)
|
||||
{
|
||||
uint32_t r = x % 256;
|
||||
uint32_t g = y % 256;
|
||||
uint32_t b = 0x00;
|
||||
|
||||
setpixel(x, y, r | (g << 8) | (b << 16));
|
||||
video(x,y) = COLOR(255, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue