Skip to content

Instantly share code, notes, and snippets.

@agesome
Created April 7, 2013 12:20
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 agesome/5330284 to your computer and use it in GitHub Desktop.
Save agesome/5330284 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <assert.h>
#include <math.h>
#include <lrmi.h>
#include <sys/ioctl.h>
#include <sys/io.h>
#include <sys/kd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
// 1024x768
#define VIDEO_MODE 324
#define VIDEO_H 1024
#define VIDEO_W 768
#define FARPTR(p) (p[1] * 16 + p[0])
struct vbe_info
{
uint8_t signature[4];
uint16_t version;
uint16_t oemStringPtr[2];
uint8_t capabilities[4];
uint16_t videomodes[2];
uint16_t totalMemory; // 64K blocks
uint16_t oemSoftwareRev;
uint16_t oemVendorNamePtr[2];
uint16_t oemProductNamePtr[2];
uint16_t oemProductRevPtr[2];
uint16_t reserved[111];
uint8_t oemData[256];
} __attribute__ ((packed));
struct modeinfo
{
unsigned short mode_attributes;
unsigned char win_a_attributes;
unsigned char win_b_attributes;
unsigned short win_granularity;
unsigned short win_size;
unsigned short win_a_segment;
unsigned short win_b_segment;
unsigned short win_func_ptr_off;
unsigned short win_func_ptr_seg;
unsigned short bytes_per_scanline;
unsigned short x_resolution;
unsigned short y_resolution;
unsigned char x_char_size;
unsigned char y_char_size;
unsigned char number_of_planes;
unsigned char bits_per_pixel;
unsigned char number_of_banks;
unsigned char memory_model;
unsigned char bank_size;
unsigned char number_of_image_pages;
unsigned char res1;
unsigned char red_mask_size;
unsigned char red_field_position;
unsigned char green_mask_size;
unsigned char green_field_position;
unsigned char blue_mask_size;
unsigned char blue_field_position;
unsigned char rsvd_mask_size;
unsigned char rsvd_field_position;
unsigned char direct_color_mode_info;
unsigned int phys_base_ptr;
unsigned int offscreen_mem_offset;
unsigned short offscreen_mem_size;
unsigned char res2[206];
} __attribute__ ((packed));
struct vbe_info * info;
struct modeinfo * minfo;
struct LRMI_regs r = {0};
uint32_t * vmem;
void
pixel (int x, int y, uint8_t r, uint8_t g, uint8_t b)
{
const int pixel_size = minfo->bits_per_pixel / 8;
const int bpl = minfo->bytes_per_scanline / 4;
uint32_t *ptr = vmem;
uint32_t c = 0;
c = (r << 16) | (g << 8) | b;
ptr += y * bpl + x;
*ptr = c;
}
void
line (int x0, int y0, int x1, int y1, uint8_t r, uint8_t g, uint8_t b)
{
int dx = abs (x1 - x0);
int dy = abs (y1 - y0);
int sx = -1, sy = -1;
if (x0 < x1)
sx = 1;
if (y0 < y1)
sy = 1;
int err = dx - dy;
int err_;
while (x0 != x1 || y0 != y1)
{
pixel (x0, y0, r, g, b);
err_ = 2 * err;
if (err_ > -dy)
{
err -= dy;
x0 += sx;
}
if (err_ < dx)
{
err += dx;
y0 += sy;
}
}
}
void
rect (int x0, int y0, int x1, int y1, uint8_t r, uint8_t g, uint8_t b)
{
printf ("%d %d %d %d\n", x0, y0, x1, y1);
int x, y;
for (x = x0; x < x1; x++)
for (y = y0; y < y1; y++)
{
pixel (x, y, r, g, b);
}
}
int main (void)
{
int x, y;
void * alloc = NULL;
if (!LRMI_init ())
{
fprintf(stderr, "%s\n", "Failed to initialize LRMI!");
return EXIT_FAILURE;
}
printf ("\t\tVBE2 test program\n\n");
info = LRMI_alloc_real (sizeof (struct vbe_info));
minfo = LRMI_alloc_real (sizeof (struct modeinfo));
/* access to video bios ports */
ioperm (0, 1024, 1);
iopl (3);
r.eax = 0x4f00;
r.es = (unsigned int) info >> 4;
r.edi = 0;
memcpy (info->signature, "VBE2", 4);
LRMI_int (0x10, &r);
printf ("VBE Version 0x%x\n", info->version);
printf ("Vendor string: %s\n", (char *) FARPTR(info->oemStringPtr));
printf ("Video card: %s\n", (char *) FARPTR(info->oemProductNamePtr));
printf ("Video memory: %dK\n", info->totalMemory * 64);
memset(&r, 0, sizeof(r));
r.eax = 0x4f01;
r.ecx = VIDEO_MODE;
r.es = (unsigned int) minfo >> 4;
r.edi = (unsigned int) minfo & 0xf;
LRMI_int (0x10, &r);
if (r.eax == 0x4f)
printf ("Mode info OK\n");
if (minfo->mode_attributes & (1 << 7))
{
printf ("Linear addressing possible!\n");
printf ("\tPhysical address: %X\n", minfo->phys_base_ptr);
}
ioctl(1, KDSETMODE, KD_GRAPHICS);
memset(&r, 0, sizeof(r));
r.eax = 0x4f02;
r.ebx = VIDEO_MODE | 0x4000; /* add linear FB flag */
LRMI_int (0x10, &r);
if (r.eax == 0x4f)
printf ("Mode set OK\n");
printf ("Selected mode %dx%d, %d bpp\n", minfo->x_resolution,
minfo->y_resolution, minfo->bits_per_pixel);
printf ("%d bytes per line\n", minfo->bytes_per_scanline);
printf ("Mapping video memory to process memory\n");
int fd = open ("/dev/mem", O_RDWR);
assert (fd != -1);
alloc = malloc (info->totalMemory * 64 * 1024);
vmem = mmap (alloc, info->totalMemory * 64 * 1024, PROT_WRITE,
MAP_SHARED, fd, minfo->phys_base_ptr);
assert (vmem != MAP_FAILED);
printf ("Mapped OK\n");
line (18, 18, 42, 180, 255, 255, 255);
rect (50, 50, 200, 300, 255, 255, 0);
LRMI_free_real (info);
LRMI_free_real (minfo);
munmap (vmem, info->totalMemory * 64 * 1024);
free (alloc);
ioctl(0, KDSETMODE, KD_TEXT);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment