mirror of
https://github.com/cowmonk/cowos.git
synced 2025-10-27 22:43:26 +00:00
cowos attempted gdt, but at least we have vga drivers now
This commit is contained in:
parent
b08b0728ae
commit
41b34d2a9d
14 changed files with 253 additions and 140 deletions
|
|
@ -1,61 +1,118 @@
|
|||
#include <drivers/video/vga.h>
|
||||
/* #include <bootloader.h> */
|
||||
#include <string.h>
|
||||
|
||||
/* for frame buffer
|
||||
static volatile struct limine_framebuffer_request limineFBreq = {
|
||||
.id = LIMINE_FRAMEBUFFER_REQUEST, .revision = 0};
|
||||
*/
|
||||
|
||||
size_t term_row;
|
||||
size_t term_col;
|
||||
uint8_t term_color;
|
||||
uint16_t* term_buf = (uint16_t*)VGA_MEMORY;
|
||||
|
||||
void
|
||||
term_init(void)
|
||||
// Helper functions for port IO
|
||||
static inline void
|
||||
outb(uint16_t port, uint8_t val)
|
||||
{
|
||||
term_row = 0;
|
||||
term_col = 0;
|
||||
term_color = vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
|
||||
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
|
||||
}
|
||||
|
||||
for (size_t y = 0; y < VGA_HEIGHT; y++) {
|
||||
for (size_t x = 0; x < VGA_WIDTH; x++) {
|
||||
const size_t index = y * VGA_WIDTH + x;
|
||||
term_buf[index] = vga_entry(' ', term_color);
|
||||
}
|
||||
}
|
||||
static inline uint8_t
|
||||
inb(uint16_t port)
|
||||
{
|
||||
uint8_t ret;
|
||||
__asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Write vga registers for mode change
|
||||
static void
|
||||
write_regs(uint8_t *regs)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
// Write misc output register
|
||||
outb(VGA_MISC_WRITE, *regs);
|
||||
regs++;
|
||||
|
||||
// Write sequencer registers (5 registers)
|
||||
for (i = 0; i < 5; i++) {
|
||||
outb(VGA_SEQ_INDEX, i);
|
||||
outb(VGA_SEQ_DATA, *regs);
|
||||
regs++;
|
||||
}
|
||||
|
||||
// Unlock CRTC registers 0-7 by clearing protect bit
|
||||
outb(VGA_CRTC_INDEX, 0x03);
|
||||
outb(VGA_CRTC_DATA, inb(VGA_CRTC_DATA) | 0x80);
|
||||
outb(VGA_CRTC_INDEX, 0x11);
|
||||
outb(VGA_CRTC_DATA, inb(VGA_CRTC_DATA) & ~0x80);
|
||||
|
||||
// Update the register values to match
|
||||
regs[0x03] = regs[0x03] | 0x80;
|
||||
regs[0x11] = regs[0x11] & ~0x80;
|
||||
|
||||
// Write CRTC registers (25 registers)
|
||||
for (i = 0; i < 25; i++) {
|
||||
outb(VGA_CRTC_INDEX, i);
|
||||
outb(VGA_CRTC_DATA, *regs);
|
||||
regs++;
|
||||
}
|
||||
|
||||
// Write graphics controller registers (9 registers)
|
||||
for (i = 0; i < 9; i++) {
|
||||
outb(VGA_GC_INDEX, i);
|
||||
outb(VGA_GC_DATA, *regs);
|
||||
regs++;
|
||||
}
|
||||
|
||||
// Write attribute controller registers (21 registers)
|
||||
for (i = 0; i < 21; i++) {
|
||||
inb(VGA_INSTAT_READ); // Reset flip-flop
|
||||
outb(VGA_AC_INDEX, i);
|
||||
outb(VGA_AC_WRITE, *regs);
|
||||
regs++;
|
||||
}
|
||||
|
||||
// Enable video display
|
||||
inb(VGA_INSTAT_READ);
|
||||
outb(VGA_AC_INDEX, 0x20);
|
||||
}
|
||||
|
||||
void
|
||||
term_setcolor(uint8_t color)
|
||||
vga_set_mode_13h(void)
|
||||
{
|
||||
term_color = color;
|
||||
// Register values for VGA mode 13h (320x200, 256 colors)
|
||||
// Order: Misc, Seq[5], CRTC[25], GC[9], AC[21]
|
||||
static uint8_t mode_320x200x256[] = {
|
||||
// Misc output register
|
||||
0x63,
|
||||
// Sequencer registers
|
||||
0x03, 0x01, 0x0F, 0x00, 0x0E,
|
||||
// CRTC registers
|
||||
0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
|
||||
0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
|
||||
0xFF,
|
||||
// Graphics controller registers
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
|
||||
0xFF,
|
||||
// Attribute controller registers
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x41, 0x00, 0x0F, 0x00, 0x00
|
||||
};
|
||||
|
||||
write_regs(mode_320x200x256);
|
||||
}
|
||||
|
||||
void
|
||||
term_putentryat(char c, uint8_t color, size_t x, size_t y)
|
||||
vga_put_pixel(uint16_t x, uint16_t y, uint8_t color)
|
||||
{
|
||||
const size_t index = y * VGA_HEIGHT + x;
|
||||
term_buf[index] = vga_entry(c, color);
|
||||
// check bounds
|
||||
if (x >= VGA_WIDTH || y >= VGA_HEIGHT) return;
|
||||
|
||||
// Direct write to video memory: offset = y * 320 + x
|
||||
uint8_t *vga = (uint8_t *)VGA_GRAPHICS_BUFFER;
|
||||
vga[y * VGA_WIDTH + x] = color;
|
||||
}
|
||||
|
||||
void
|
||||
term_putchar(char c)
|
||||
vga_clear_screen(uint8_t color)
|
||||
{
|
||||
term_putentryat(c, term_color, term_col, term_row);
|
||||
if (++term_col == VGA_WIDTH) {
|
||||
term_col = 0;
|
||||
if (++term_row == VGA_HEIGHT) {
|
||||
term_row = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
term_writestr(const char* data)
|
||||
{
|
||||
for (size_t i = 0; data[i] != '\0'; i++) {
|
||||
term_putchar(data[i]);
|
||||
}
|
||||
uint8_t *vga = (uint8_t *)VGA_GRAPHICS_BUFFER;
|
||||
// fill entire buffer (64k pixels)
|
||||
for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
|
||||
vga[i] = color;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
kernel/drivers/video/vga.o
Normal file
BIN
kernel/drivers/video/vga.o
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue