summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Huber <huber@crans.org>2010-04-24 17:27:00 -0400
committerOlivier Huber <huber@crans.org>2010-04-24 17:27:00 -0400
commitbd1c4e26a2c6ca07657bca598cc458301b4d8a1e (patch)
treee4c1377710eab84a22c029503fd455b0cf0168e4 /sys-apps
downloadxhub-bd1c4e26a2c6ca07657bca598cc458301b4d8a1e.tar.gz
xhub-bd1c4e26a2c6ca07657bca598cc458301b4d8a1e.tar.bz2
xhub-bd1c4e26a2c6ca07657bca598cc458301b4d8a1e.zip
Initial import
Diffstat (limited to 'sys-apps')
-rw-r--r--sys-apps/v86d/Manifest4
-rw-r--r--sys-apps/v86d/files/v86d-0.1.9-915resolution.patch1005
-rw-r--r--sys-apps/v86d/files/v86d-0.1.9-prot_write.patch28
-rw-r--r--sys-apps/v86d/v86d-0.1.9.ebuild59
4 files changed, 1096 insertions, 0 deletions
diff --git a/sys-apps/v86d/Manifest b/sys-apps/v86d/Manifest
new file mode 100644
index 0000000..b56bd4f
--- /dev/null
+++ b/sys-apps/v86d/Manifest
@@ -0,0 +1,4 @@
+AUX v86d-0.1.9-915resolution.patch 27936 RMD160 69114c1f02a7fe98744df4361fc4f8850c766f7e SHA1 7df9358d5db2d2739b40026d765988d441673d8f SHA256 b08df989846d6647ad6040594c9891be38ca3c170e7229f37293e7415d5a2417
+AUX v86d-0.1.9-prot_write.patch 1020 RMD160 5cd1a337dbd5316e6ef1e7cb14c024f051bb3272 SHA1 fe63622120c164e5b95d37f347d234bfb5ed28a9 SHA256 faaf65c087887e1c78f6c8c92eed6fa89d87128d5cdff462fbb00081f0a3e4fb
+DIST v86d-0.1.9.tar.bz2 69752 RMD160 e2d9cda4e8b40a5002c8448d1954a06c5fddb3bf SHA1 ca16ae61329847955ca65da3222131866703a02a SHA256 8167dec4ff919cfd73f854bbd3244f05c2b867e014fa8298044ea7cfd66d18a8
+EBUILD v86d-0.1.9.ebuild 1595 RMD160 98250c756f07939a6060648a1bec833179b6fd62 SHA1 f4b72891c046c9c939795dd3b2b6f402aa886f70 SHA256 5b1157c607b0f7d60afbde75339e7791b351522457e52020ec4b5d080236eedf
diff --git a/sys-apps/v86d/files/v86d-0.1.9-915resolution.patch b/sys-apps/v86d/files/v86d-0.1.9-915resolution.patch
new file mode 100644
index 0000000..9f8c16b
--- /dev/null
+++ b/sys-apps/v86d/files/v86d-0.1.9-915resolution.patch
@@ -0,0 +1,1005 @@
+diff -Naur v86d-0.1.9.orig/915resolution.c v86d-0.1.9/915resolution.c
+--- v86d-0.1.9.orig/915resolution.c 1970-01-01 01:00:00.000000000 +0100
++++ v86d-0.1.9/915resolution.c 2008-10-04 15:53:23.155038024 +0200
+@@ -0,0 +1,964 @@
++/* 915 resolution by steve tomljenovic
++ *
++ * This was tested only on Sony VGN-FS550. Use at your own risk
++ *
++ * This code is based on the techniques used in :
++ *
++ * - 855patch. Many thanks to Christian Zietz (czietz gmx net)
++ * for demonstrating how to shadow the VBIOS into system RAM
++ * and then modify it.
++ *
++ * - 1280patch by Andrew Tipton (andrewtipton null li).
++ *
++ * - 855resolution by Alain Poirier
++ *
++ * This source code is into the public domain.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#define __USE_GNU
++#include <string.h>
++#include <sys/mman.h>
++#include <fcntl.h>
++
++#if defined(__NetBSD__)
++#include <sys/types.h>
++#include <machine/sysarch.h>
++#include "bsd_io.h"
++#elif defined(__FreeBSD__)
++#include "bsd_io.h"
++#elif defined(linux)
++#include <sys/io.h>
++#endif
++
++#include <unistd.h>
++#include <assert.h>
++
++
++
++#define NEW(a) ((a *)(calloc(1, sizeof(a))))
++#define FREE(a) (free(a))
++
++#define VBIOS_START 0xc0000
++#define VBIOS_SIZE 0x10000
++
++#define VBIOS_FILE "/dev/mem"
++
++#define FALSE 0
++#define TRUE 1
++
++#define MODE_TABLE_OFFSET_845G 617
++
++#define VERSION "0.5.3"
++
++#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
++#define ATI_SIGNATURE2 "ATI Technologies Inc"
++#define NVIDIA_SIGNATURE "NVIDIA Corp"
++#define INTEL_SIGNATURE "Intel Corp"
++
++typedef unsigned char * address;
++typedef unsigned char byte;
++typedef unsigned short word;
++typedef unsigned char boolean;
++typedef unsigned int cardinal;
++
++typedef enum {
++ CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G, CT_915G, CT_915GM, CT_945G, CT_945GM,
++ CT_946GZ, CT_G965, CT_Q965, CT_965GM
++} chipset_type;
++
++char * chipset_type_names[] = {
++ "UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM",
++ "946GZ", "G965", "Q965", "965GM"
++};
++
++typedef enum {
++ BT_UNKWN, BT_1, BT_2, BT_3
++} bios_type;
++
++char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
++
++int freqs[] = { 60, 75, 85 };
++
++typedef struct {
++ byte mode;
++ byte bits_per_pixel;
++ word resolution;
++ byte unknown;
++} __attribute__((packed)) vbios_mode;
++
++typedef struct {
++ byte unknow1[2];
++ byte x1;
++ byte x_total;
++ byte x2;
++ byte y1;
++ byte y_total;
++ byte y2;
++} __attribute__((packed)) vbios_resolution_type1;
++
++typedef struct {
++ unsigned long clock;
++
++ word x1;
++ word htotal;
++ word x2;
++ word hblank;
++ word hsyncstart;
++ word hsyncend;
++
++ word y1;
++ word vtotal;
++ word y2;
++ word vblank;
++ word vsyncstart;
++ word vsyncend;
++} __attribute__((packed)) vbios_modeline_type2;
++
++typedef struct {
++ byte xchars;
++ byte ychars;
++ byte unknown[4];
++
++ vbios_modeline_type2 modelines[];
++} __attribute__((packed)) vbios_resolution_type2;
++
++typedef struct {
++ unsigned long clock;
++
++ word x1;
++ word htotal;
++ word x2;
++ word hblank;
++ word hsyncstart;
++ word hsyncend;
++
++ word y1;
++ word vtotal;
++ word y2;
++ word vblank;
++ word vsyncstart;
++ word vsyncend;
++
++ word timing_h;
++ word timing_v;
++
++ byte unknown[6];
++} __attribute__((packed)) vbios_modeline_type3;
++
++typedef struct {
++ unsigned char unknown[6];
++
++ vbios_modeline_type3 modelines[];
++} __attribute__((packed)) vbios_resolution_type3;
++
++
++typedef struct {
++ cardinal chipset_id;
++ chipset_type chipset;
++ bios_type bios;
++
++ int bios_fd;
++ address bios_ptr;
++
++ vbios_mode * mode_table;
++ cardinal mode_table_size;
++
++ byte b1, b2;
++
++ boolean unlocked;
++} vbios_map;
++
++
++void initialize_system(char * filename) {
++ if (!filename) {
++#if defined(__FreeBSD__)
++ int iofd = open("/dev/io", O_RDONLY);
++ if (iofd == -1) {
++ perror("Unable to obtain the proper IO permissions");
++ exit(2);
++ }
++#elif defined(__NetBSD__)
++ if (i386_iopl(3) < 0) {
++ perror("Unable to obtain the proper IO permissions");
++ exit(2);
++ }
++#elif defined(linux)
++ if (iopl(3) < 0) {
++ perror("Unable to obtain the proper IO permissions");
++ exit(2);
++ }
++#else
++#error Not ported to this operating system
++#endif
++ }
++}
++
++cardinal get_chipset_id(void) {
++ outl(0x80000000, 0xcf8);
++ return inl(0xcfc);
++}
++
++chipset_type get_chipset(cardinal id) {
++ chipset_type type;
++
++ switch (id) {
++ case 0x35758086:
++ type = CT_830;
++ break;
++
++ case 0x25608086:
++ type = CT_845G;
++ break;
++
++ case 0x35808086:
++ type = CT_855GM;
++ break;
++
++ case 0x25708086:
++ type = CT_865G;
++ break;
++
++ case 0x25808086:
++ type = CT_915G;
++ break;
++
++ case 0x25908086:
++ type = CT_915GM;
++ break;
++
++ case 0x27708086:
++ type = CT_945G;
++ break;
++
++ case 0x27a08086:
++ type = CT_945GM;
++ break;
++
++ case 0x29708086:
++ type = CT_946GZ;
++ break;
++
++ case 0x29a08086:
++ type = CT_G965;
++ break;
++
++ case 0x29908086:
++ type = CT_Q965;
++ break;
++
++ case 0x2a008086:
++ type = CT_965GM;
++ break;
++
++ default:
++ type = CT_UNKWN;
++ break;
++ }
++
++ return type;
++}
++
++
++vbios_resolution_type1 * map_type1_resolution(vbios_map * map, word res) {
++ vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
++ return ptr;
++}
++
++vbios_resolution_type2 * map_type2_resolution(vbios_map * map, word res) {
++ vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
++ return ptr;
++}
++
++vbios_resolution_type3 * map_type3_resolution(vbios_map * map, word res) {
++ vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
++ return ptr;
++}
++
++
++boolean detect_bios_type(vbios_map * map, boolean modeline, int entry_size) {
++ int i;
++ short int r1, r2;
++ float f;
++
++ r1 = r2 = 32000;
++
++ for (i=0; i < map->mode_table_size; i++) {
++ if (map->mode_table[i].resolution <= r1) {
++ r1 = map->mode_table[i].resolution;
++ }
++ else {
++ if (map->mode_table[i].resolution <= r2) {
++ r2 = map->mode_table[i].resolution;
++ }
++ }
++
++ /*printf("r1 = %d r2 = %d\n", r1, r2);*/
++ }
++
++
++ f = ((float) (r2-r1-6)) / entry_size;
++
++ return f == (int) f;
++}
++
++
++void close_vbios(vbios_map * map);
++
++
++vbios_map * open_vbios(char * filename, chipset_type forced_chipset) {
++ vbios_map * map = NEW(vbios_map);
++
++ /*
++ * Determine chipset
++ */
++
++ if (!filename && forced_chipset == CT_UNKWN) {
++ map->chipset_id = get_chipset_id();
++
++ map->chipset = get_chipset(map->chipset_id);
++ }
++ else if (forced_chipset != CT_UNKWN) {
++ map->chipset = forced_chipset;
++ }
++ else {
++ map->chipset = CT_915GM;
++ }
++
++ /*
++ * Map the video bios to memory
++ */
++
++ if (!filename) {
++ map->bios_fd = open(VBIOS_FILE, O_RDWR);
++ if(map->bios_fd < 0) {
++ if (map->chipset == CT_UNKWN) {
++ fprintf(stderr, "Invalid chipset detected: %x\n", map->chipset_id);
++ }
++ perror("Unable to open the BIOS file");
++ exit(2);
++ }
++
++ map->bios_ptr = mmap(0, VBIOS_SIZE,
++ PROT_READ | PROT_WRITE, MAP_SHARED,
++ map->bios_fd, VBIOS_START);
++
++ if (map->bios_ptr == MAP_FAILED) {
++ if (map->chipset == CT_UNKWN) {
++ fprintf(stderr, "Invalid chipset detected: %x\n", map->chipset_id);
++ }
++ perror("Cannot mmap() the video BIOS\n");
++ close(map->bios_fd);
++ exit(2);
++ }
++ }
++ else {
++ map->bios_fd = open(filename, O_RDWR);
++ if(map->bios_fd < 0) {
++ if (map->chipset == CT_UNKWN) {
++ fprintf(stderr, "Invalid chipset detected: %x\n", map->chipset_id);
++ }
++ perror("Unable to open the BIOS file");
++ exit(2);
++ }
++
++ map->bios_ptr = mmap(0, VBIOS_SIZE,
++ PROT_READ | PROT_WRITE, MAP_SHARED,
++ map->bios_fd, 0);
++
++ if (map->bios_ptr == MAP_FAILED) {
++ if (map->chipset == CT_UNKWN) {
++ fprintf(stderr, "Invalid chipset detected: %x\n", map->chipset_id);
++ }
++ perror("Cannot mmap() the BIOS file\n");
++ close(map->bios_fd);
++ exit(2);
++ }
++ }
++
++ /*
++ * check if we have ATI Radeon
++ */
++
++ if (memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE1, strlen(ATI_SIGNATURE1)) ||
++ memmem(map->bios_ptr, VBIOS_SIZE, ATI_SIGNATURE2, strlen(ATI_SIGNATURE2)) ) {
++ fprintf(stderr, "ATI chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\n");
++ close(map->bios_fd);
++ exit(2);
++ }
++
++ /*
++ * check if we have NVIDIA
++ */
++
++ if (memmem(map->bios_ptr, VBIOS_SIZE, NVIDIA_SIGNATURE, strlen(NVIDIA_SIGNATURE))) {
++ fprintf(stderr, "NVIDIA chipset detected. 915resolution only works with Intel 800/900 series graphic chipsets.\n");
++ close(map->bios_fd);
++ exit(2);
++ }
++
++ /*
++ * check if we have Intel
++ */
++
++ if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
++ fprintf(stderr, "Intel chipset detected. However, 915resolution was unable to determine the chipset type.\n");
++
++ fprintf(stderr, "Chipset Id: %x\n", map->chipset_id);
++
++ fprintf(stderr, "Please report this problem to stomljen@yahoo.com\n");
++
++ close_vbios(map);
++ exit(2);
++ }
++
++ /*
++ * check for others
++ */
++
++ if (map->chipset == CT_UNKWN) {
++ fprintf(stderr, "Unknown chipset type and unrecognized bios.\n");
++ fprintf(stderr, "915resolution only works with Intel 800/900 series graphic chipsets.\n");
++
++ fprintf(stderr, "Chipset Id: %x\n", map->chipset_id);
++ close_vbios(map);
++ exit(2);
++ }
++
++ /*
++ * Figure out where the mode table is
++ */
++
++ {
++ address p = map->bios_ptr + 16;
++ address limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
++
++ while (p < limit && map->mode_table == 0) {
++ vbios_mode * mode_ptr = (vbios_mode *) p;
++
++ if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
++ ((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
++
++ map->mode_table = mode_ptr;
++ }
++
++ p++;
++ }
++
++ if (map->mode_table == 0) {
++ fprintf(stderr, "Unable to locate the mode table.\n");
++ fprintf(stderr, "Please run the program 'dump_bios' as root and\n");
++ fprintf(stderr, "email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
++
++ fprintf(stderr, "Chipset: %s\n", chipset_type_names[map->chipset]);
++ close_vbios(map);
++ exit(2);
++ }
++ }
++
++ /*
++ * Determine size of mode table
++ */
++
++ {
++ vbios_mode * mode_ptr = map->mode_table;
++
++ while (mode_ptr->mode != 0xff) {
++ map->mode_table_size++;
++ mode_ptr++;
++ }
++ }
++
++ /*
++ * Figure out what type of bios we have
++ * order of detection is important
++ */
++
++ if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {
++ map->bios = BT_3;
++ }
++ else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {
++ map->bios = BT_2;
++ }
++ else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {
++ map->bios = BT_1;
++ }
++ else {
++ fprintf(stderr, "Unable to determine bios type.\n");
++ fprintf(stderr, "Please run the program 'dump_bios' as root and\n");
++ fprintf(stderr, "email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
++
++ fprintf(stderr, "Chipset: %s\n", chipset_type_names[map->chipset]);
++ fprintf(stderr, "Mode Table Offset: $C0000 + $%x\n", ((cardinal)map->mode_table) - ((cardinal)map->bios_ptr));
++ fprintf(stderr, "Mode Table Entries: %u\n", map->mode_table_size);
++ exit(2);
++ }
++
++ return map;
++}
++
++void close_vbios(vbios_map * map) {
++ assert(!map->unlocked);
++
++ if(map->bios_ptr == MAP_FAILED) {
++ fprintf(stderr, "BIOS should be open already!\n");
++ exit(2);
++ }
++
++ munmap(map->bios_ptr, VBIOS_SIZE);
++ close(map->bios_fd);
++
++ FREE(map);
++}
++
++void unlock_vbios(vbios_map * map) {
++
++ assert(!map->unlocked);
++
++ map->unlocked = TRUE;
++
++ switch (map->chipset) {
++ case CT_UNKWN:
++ break;
++ case CT_830:
++ case CT_855GM:
++ outl(0x8000005a, 0xcf8);
++ map->b1 = inb(0xcfe);
++
++ outl(0x8000005a, 0xcf8);
++ outb(0x33, 0xcfe);
++ break;
++ case CT_845G:
++ case CT_865G:
++ case CT_915G:
++ case CT_915GM:
++ case CT_945G:
++ case CT_945GM:
++ case CT_946GZ:
++ case CT_G965:
++ case CT_Q965:
++ case CT_965GM:
++ outl(0x80000090, 0xcf8);
++ map->b1 = inb(0xcfd);
++ map->b2 = inb(0xcfe);
++
++ outl(0x80000090, 0xcf8);
++ outb(0x33, 0xcfd);
++ outb(0x33, 0xcfe);
++ break;
++ }
++
++#if DEBUG
++ {
++ cardinal t = inl(0xcfc);
++ printf("unlock PAM: (0x%08x)\n", t);
++ }
++#endif
++}
++
++void relock_vbios(vbios_map * map) {
++
++ assert(map->unlocked);
++ map->unlocked = FALSE;
++
++ switch (map->chipset) {
++ case CT_UNKWN:
++ break;
++ case CT_830:
++ case CT_855GM:
++ outl(0x8000005a, 0xcf8);
++ outb(map->b1, 0xcfe);
++ break;
++ case CT_845G:
++ case CT_865G:
++ case CT_915G:
++ case CT_915GM:
++ case CT_945G:
++ case CT_945GM:
++ case CT_946GZ:
++ case CT_G965:
++ case CT_Q965:
++ case CT_965GM:
++ outl(0x80000090, 0xcf8);
++ outb(map->b1, 0xcfd);
++ outb(map->b2, 0xcfe);
++ break;
++ }
++
++#if DEBUG
++ {
++ cardinal t = inl(0xcfc);
++ printf("relock PAM: (0x%08x)\n", t);
++ }
++#endif
++}
++
++
++void list_modes(vbios_map *map, cardinal raw) {
++ cardinal i, x, y;
++
++ for (i=0; i < map->mode_table_size; i++) {
++ switch(map->bios) {
++ case BT_1:
++ {
++ vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
++
++ x = ((((cardinal) res->x2) & 0xf0) << 4) | res->x1;
++ y = ((((cardinal) res->y2) & 0xf0) << 4) | res->y1;
++
++ if (x != 0 && y != 0) {
++ printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
++ }
++
++ if (raw)
++ {
++ printf("Mode %02x (raw) :\n\t%02x %02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
++ }
++
++ }
++ break;
++ case BT_2:
++ {
++ vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
++
++ x = res->modelines[0].x1+1;
++ y = res->modelines[0].y1+1;
++
++ if (x != 0 && y != 0) {
++ printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
++ }
++ }
++ break;
++ case BT_3:
++ {
++ vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
++
++ x = res->modelines[0].x1+1;
++ y = res->modelines[0].y1+1;
++
++ if (x != 0 && y != 0) {
++ printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
++ }
++ }
++ break;
++ case BT_UNKWN:
++ break;
++ }
++ }
++}
++
++static void gtf_timings(int x, int y, int freq,
++ unsigned long *clock,
++ word *hsyncstart, word *hsyncend, word *hblank,
++ word *vsyncstart, word *vsyncend, word *vblank)
++{
++ int hbl, vbl, vfreq;
++
++ vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
++ vfreq = vbl * freq;
++ hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
++ (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
++
++ *vsyncstart = y;
++ *vsyncend = y + 3;
++ *vblank = vbl - 1;
++ *hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
++ *hsyncend = x + hbl / 2 - 1;
++ *hblank = x + hbl - 1;
++ *clock = (x + hbl) * vfreq / 1000;
++}
++
++void set_mode(vbios_map * map, cardinal mode, cardinal x, cardinal y, cardinal bp, cardinal htotal, cardinal vtotal) {
++ int xprev, yprev;
++ cardinal i, j;
++
++ for (i=0; i < map->mode_table_size; i++) {
++ if (map->mode_table[i].mode == mode) {
++ switch(map->bios) {
++ case BT_1:
++ {
++ vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
++
++ if (bp) {
++ map->mode_table[i].bits_per_pixel = bp;
++ }
++
++ res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0);
++ res->x1 = (x & 0xff);
++
++ res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0);
++ res->y1 = (y & 0xff);
++ if (htotal)
++ res->x_total = ((htotal-x) & 0xff);
++
++ if (vtotal)
++ res->y_total = ((vtotal-y) & 0xff);
++ }
++ break;
++ case BT_2:
++ {
++ vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
++
++ res->xchars = x / 8;
++ res->ychars = y / 16 - 1;
++ xprev = res->modelines[0].x1;
++ yprev = res->modelines[0].y1;
++
++ for(j=0; j < 3; j++) {
++ vbios_modeline_type2 * modeline = &res->modelines[j];
++
++ if (modeline->x1 == xprev && modeline->y1 == yprev) {
++ modeline->x1 = modeline->x2 = x-1;
++ modeline->y1 = modeline->y2 = y-1;
++
++ gtf_timings(x, y, freqs[j], &modeline->clock,
++ &modeline->hsyncstart, &modeline->hsyncend,
++ &modeline->hblank, &modeline->vsyncstart,
++ &modeline->vsyncend, &modeline->vblank);
++
++ if (htotal)
++ modeline->htotal = htotal;
++ else
++ modeline->htotal = modeline->hblank;
++
++ if (vtotal)
++ modeline->vtotal = vtotal;
++ else
++ modeline->vtotal = modeline->vblank;
++ }
++ }
++ }
++ break;
++ case BT_3:
++ {
++ vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
++
++ xprev = res->modelines[0].x1;
++ yprev = res->modelines[0].y1;
++
++ for (j=0; j < 3; j++) {
++ vbios_modeline_type3 * modeline = &res->modelines[j];
++
++ if (modeline->x1 == xprev && modeline->y1 == yprev) {
++ modeline->x1 = modeline->x2 = x-1;
++ modeline->y1 = modeline->y2 = y-1;
++
++ gtf_timings(x, y, freqs[j], &modeline->clock,
++ &modeline->hsyncstart, &modeline->hsyncend,
++ &modeline->hblank, &modeline->vsyncstart,
++ &modeline->vsyncend, &modeline->vblank);
++ if (htotal)
++ modeline->htotal = htotal;
++ else
++ modeline->htotal = modeline->hblank;
++ if (vtotal)
++ modeline->vtotal = vtotal;
++ else
++ modeline->vtotal = modeline->vblank;
++
++ modeline->timing_h = y-1;
++ modeline->timing_v = x-1;
++ }
++ }
++ }
++ break;
++ case BT_UNKWN:
++ break;
++ }
++ }
++ }
++}
++
++void display_map_info(vbios_map * map) {
++ printf("Chipset: %s\n", chipset_type_names[map->chipset]);
++ printf("BIOS: %s\n", bios_type_names[map->bios]);
++
++ printf("Mode Table Offset: $C0000 + $%x\n", ((cardinal)map->mode_table) - ((cardinal)map->bios_ptr));
++ printf("Mode Table Entries: %u\n", map->mode_table_size);
++}
++
++
++int parse_args(int argc, char *argv[], char ** filename, chipset_type *forced_chipset, cardinal *list, cardinal *mode, cardinal *x, cardinal *y, cardinal *bp, cardinal *raw, cardinal *htotal, cardinal *vtotal) {
++ cardinal index = 1;
++
++ *list = *mode = *x = *y = *raw = *htotal = *vtotal = 0;
++
++ *forced_chipset = CT_UNKWN;
++
++ *filename = NULL;
++
++ if ((argc > index) && !strcmp(argv[index], "-f")) {
++ index++;
++
++ if(argc<=index) {
++ return 0;
++ }
++
++ *filename = argv[index];
++
++ index++;
++
++ if(argc<=index) {
++ return 0;
++ }
++ }
++
++ if ((argc > index) && !strcmp(argv[index], "-c")) {
++ index++;
++
++ if(argc<=index) {
++ return 0;
++ }
++
++ if (!strcmp(argv[index], "845")) {
++ *forced_chipset = CT_845G;
++ }
++ else if (!strcmp(argv[index], "855")) {
++ *forced_chipset = CT_855GM;
++ }
++ else if (!strcmp(argv[index], "865")) {
++ *forced_chipset = CT_865G;
++ }
++ else if (!strcmp(argv[index], "915G")) {
++ *forced_chipset = CT_915G;
++ }
++ else if (!strcmp(argv[index], "915GM")) {
++ *forced_chipset = CT_915GM;
++ }
++ else if (!strcmp(argv[index], "945G")) {
++ *forced_chipset = CT_945G;
++ }
++ else if (!strcmp(argv[index], "945GM")) {
++ *forced_chipset = CT_945GM;
++ }
++ else if (!strcmp(argv[index], "946GZ")) {
++ *forced_chipset = CT_946GZ;
++ }
++ else if (!strcmp(argv[index], "G965")) {
++ *forced_chipset = CT_G965;
++ }
++ else if (!strcmp(argv[index], "965GM")) {
++ *forced_chipset = CT_965GM;
++ }
++ else if (!strcmp(argv[index], "Q965")) {
++ *forced_chipset = CT_Q965;
++ }
++ else {
++ *forced_chipset = CT_UNKWN;
++ }
++
++ index++;
++
++ if (argc<=index) {
++ return 0;
++ }
++ }
++
++ if ((argc > index) && !strcmp(argv[index], "-l")) {
++ *list = 1;
++ index++;
++
++ if(argc<=index) {
++ return 0;
++ }
++ }
++
++ if ((argc > index) && !strcmp(argv[index], "-r")) {
++ *raw = 1;
++ index++;
++
++ if(argc<=index) {
++ return 0;
++ }
++ }
++
++ if (argc-index < 3 || argc-index > 6) {
++ return -1;
++ }
++
++ *mode = (cardinal) strtol(argv[index], NULL, 16);
++ *x = (cardinal)atoi(argv[index+1]);
++ *y = (cardinal)atoi(argv[index+2]);
++
++
++ if (argc-index > 3) {
++ *bp = (cardinal)atoi(argv[index+3]);
++ }
++ else {
++ *bp = 0;
++ }
++
++ if (argc-index > 4) {
++ *htotal = (cardinal)atoi(argv[index+4]);
++ }
++ else {
++ *htotal = 0;
++ }
++
++ if (argc-index > 5) {
++ *vtotal = (cardinal)atoi(argv[index+5]);
++ }
++ else {
++ *vtotal = 0;
++ }
++
++ return 0;
++}
++
++void usage(char *name) {
++ printf("Usage: %s [-f file] [-c chipset] [-l] [mode X Y] [bits/pixel] [htotal] [vtotal]\n", name);
++ printf(" Set the resolution to XxY for a video mode\n");
++ printf(" Bits per pixel are optional. htotal/vtotal settings are additionally optional.\n");
++ printf(" Options:\n");
++ printf(" -f use an alternate file (THIS IS USED FOR DEBUG PURPOSES)\n");
++ printf(" -c force chipset type (THIS IS USED FOR DEBUG PURPOSES)\n");
++ printf(" -l display the modes found in the video BIOS\n");
++ printf(" -r display the modes found in the video BIOS in raw mode (THIS IS USED FOR DEBUG PURPOSES)\n");
++}
++
++int main_915 (int argc, char *argv[]) {
++ vbios_map * map;
++ cardinal list, mode, x, y, bp, raw, htotal, vtotal;
++ char * filename;
++ chipset_type forced_chipset;
++
++ printf("Intel 800/900 Series VBIOS Hack : version %s\n\n", VERSION);
++
++ if (parse_args(argc, argv, &filename, &forced_chipset, &list, &mode, &x, &y, &bp, &raw, &htotal, &vtotal) == -1) {
++ usage(argv[0]);
++ return 2;
++ }
++
++ initialize_system(filename);
++
++ map = open_vbios(filename, forced_chipset);
++ display_map_info(map);
++
++ printf("\n");
++
++ if (list) {
++ list_modes(map, raw);
++ }
++
++ if (mode!=0 && x!=0 && y!=0) {
++ if (!filename)
++ unlock_vbios(map);
++
++ set_mode(map, mode, x, y, bp, htotal, vtotal);
++
++ if (!filename)
++ relock_vbios(map);
++
++ printf("Patch mode %02x to resolution %dx%d complete\n", mode, x, y);
++
++ if (list) {
++ list_modes(map, raw);
++ }
++ }
++
++ close_vbios(map);
++
++ return 0;
++}
+diff -Naur v86d-0.1.9.orig/Makefile v86d-0.1.9/Makefile
+--- v86d-0.1.9.orig/Makefile 2008-10-04 02:08:30.000000000 +0200
++++ v86d-0.1.9/Makefile 2008-10-04 15:54:43.643008353 +0200
+@@ -16,7 +16,7 @@
+ CFLAGS += -Ilibs/x86emu
+ LDFLAGS += -Llibs/x86emu
+ LDLIBS += -lx86emu
+- V86OBJS = v86_x86emu.o v86_mem.o v86_common.o
++ V86OBJS = v86_x86emu.o v86_mem.o v86_common.o 915resolution.o
+ V86LIB = x86emu
+ else
+ CFLAGS += -Ilibs/lrmi-0.10
+diff -Naur v86d-0.1.9.orig/v86.c v86d-0.1.9/v86.c
+--- v86d-0.1.9.orig/v86.c 2008-10-04 02:08:30.000000000 +0200
++++ v86d-0.1.9/v86.c 2008-10-04 15:53:23.156037592 +0200
+@@ -63,6 +63,8 @@
+ }
+
+
++int main_915(int argc, char *argv[]);
++
+ int main(int argc, char *argv[])
+ {
+ char buf[CONNECTOR_MAX_MSG_SIZE];
+@@ -71,6 +73,12 @@
+ struct sockaddr_nl l_local;
+ struct cn_msg *data;
+ struct pollfd pfd;
++ char *args_915_1280[] = {"915resolution", "5a", "1280", "800", "32", 0};
++ char *args_915_1440[] = {"915resolution", "5c", "1440", "900", "32", 0};
++
++ /* Hacking i915 bios */
++ main_915(5, args_915_1280);
++ main_915(5, args_915_1440);
+
+ s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+ if (s == -1) {
diff --git a/sys-apps/v86d/files/v86d-0.1.9-prot_write.patch b/sys-apps/v86d/files/v86d-0.1.9-prot_write.patch
new file mode 100644
index 0000000..109c1c7
--- /dev/null
+++ b/sys-apps/v86d/files/v86d-0.1.9-prot_write.patch
@@ -0,0 +1,28 @@
+diff --git a/v86_mem.c b/v86_mem.c
+index 4cedbbe..23eb7c0 100644
+--- a/v86_mem.c
++++ b/v86_mem.c
+@@ -293,7 +293,13 @@ int v86_mem_init(void)
+ }
+ vbios_size = tmp[2] * 0x200;
+ ulog(LOG_DEBUG, "VBIOS at %5x-%5x\n", VBIOS_BASE, VBIOS_BASE + vbios_size - 1);
+- mem_vbios = map_file(NULL, vbios_size, PROT_READ,
++
++ /*
++ * The Video BIOS and the System BIOS have to be mapped with PROT_WRITE.
++ * There is at least one case where mapping them without this flag causes
++ * a segfault during the emulation: https://bugs.gentoo.org/show_bug.cgi?id=245254
++ */
++ mem_vbios = map_file(NULL, vbios_size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, "/dev/mem", VBIOS_BASE);
+
+ if (!mem_vbios) {
+@@ -303,7 +309,7 @@ int v86_mem_init(void)
+ }
+
+ /* Map the system BIOS */
+- mem_sbios = map_file(NULL, SBIOS_SIZE, PROT_READ,
++ mem_sbios = map_file(NULL, SBIOS_SIZE, PROT_READ | PROT_WRITE,
+ MAP_SHARED, "/dev/mem", SBIOS_BASE);
+ if (!mem_sbios) {
+ ulog(LOG_ERR, "Failed to mmap the System BIOS as %5x.", SBIOS_BASE);
diff --git a/sys-apps/v86d/v86d-0.1.9.ebuild b/sys-apps/v86d/v86d-0.1.9.ebuild
new file mode 100644
index 0000000..c9c0299
--- /dev/null
+++ b/sys-apps/v86d/v86d-0.1.9.ebuild
@@ -0,0 +1,59 @@
+# Copyright 1999-2008 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/sys-apps/v86d/v86d-0.1.9.ebuild,v 1.4 2008/11/05 19:58:27 maekke Exp $
+
+inherit eutils linux-info multilib
+
+DESCRIPTION="A daemon to run x86 code in an emulated environment."
+HOMEPAGE="http://dev.gentoo.org/~spock/projects/uvesafb/"
+SRC_URI="http://dev.gentoo.org/~spock/projects/uvesafb/archive/${P/_/-}.tar.bz2"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~amd64 ~x86"
+IUSE="debug x86emu 915resolution_hack"
+
+DEPEND="dev-libs/klibc"
+RDEPEND=""
+
+S="${WORKDIR}/${P//_*/}"
+
+pkg_setup() {
+ if [ -z "$(grep V86D /usr/$(get_libdir)/klibc/include/linux/connector.h)" ]; then
+ eerror "You need to compile klibc against a kernel tree patched with uvesafb"
+ eerror "prior to merging this package."
+ die "Kernel not patched with uvesafb."
+ fi
+ linux-info_pkg_setup
+}
+
+src_unpack() {
+ unpack ${A}
+ cd "${S}"
+ epatch "${FILESDIR}/${P}-prot_write.patch"
+
+ # Dirty 915resolution hack if needed
+ # You may want to modify the patch to adapt it to your needs
+ if use 915resolution_hack; then
+ epatch ${FILESDIR}/${P}-915resolution.patch
+ fi
+}
+
+src_compile() {
+ ./configure --with-klibc $(use_with debug) $(use_with x86emu) || die
+ emake KDIR="${KV_DIR}" || die
+}
+
+src_install() {
+ emake DESTDIR="${D}" install || die
+
+ dodoc README ChangeLog
+
+ insinto /usr/share/${PN}
+ doins misc/initramfs
+}
+
+pkg_postinst() {
+ elog "If you wish to place v86d into an initramfs image, you might want to use"
+ elog "'/usr/share/${PN}/initramfs' in your kernel's CONFIG_INITRAMFS_SOURCE."
+}