Skip to content

Instantly share code, notes, and snippets.

/main.c Secret

Created March 12, 2016 12:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/772bed7d9c40700dd0c5 to your computer and use it in GitHub Desktop.
Save anonymous/772bed7d9c40700dd0c5 to your computer and use it in GitHub Desktop.
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "include/font.h"
#include "include/mboot.h"
#include "include/mod.h"
#include "include/pit.h"
#include "include/ps2.h"
#include "include/tty.h"
#include "include/vbe.h"
/* TODO: Fix struct naming conventions. */
/* TODO: Add paging, scheduling and memory management. */
struct mboot_info_struct* mboot_info = NULL;
struct vbe_mode_info_struct* vbe_mode_info = NULL;
struct vbe_control_info_struct* vbe_control_info = NULL;
int main (struct mboot_info_struct* mboot)
{
mboot_info = mboot;
vbe_mode_info = (struct vbe_mode_info_struct*) (uintptr_t) mboot_info->vbe_mode_info;
vbe_control_info = (struct vbe_control_info_struct*) (uintptr_t) mboot_info->vbe_control_info;
mod_scan ();
if (!ps2_init ())
{
tty_printf ("Warning: PS/2 initialisation failed\n");
tty_update ();
}
tty_printf ("The Glaux Operating System Project version 0.0.1-dev\n");
tty_printf ("%x\n", vbe_control_info->version);
tty_update ();
while (1)
{
pit_sleep (20);
}
return 0;
}
extern struct mboot_info_struct* mboot_info;
struct __attribute__ ((packed)) mboot_info_struct
{
uint32_t flags;
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
uint32_t cmdline;
uint32_t mods_count;
uint32_t mods_addr;
uint32_t num;
uint32_t size;
uint32_t addr;
uint32_t shndx;
uint32_t mmap_length;
uint32_t mmap_addr;
uint32_t drives_length;
uint32_t drives_addr;
uint32_t config_table;
uint32_t boot_loader_name;
uint32_t apm_table;
uint32_t vbe_control_info;
uint32_t vbe_mode_info;
uint16_t vbe_mode;
uint16_t vbe_interface_seg;
uint16_t vbe_interface_off;
uint16_t vbe_interface_len;
};
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include "include/font.h"
#include "include/mboot.h"
#include "include/tty.h"
#include "include/vbe.h"
/* TODO: "uint8_t tempbuf [800*600];" is unsafe.
* There is undefined behavior if the display is greater.
* A memory allocator is required here. */
/* TODO: Don't let other threads/interrupts print while already printing. */
/* TODO: There is undefined behaviour if the vbe mode is not linear. */
/* TODO: Write to the video memory in the longest possible word sizes. */
uint32_t tempbuf [800*600];
uint32_t pixel_x = 0;
uint32_t pixel_y = 0;
struct tty_printf_struct
{
size_t index;
};
void tty_update ()
{
uint32_t bpp = vbe_mode_info->bpp;
uint32_t width = vbe_mode_info->x_res;
uint32_t height = vbe_mode_info->y_res;
uint8_t* framebuf = (uint8_t*) (uintptr_t) vbe_mode_info->framebuffer_addr;
bool vbe_3 = (vbe_control_info->version >= 0x0300);
uint32_t pitch = vbe_3 ? vbe_mode_info->lin_pitch : vbe_mode_info->pitch;
uint8_t red_pos = vbe_3 ?
vbe_mode_info->lin_red_field_pos : vbe_mode_info->red_field_pos;
uint8_t red_mask_size = vbe_3 ?
vbe_mode_info->lin_red_mask_size : vbe_mode_info->red_mask_size;
uint8_t green_pos = vbe_3 ?
vbe_mode_info->lin_green_field_pos : vbe_mode_info->green_field_pos;
uint8_t green_mask_size = vbe_3 ?
vbe_mode_info->lin_green_mask_size : vbe_mode_info->green_mask_size;
uint8_t blue_pos = vbe_3 ?
vbe_mode_info->lin_blue_field_pos : vbe_mode_info->blue_field_pos;
uint8_t blue_mask_size = vbe_3 ?
vbe_mode_info->lin_blue_mask_size : vbe_mode_info->blue_mask_size;
uint32_t red_mask = (1 << red_mask_size) - 1;
uint32_t green_mask = (1 << green_mask_size) - 1;
uint32_t blue_mask = (1 << blue_mask_size) - 1;
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
size_t index = (y * width) + x;
uint32_t data = tempbuf[index];
uint32_t red = (data >> (24 - red_mask_size)) & red_mask;
uint32_t green = (data >> (16 - green_mask_size)) & green_mask;
uint32_t blue = (data >> (8 - blue_mask_size)) & blue_mask;
data = (red << red_pos) | (green << green_pos) | (blue << blue_pos);
index = (y * pitch) + (x * ((bpp + 7) / 8));
if (bpp == 15 || bpp == 16)
{
framebuf[index+0] = data >> 0;
framebuf[index+1] = data >> 8;
}
else if (bpp == 24)
{
framebuf[index+0] = data >> 0;
framebuf[index+1] = data >> 8;
framebuf[index+2] = data >> 16;
}
else if (bpp == 32)
{
framebuf[index+0] = data >> 0;
framebuf[index+1] = data >> 8;
framebuf[index+2] = data >> 16;
framebuf[index+3] = data >> 24;
}
}
}
}
size_t tty_write (const char* str, size_t size)
{
size_t i = 0;
while (i < size)
{
struct wchar wc = wcget (&str[i], size-i);
if (wc.bytecount == -1)
{
return i;
}
tty_blitc (wc.codepoint, 0x000000, 0xCCCCCC);
i += wc.bytecount;
}
return i;
}
size_t callback (void* info_ptr, const char* str, size_t size)
{
struct tty_printf_struct* info = (struct tty_printf_struct*) info_ptr;
size_t i = tty_write (str, size);
info->index += i;
return i;
}
int tty_printf (const char* format, ...)
{
va_list args;
va_start (args, format);
struct tty_printf_struct info;
int i = vcbprintf (&info, callback, format, args);
va_end (args);
return i;
}
int tty_blitc (uint32_t c, uint32_t fg, uint32_t bg)
{
const struct font_stat_struct* font_stat = font_get_stat ();
const struct font_data_struct* font_data = font_get_data_entry (c);
if (!font_stat || !font_data)
{
return -1;
}
uint32_t width = vbe_mode_info->x_res;
uint32_t height = vbe_mode_info->y_res;
uint16_t cwidth = __builtin_bswap16 (font_data->width);
uint16_t cheight = __builtin_bswap16 (font_data->height);
int16_t cxoffset = __builtin_bswap16 (font_data->xoffset);
int16_t cyoffset = __builtin_bswap16 (font_data->yoffset);
int16_t cdevwidth = __builtin_bswap16 (font_data->devwidth);
size_t x, y;
if (c == '\n' || pixel_x + cdevwidth > width)
{
for (y = pixel_y; y < pixel_y + font_stat->maxh; y++)
{
for (x = pixel_x; x < width; x++)
{
size_t index = (y * width) + x;
tempbuf[index] = bg;
}
}
pixel_x = 0;
if (pixel_y + (font_stat->maxh * 2) > height)
{
memmove (tempbuf, tempbuf + (width * font_stat->maxh),
width * pixel_y * sizeof (uint32_t));
for (y = pixel_y; y < height; y++)
{
for (x = 0; x < width; x++)
{
size_t index = (y * width) + x;
tempbuf[index] = bg;
}
}
}
else
{
pixel_y += font_stat->maxh;
}
if (c == '\n')
{
return c;
}
}
for (y = pixel_y; y < pixel_y + font_stat->maxh; y++)
{
for (x = pixel_x; x < pixel_x + cdevwidth; x++)
{
size_t index = (y * width) + x;
tempbuf[index] = bg;
}
}
uint32_t i = 0;
uint8_t b = 0;
for (y = pixel_y - cyoffset + font_stat->asce - cheight;
y < pixel_y - cyoffset + font_stat->asce; y++)
{
for (x = pixel_x + cxoffset; x < pixel_x + cxoffset + cwidth; x++)
{
if (b > 7)
{
b = 0;
i += 1;
}
uint8_t bitmap = font_data->bitmap[i];
bool on = bitmap & (1 << (7 - b));
size_t index = (y * width) + x;
tempbuf[index] = (on ? fg : bg);
b += 1;
}
}
pixel_x += cdevwidth;
return c;
}
extern struct vbe_mode_info_struct* vbe_mode_info;
extern struct vbe_control_info_struct* vbe_control_info;
struct __attribute__ ((packed)) vbe_mode_info_struct
{
uint16_t mode_attr;
uint8_t winA_attr;
uint8_t winB_attr;
uint16_t win_granul;
uint16_t win_size;
uint16_t winA_seg;
uint16_t winB_seg;
uint32_t win_func_addr;
uint16_t pitch;
uint16_t x_res;
uint16_t y_res;
uint8_t x_char_size;
uint8_t y_char_size;
uint8_t planes;
uint8_t bpp;
uint8_t banks;
uint8_t memmodel;
uint8_t bank_size;
uint8_t img_pages;
uint8_t reserved0;
uint8_t red_mask_size;
uint8_t red_field_pos;
uint8_t green_mask_size;
uint8_t green_field_pos;
uint8_t blue_mask_size;
uint8_t blue_field_pos;
uint8_t reserved_mask_size;
uint8_t reserved_field_pos;
uint8_t direct_color_attr;
uint32_t framebuffer_addr;
uint32_t reserved1;
uint16_t reserved2;
uint16_t lin_pitch;
uint8_t bnk_img_pages;
uint8_t lin_img_pages;
uint8_t lin_red_mask_size;
uint8_t lin_red_field_pos;
uint8_t lin_green_mask_size;
uint8_t lin_green_field_pos;
uint8_t lin_blue_mask_size;
uint8_t lin_blue_field_pos;
uint8_t lin_reserved_mask_size;
uint8_t lin_reserved_field_pos;
uint32_t max_pixel_clock;
};
struct __attribute__ ((packed)) vbe_control_info_struct
{
uint32_t signature;
uint16_t version;
uint32_t oem_str_addr;
uint32_t capabilities;
uint32_t video_mode_addr;
uint16_t blocks;
uint16_t oem_software_revision;
uint32_t oem_vendor_name_addr;
uint32_t oem_product_name_addr;
uint32_t oem_product_revision_addr;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment