Skip to content

Instantly share code, notes, and snippets.

@agesome
Created April 4, 2013 18:54
Show Gist options
  • Save agesome/5313103 to your computer and use it in GitHub Desktop.
Save agesome/5313103 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;
}
int main (void)
{
int x, y;
double sv, x_;
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(0, KDSETMODE, KD_GRAPHICS);
memset(&r, 0, sizeof(r));
r.eax = 0x4f02;
r.ebx = VIDEO_MODE | 0x4000;
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);
vmem = malloc (info->totalMemory * 64 * 1024);
vmem = mmap (vmem, info->totalMemory * 64 * 1024, PROT_WRITE,
MAP_SHARED, fd, minfo->phys_base_ptr);
assert (vmem != MAP_FAILED);
printf ("Mapped OK\n");
for (x = 0; x < VIDEO_W; x++)
for (y = 0; y < VIDEO_H; y++)
pixel (x, y, 0, 0, 0);
for (y = 0; y < VIDEO_H; y++)
pixel (y, y, 0xff, 0, 0);
for (y = 0; y < VIDEO_H; y++)
pixel (y + 1, y, 0xff, 0, 0);
for (x = 1; x < VIDEO_W; x++)
{
x_ = (double) x;
sv = fabs (sin (VIDEO_W / x_));
pixel (x, (VIDEO_H * sv) / 2, 0xff, 0xff, 0xff);
printf ("%f %f\n", x_, sv);
}
LRMI_free_real (info);
LRMI_free_real (minfo);
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