Files

174 lines
3.8 KiB
C
Raw Permalink Normal View History

2026-06-05 16:14:14 -05:00
#include <types.h>
#include <mm/paging.h>
#include <stdio.h>
#include <port_io.h>
#include <math.h>
#include <drivers/graphics/vga.h>
#define VBE_DISPI_IOPORT_INDEX 0x01CE
#define VBE_DISPI_IOPORT_DATA 0x01CF
#define VBE_DISPI_INDEX_ID 0x0
#define VBE_DISPI_INDEX_XRES 0x1
#define VBE_DISPI_INDEX_YRES 0x2
#define VBE_DISPI_INDEX_BPP 0x3
#define VBE_DISPI_INDEX_ENABLE 0x4
#define VBE_DISPI_INDEX_BANK 0x5
#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
#define VBE_DISPI_INDEX_X_OFFSET 0x8
#define VBE_DISPI_INDEX_Y_OFFSET 0x9
#define VBE_DISPI_DISABLED 0x00
#define VBE_DISPI_ENABLED 0x01
#define VBE_DISPI_LFB_ENABLED 0x40
static bool bga_init = false;
static bool bga_error = false;
uint32_t current_bpp = 0;
uint32_t current_xres = 0;
uint32_t current_yres = 0;
static struct bga_framebuffer bga_fb;
void init_bga_framebuffer(uint32_t* _p)
{
uint32_t width = 1024;
uint32_t height = 768;
uint32_t bpp = 32;
uint32_t pitch = width * (bpp / 8);
uint32_t fb_size = pitch * height;
fb_size = (fb_size + 0xFFF) & ~0xFFF;
uint8_t* bp = (uint8_t*) _p;
for (uint32_t off = 0; off < fb_size; off += 0x1000)
{
map_page(bp + off, bp + off);
}
bga_fb.addr = _p;
bga_fb.bpp = bpp;
bga_fb.height = height;
bga_fb.width = width;
bga_fb.pitch = pitch;
bga_init = true;
}
uint8_t* bga_get_framebuffer(void)
{
return bga_fb.addr;
}
void bga_write_register(uint16_t index, uint16_t data)
{
outw(VBE_DISPI_IOPORT_INDEX, index);
outw(VBE_DISPI_IOPORT_DATA, data);
}
uint16_t bga_read_register(uint16_t index)
{
outw(VBE_DISPI_IOPORT_INDEX, index);
return inw(VBE_DISPI_IOPORT_DATA);
}
void bga_set_video_mode(uint32_t width, uint32_t height, uint32_t bit_depth)
{
bga_write_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
bga_write_register(VBE_DISPI_INDEX_XRES, width);
bga_write_register(VBE_DISPI_INDEX_YRES, height);
bga_write_register(VBE_DISPI_INDEX_BPP, bit_depth);
bga_write_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
/* now we check to see if any info we gave was rejected, in which case everything would be the way it was before we wrote the configuration info. */
uint16_t bpp = bga_read_register(VBE_DISPI_INDEX_BPP);
if (bpp != bit_depth)
{
bga_error = true;
}
else
{
current_bpp = bit_depth;
current_xres = width;
current_yres = height;
}
}
void bga_defaults(void)
{
// Disable device while changing settings
bga_write_register(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
// Set resolution
bga_write_register(VBE_DISPI_INDEX_XRES, 1024);
bga_write_register(VBE_DISPI_INDEX_YRES, 768);
bga_write_register(VBE_DISPI_INDEX_BPP, 32);
// Enable graphics + linear framebuffer
bga_write_register(
VBE_DISPI_INDEX_ENABLE,
VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED
);
}
/*void bga_putpixel(uint32_t x, uint32_t y, uint32_t color)
{
if (current_bpp == 16)
{
uint16_t* fb = (uint16_t*) bga_framebuffer;
uint32_t idx = (y * current_xres + x) * 2;
*(fb + idx) = (uint16_t) color;
}
}*/
void bga_putpixel(uint32_t x, uint32_t y, uint32_t color)
{
uint32_t bytes_per_pixel = bga_fb.bpp / 8;
uint8_t* pixel = (uint8_t*)bga_fb.addr + (y * bga_fb.pitch) + (x * bytes_per_pixel);
*(volatile uint32_t*)pixel = color;
}
void bga_drawline(int x0, int y0, int x1, int y1, uint32_t color)
{
int dx = abs(x1 - x0);
int dy = abs(y1 - y0);
int sx = (x0 < x1) ? 1 : -1;
int sy = (y0 < y1) ? 1 : -1;
int err = dx - dy;
while (1)
{
bga_putpixel(x0, y0, color);
if (x0 == x1 && y0 == y1)
break;
int e2 = err * 2;
if (e2 > -dy)
{
err -= dy;
x0 += sx;
}
if (e2 < dx)
{
err += dx;
y0 += sy;
}
}
}