Created
April 18, 2013 16:18
-
-
Save agesome/5414040 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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