diff options
-rw-r--r-- | tools/ddcprobe/Makefile | 41 | ||||
-rw-r--r-- | tools/ddcprobe/ddcxinfos.c | 59 | ||||
-rw-r--r-- | tools/ddcprobe/vbe.c | 600 | ||||
-rw-r--r-- | tools/ddcprobe/vbe.h | 150 |
4 files changed, 235 insertions, 615 deletions
diff --git a/tools/ddcprobe/Makefile b/tools/ddcprobe/Makefile index bcbf1464d..0b96f3c44 100644 --- a/tools/ddcprobe/Makefile +++ b/tools/ddcprobe/Makefile @@ -1,29 +1,26 @@ -CFLAGS=-Wall -O # -g -DDEBUG -LDFLAGS = -lm -TARGETS=ddcxinfos +CC = gcc +CFLAGS = -O -Wall # -g -DDEBUG +INCS = -I. +LDFLAGS = -lm -L. -lint10 -lx86emu +OBJS = ddcxinfos.o vesamode.o vbe.o +LIBS = libint10.a libx86emu.a +TARGETS = ddcxinfos -ARCH := $(patsubst i%86,i386,$(shell uname -m)) -ARCH := $(patsubst sparc%,sparc,$(ARCH)) +all: $(TARGETS) -ifeq (i386,$(ARCH)) +ddcxinfos: $(OBJS) $(LIBS) + $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDFLAGS) -ddcxinfos: lrmi.o vesamode.o vbe.o ddcxinfos.o +libx86emu.a: + $(MAKE) -C x86emu -libvbe.a: lrmi.o vesamode.o vbe.o - $(AR) cru $@ $^ +libint10.a: libx86emu.a + $(MAKE) -C int10 -#install: $(DESTDIR)/usr/include/vbe.h $(DESTDIR)/usr/lib/libvbe.a - -$(DESTDIR)/usr/include/vbe.h: - install -m 644 vbe.h $(DESTDIR)/usr/include/vbe.h - -$(DESTDIR)/usr/lib/libvbe.a: - install -m 644 libvbe.a $(DESTDIR)/usr/lib/libvbe.a - -else -ddcxinfos: not_handled.c - gcc -o $@ $< -endif +%.o: %.c + $(CC) $(CFLAGS) $(INCS) -c $< -o $@ clean: - $(RM) $(TARGETS) *.o core + $(MAKE) -C int10 clean + $(MAKE) -C x86emu clean + $(RM) $(TARGETS) $(LIBS) *.o core diff --git a/tools/ddcprobe/ddcxinfos.c b/tools/ddcprobe/ddcxinfos.c index 22ed653b8..93352d846 100644 --- a/tools/ddcprobe/ddcxinfos.c +++ b/tools/ddcprobe/ddcxinfos.c @@ -2,30 +2,54 @@ #include <stdlib.h> #include <string.h> #include <math.h> +#include <sys/mman.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <stdarg.h> #include "vbe.h" #include "vesamode.h" +#include "int10/vbios.h" #ident "$Id$" #define SQR(x) ((x) * (x)) -int main(int argc, char **argv) +void log_err(char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); +} + +int main(void) { int i, j; - u_int16_t *mode_list; unsigned char hmin, hmax, vmin, vmax; - struct vbe_info *vbe_info; - struct vbe_edid1_info *edid; + struct vbe_info vbe_info_static; + struct vbe_info *vbe_info = &vbe_info_static; + struct vbe_edid1_info edid_static; + struct vbe_edid1_info *edid = &edid_static; struct vbe_modeline *modelines; - + int pci_config_type = 0; - if ((vbe_info = vbe_get_vbe_info()) == NULL) return 1; + /* Determine PCI configuration type */ + pci_config_type = 1; - printf("%dKB of video ram\n", vbe_info->memory_size * 64); + /* Initialize Int10 */ + if (InitInt10(pci_config_type)) return 1; - /* List supported standard modes. */ - for (mode_list = vbe_info->mode_list.list; *mode_list != 0xffff; mode_list++) + /* Get VBE information */ + if (vbe_get_vbe_info(vbe_info) == 0) { + FreeInt10(); + return 1; + } + printf("%dKB of video ram\n", vbe_info->memory_size / 1024); + + /* List supported standard modes */ + for (j = 0; j < vbe_info->modes; j++) for (i = 0; known_vesa_modes[i].x; i++) - if (known_vesa_modes[i].number == *mode_list) + if (known_vesa_modes[i].number == vbe_info->mode_list[j]) printf("%d %d %d\n", known_vesa_modes[i].colors, known_vesa_modes[i].x, @@ -33,7 +57,14 @@ int main(int argc, char **argv) ); printf("\n"); - if ((edid = vbe_get_edid_info()) == NULL) return 0; + /* Get EDID information */ + if (vbe_get_edid_info(edid) == 0) { + FreeInt10(); + return 0; + } + FreeInt10(); + + if (edid->manufacturer_name.p == 0 || edid->product_code == 0) return 0; if (edid->version == 255 && edid->revision == 255) return 0; vbe_get_edid_ranges(edid, &hmin, &hmax, &vmin, &vmax); @@ -48,9 +79,9 @@ int main(int argc, char **argv) char manufacturer[4]; double size = sqrt(SQR(edid->max_size_horizontal) + SQR(edid->max_size_vertical)) / 2.54; - manufacturer[0] = edid->manufacturer_name.char1 + 'A' - 1; - manufacturer[1] = edid->manufacturer_name.char2 + 'A' - 1; - manufacturer[2] = edid->manufacturer_name.char3 + 'A' - 1; + manufacturer[0] = edid->manufacturer_name.u.char1 + 'A' - 1; + manufacturer[1] = edid->manufacturer_name.u.char2 + 'A' - 1; + manufacturer[2] = edid->manufacturer_name.u.char3 + 'A' - 1; manufacturer[3] = '\0'; printf(size ? "%3.2f inches monitor (truly %3.2f') EISA ID=%s%04x\n" : "\n", size * 1.08, size, manufacturer, edid->product_code); } diff --git a/tools/ddcprobe/vbe.c b/tools/ddcprobe/vbe.c index a67e56d0b..7b061f213 100644 --- a/tools/ddcprobe/vbe.c +++ b/tools/ddcprobe/vbe.c @@ -8,330 +8,168 @@ #include <assert.h> #include <limits.h> #include <ctype.h> -#include "lrmi.h" +#include <fcntl.h> +#include <unistd.h> #include "vesamode.h" #include "vbe.h" -#ident "$Id$" - -/* Return information about a particular video mode. */ -struct vbe_mode_info *vbe_get_mode_info(u_int16_t mode) -{ - struct LRMI_regs regs; - char *mem; - struct vbe_mode_info *ret = NULL; - - /* Initialize LRMI. */ - if(LRMI_init() == 0) { - return NULL; - } - - /* Allocate a chunk of memory. */ - mem = LRMI_alloc_real(sizeof(struct vbe_mode_info)); - if(mem == NULL) { - return NULL; - } - memset(mem, 0, sizeof(struct vbe_mode_info)); - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f01; - regs.ecx = mode; - regs.es = ((u_int32_t)mem) >> 4; - regs.edi = ((u_int32_t)mem) & 0x0f; - - /* Do it. */ - iopl(3); - ioperm(0, 0x400, 1); - - if(LRMI_int(0x10, ®s) == 0) { - LRMI_free_real(mem); - return NULL; - } - - /* Check for successful return. */ - if((regs.eax & 0xffff) != 0x004f) { - LRMI_free_real(mem); - return NULL; - } - - /* Get memory for return. */ - ret = malloc(sizeof(struct vbe_mode_info)); - if(ret == NULL) { - LRMI_free_real(mem); - return NULL; - } - - /* Copy the buffer for return. */ - memcpy(ret, mem, sizeof(struct vbe_mode_info)); +#include "int10/vbios.h" + +#define DEBUG 0 +#if DEBUG +#define bug printf +#define D(X) X +#else +#define D(X) +#endif - /* Clean up and return. */ - LRMI_free_real(mem); - return ret; -} +#ifdef __i386__ +#define cpuemu 1 +#else +#define cpuemu 0 +#endif -/* Get VBE info. */ -struct vbe_info *vbe_get_vbe_info() +/* + * Create a 'canonical' version, i.e. no spaces at start and end. + * + * Note: removes chars >= 0x80 as well (due to (char *))! This + * is currently considered a feature. + */ +static char *canon_str(char *s, int len) { - struct LRMI_regs regs; - unsigned char *mem; - struct vbe_info *ret = NULL; - int i; - - /* Initialize LRMI. */ - if(LRMI_init() == 0) { - return NULL; - } - - /* Allocate a chunk of memory. */ - mem = LRMI_alloc_real(sizeof(struct vbe_mode_info)); - if(mem == NULL) { - return NULL; - } - memset(mem, 0, sizeof(struct vbe_mode_info)); - - /* Set up registers for the interrupt call. */ - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f00; - regs.es = ((u_int32_t)mem) >> 4; - regs.edi = ((u_int32_t)mem) & 0x0f; - memcpy(mem, "VBE2", 4); - - /* Do it. */ - iopl(3); - ioperm(0, 0x400, 1); - - if(LRMI_int(0x10, ®s) == 0) { - LRMI_free_real(mem); - return NULL; - } - - /* Check for successful return code. */ - if((regs.eax & 0xffff) != 0x004f) { - LRMI_free_real(mem); - return NULL; - } - - /* Get memory to return the information. */ - ret = malloc(sizeof(struct vbe_info)); - if(ret == NULL) { - LRMI_free_real(mem); - return NULL; - } - memcpy(ret, mem, sizeof(struct vbe_info)); - - /* Set up pointers to usable memory. */ - ret->mode_list.list = (u_int16_t*) ((ret->mode_list.addr.seg << 4) + - (ret->mode_list.addr.ofs)); - ret->oem_name.string = (char*) ((ret->oem_name.addr.seg << 4) + - (ret->oem_name.addr.ofs)); - - /* Snip, snip. */ - mem = strdup(ret->oem_name.string); /* leak */ - while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { - mem[i - 1] = '\0'; - } - ret->oem_name.string = mem; - - /* Set up pointers for VESA 3.0+ strings. */ - if(ret->version[1] >= 3) { - - /* Vendor name. */ - ret->vendor_name.string = (char*) - ((ret->vendor_name.addr.seg << 4) - + (ret->vendor_name.addr.ofs)); - - mem = strdup(ret->vendor_name.string); /* leak */ - while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { - mem[i - 1] = '\0'; - } - ret->vendor_name.string = mem; - - /* Product name. */ - ret->product_name.string = (char*) - ((ret->product_name.addr.seg << 4) - + (ret->product_name.addr.ofs)); - - mem = strdup(ret->product_name.string); /* leak */ - while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { - mem[i - 1] = '\0'; - } - ret->product_name.string = mem; - - /* Product revision. */ - ret->product_revision.string = (char*) - ((ret->product_revision.addr.seg << 4) - + (ret->product_revision.addr.ofs)); - - mem = strdup(ret->product_revision.string); /* leak */ - while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { - mem[i - 1] = '\0'; - } - ret->product_revision.string = mem; - } - - /* Cleanup. */ - LRMI_free_real(mem); - return ret; + char *m2, *m1, *m0 = malloc(len + 1); + int i; + + for(m1 = m0, i = 0; i < len; i++) { + if(m1 == m0 && s[i] <= ' ') continue; + *m1++ = s[i]; + } + *m1 = 0; + while(m1 > m0 && m1[-1] <= ' ') { + *--m1 = 0; + } + + m2 = strdup(m0); + free(m0); + + return m2; } -/* Check if EDID queries are suorted. */ -int vbe_get_edid_supported() +static unsigned segofs2addr(unsigned char *segofs) { - struct LRMI_regs regs; - int ret = 0; - - /* Initialize LRMI. */ - if(LRMI_init() == 0) { - return 0; - } - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f15; - regs.ebx = 0x0000; - regs.es = 0x3000; - regs.edi = 0x3000; - - /* Do it. */ - iopl(3); - ioperm(0, 0x400, 1); - - if(LRMI_int(0x10, ®s) == 0) { - return 0; - } - - /* Check for successful return. */ - if((regs.eax & 0xff) == 0x4f) { - /* Supported. */ - ret = 1; - } else { - /* Not supported. */ - ret = 0; - } - - /* Clean up and return. */ - return ret; + return segofs[0] + (segofs[1] << 8) + (segofs[2] << 4)+ (segofs[3] << 12); } -/* Get EDID info. */ -struct vbe_edid1_info *vbe_get_edid_info() -{ - struct LRMI_regs regs; - unsigned char *mem; - struct vbe_edid1_info *ret = NULL; - u_int16_t man; - - /* Initialize LRMI. */ - if(LRMI_init() == 0) { - return NULL; - } - - /* Allocate a chunk of memory. */ - mem = LRMI_alloc_real(sizeof(struct vbe_edid1_info)); - if(mem == NULL) { - return NULL; - } - memset(mem, 0, sizeof(struct vbe_edid1_info)); - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f15; - regs.ebx = 0x0001; - regs.es = ((u_int32_t)mem) >> 4; - regs.edi = ((u_int32_t)mem) & 0x0f; - /* Do it. */ - iopl(3); - ioperm(0, 0x400, 1); - - if(LRMI_int(0x10, ®s) == 0) { - LRMI_free_real(mem); - return NULL; - } - -#if 0 - /* Check for successful return. */ - if((regs.eax & 0xffff) != 0x004f) { - LRMI_free_real(mem); - return NULL; - } -#elseif - /* Check for successful return. */ - if((regs.eax & 0xff) != 0x4f) { - LRMI_free_real(mem); - return NULL; - } -#endif - - /* Get memory for return. */ - ret = malloc(sizeof(struct vbe_edid1_info)); - if(ret == NULL) { - LRMI_free_real(mem); - return NULL; - } - - /* Copy the buffer for return. */ - memcpy(ret, mem, sizeof(struct vbe_edid1_info)); - - memcpy(&man, &ret->manufacturer_name, 2); - man = ntohs(man); - memcpy(&ret->manufacturer_name, &man, 2); - - LRMI_free_real(mem); - return ret; -} - -/* Figure out what the current video mode is. */ -int32_t vbe_get_mode() +static unsigned get_data(unsigned char *buf, unsigned buf_size, unsigned addr) { - struct LRMI_regs regs; - int32_t ret = -1; - - /* Initialize LRMI. */ - if(LRMI_init() == 0) { - return -1; - } - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f03; + unsigned bufferaddr = 0x7e00; + unsigned len; + + *buf = 0; + len = 0; + + if(addr >= bufferaddr && addr < bufferaddr + 0x200) { + len = bufferaddr + 0x200 - addr; + if(len >= buf_size) len = buf_size - 1; + memcpy(buf, addr + (char *) 0, len); + } + else if(addr >= 0x0c0000 && addr < 0x100000) { + len = 0x100000 - addr; + if(len >= buf_size) len = buf_size - 1; + memcpy(buf, addr + (char *) 0, len); + } + + buf[len] = 0; + + return len; +} - /* Do it. */ - iopl(3); - ioperm(0, 0x400, 1); +#define GET_WORD(ADDR, OFS) ((ADDR)[OFS] + ((ADDR)[(OFS) + 1] << 8)) - if(LRMI_int(0x10, ®s) == 0) { - return -1; - } - - /* Save the returned value. */ - if((regs.eax & 0xffff) == 0x004f) { - ret = regs.ebx & 0xffff; - } else { - ret = -1; - } - - /* Clean up and return. */ - return ret; +int vbe_get_vbe_info(struct vbe_info *vbe) +{ + int i, l, u; + unsigned char v[0x200]; + unsigned char tmp[1024]; + int ax, bx, cx; + + if (vbe == NULL) + return 0; + + /* Setup registers for the interrupt call */ + ax = 0x4f00; + bx = 0; + cx = 0; + memset(v, 0, sizeof(v)); + strcpy(v, "VBE2"); + + /* Get VBE block */ + i = CallInt10(&ax, &bx, &cx, v, sizeof(v), cpuemu) & 0xffff; + if (i != 0x4f) { + D(bug("VBE: Error (0x4f00): 0x%04x\n", i)); + return 0; + } + + /* Parse VBE block */ + vbe->version = GET_WORD(v, 0x04); + vbe->oem_version = GET_WORD(v, 0x14); + vbe->memory_size = GET_WORD(v, 0x12) << 16; + D(bug("version = %u.%u, oem version = %u.%u\n", + vbe->version >> 8, vbe->version & 0xff, vbe->oem_version >> 8, vbe->oem_version & 0xff)); + D(bug("memory = %uk\n", vbe->memory_size >> 10)); + + l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x06)); + vbe->oem_name = canon_str(tmp, l); + D(bug("oem name [0x%05x] = \"%s\"\n", u, vbe->oem_name)); + + l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x16)); + vbe->vendor_name = canon_str(tmp, l); + D(bug("vendor name [0x%05x] = \"%s\"\n", u, vbe->vendor_name)); + + l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x1a)); + vbe->product_name = canon_str(tmp, l); + D(bug("product name [0x%05x] = \"%s\"\n", u, vbe->product_name)); + + l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x1e)); + vbe->product_revision = canon_str(tmp, l); + D(bug("product revision [0x%05x] = \"%s\"\n", u, vbe->product_revision)); + + l = get_data(tmp, sizeof tmp, u = segofs2addr(v + 0x0e)) >> 1; + for(i = vbe->modes = 0; i < l && i < sizeof vbe->mode_list / sizeof *vbe->mode_list; i++) { + u = GET_WORD(tmp, 2 * i); + if(u != 0xffff) + vbe->mode_list[vbe->modes++] = u; + else + break; + } + D(bug("%u video modes\n", vbe->modes)); + + return 1; } -/* Set the video mode. */ -void vbe_set_mode(u_int16_t mode) +/* Get EDID info. */ +int vbe_get_edid_info(struct vbe_edid1_info *edid) { - struct LRMI_regs regs; - - /* Initialize LRMI. */ - if(LRMI_init() == 0) { - return; - } - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f02; - regs.ebx = mode; - - /* Do it. */ - iopl(3); - ioperm(0, 0x400, 1); - LRMI_int(0x10, ®s); - - /* Return. */ - return; + int i; + int ax, bx, cx; + + if (edid == NULL) + return 0; + + /* Setup registers for the interrupt call */ + ax = 0x4f15; + bx = 1; + cx = 0; + + /* Get EDID block */ + i = CallInt10(&ax, &bx, &cx, (unsigned char *)edid, sizeof *edid, cpuemu) & 0xffff; + if (i != 0x4f) { + D(bug("EDID: Error (0x4f15): 0x%04x\n", i)); + return 0; + } + + edid->manufacturer_name.p = ntohs(edid->manufacturer_name.p); + return 1; } /* Just read ranges from the EDID. */ @@ -364,16 +202,14 @@ static int compare_vbe_modelines(const void *m1, const void *m2) return 0; } -struct vbe_modeline *vbe_get_edid_modelines() +struct vbe_modeline *vbe_get_edid_modelines(struct vbe_edid1_info *edid) { - struct vbe_edid1_info *edid; struct vbe_modeline *ret; char buf[LINE_MAX]; int modeline_count = 0, i, j; - if((edid = vbe_get_edid_info()) == NULL) { - return NULL; - } + if (edid == NULL) + return NULL; memcpy(buf, &edid->established_timings, sizeof(edid->established_timings)); @@ -567,143 +403,3 @@ struct vbe_modeline *vbe_get_edid_modelines() return ret; } - -const void *vbe_save_svga_state() -{ - struct LRMI_regs regs; - unsigned char *mem; - u_int16_t block_size; - void *data; - - /* Initialize LRMI. */ - if(LRMI_init() == 0) { - return NULL; - } - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f04; - regs.ecx = 0xffff; - regs.edx = 0; - - iopl(3); - ioperm(0, 0x400, 1); - - if(LRMI_int(0x10, ®s) == 0) { - return NULL; - } - - if((regs.eax & 0xff) != 0x4f) { - fprintf(stderr, "Get SuperVGA Video State not supported.\n"); - return NULL; - } - - if((regs.eax & 0xffff) != 0x004f) { - fprintf(stderr, "Get SuperVGA Video State Info failed.\n"); - return NULL; - } - - block_size = 64 * (regs.ebx & 0xffff); - - /* Allocate a chunk of memory. */ - mem = LRMI_alloc_real(block_size); - if(mem == NULL) { - return NULL; - } - memset(mem, 0, sizeof(block_size)); - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f04; - regs.ecx = 0x000f; - regs.edx = 0x0001; - regs.es = ((u_int32_t)mem) >> 4; - regs.ebx = ((u_int32_t)mem) & 0x0f; - memset(mem, 0, block_size); - iopl(3); - ioperm(0, 0x400, 1); - - if(LRMI_int(0x10, ®s) == 0) { - LRMI_free_real(mem); - return NULL; - } - - if((regs.eax & 0xffff) != 0x004f) { - fprintf(stderr, "Get SuperVGA Video State Save failed.\n"); - return NULL; - } - - data = malloc(block_size); - if(data == NULL) { - LRMI_free_real(mem); - return NULL; - } - - /* Clean up and return. */ - memcpy(data, mem, block_size); - LRMI_free_real(mem); - return data; -} - -void vbe_restore_svga_state(const void *state) -{ - struct LRMI_regs regs; - unsigned char *mem; - u_int16_t block_size; - - /* Initialize LRMI. */ - if(LRMI_init() == 0) { - return; - } - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f04; - regs.ecx = 0x000f; - regs.edx = 0; - - /* Find out how much memory we need. */ - iopl(3); - ioperm(0, 0x400, 1); - - if(LRMI_int(0x10, ®s) == 0) { - return; - } - - if((regs.eax & 0xff) != 0x4f) { - fprintf(stderr, "Get SuperVGA Video State not supported.\n"); - return; - } - - if((regs.eax & 0xffff) != 0x004f) { - fprintf(stderr, "Get SuperVGA Video State Info failed.\n"); - return; - } - - block_size = 64 * (regs.ebx & 0xffff); - - /* Allocate a chunk of memory. */ - mem = LRMI_alloc_real(block_size); - if(mem == NULL) { - return; - } - memset(mem, 0, sizeof(block_size)); - - memset(®s, 0, sizeof(regs)); - regs.eax = 0x4f04; - regs.ecx = 0x000f; - regs.edx = 0x0002; - regs.es = 0x2000; - regs.ebx = 0x0000; - memcpy(mem, state, block_size); - - iopl(3); - ioperm(0, 0x400, 1); - - if(LRMI_int(0x10, ®s) == 0) { - LRMI_free_real(mem); - return; - } - - if((regs.eax & 0xffff) != 0x004f) { - fprintf(stderr, "Get SuperVGA Video State Restore failed.\n"); - return; - } -} diff --git a/tools/ddcprobe/vbe.h b/tools/ddcprobe/vbe.h index 338d3bd88..4dd7e70c5 100644 --- a/tools/ddcprobe/vbe.h +++ b/tools/ddcprobe/vbe.h @@ -3,113 +3,20 @@ #ident "$Id$" #include <sys/types.h> +struct vbe_mode_info; + /* Record returned by int 0x10, function 0x4f, subfunction 0x00. */ struct vbe_info { - unsigned char signature[4]; - unsigned char version[2]; - union { - struct { - u_int16_t ofs; - u_int16_t seg; - } addr; - const char *string; - } oem_name; - u_int32_t capabilities; - union { - struct { - u_int16_t ofs; - u_int16_t seg; - } addr; - u_int16_t *list; - } mode_list; - u_int16_t memory_size; - /* VESA 3.0+ */ - u_int16_t vbe_revision; - union { - struct { - u_int16_t ofs; - u_int16_t seg; - } addr; - const char *string; - } vendor_name; - union { - struct { - u_int16_t ofs; - u_int16_t seg; - } addr; - const char *string; - } product_name; - union { - struct { - u_int16_t ofs; - u_int16_t seg; - } addr; - const char *string; - } product_revision; - char reserved1[222]; - char reserved2[256]; -} __attribute__ ((packed)); - -/* Stuff returned by int 0x10, function 0x4f, subfunction 0x01. */ -struct vbe_mode_info { - /* required for all VESA versions */ - struct { - /* VBE 1.0+ */ - u_int16_t supported: 1; - u_int16_t optional_info_available: 1; - u_int16_t bios_output_supported: 1; - u_int16_t color: 1; - u_int16_t graphics: 1; - /* VBE 2.0+ */ - u_int16_t not_vga_compatible: 1; - u_int16_t not_bank_switched: 1; - u_int16_t lfb: 1; - /* VBE 1.0+ */ - u_int16_t unknown: 1; - u_int16_t must_enable_directaccess_in_10: 1; - } mode_attributes; - struct { - unsigned char exists: 1; - unsigned char readable: 1; - unsigned char writeable: 1; - unsigned char reserved: 5; - } windowa_attributes, windowb_attributes; - u_int16_t window_granularity; - u_int16_t window_size; - u_int16_t windowa_start_segment, windowb_start_segment; - u_int16_t window_positioning_seg, window_positioning_ofs; - u_int16_t bytes_per_scanline; - /* optional for VESA 1.0/1.1, required for OEM modes */ - u_int16_t w, h; - unsigned char cell_width, cell_height; - unsigned char memory_planes; - unsigned char bpp; - unsigned char banks; - enum { - memory_model_text = 0, - memory_model_cga = 1, - memory_model_hgc = 2, - memory_model_ega16 = 3, - memory_model_packed_pixel = 4, - memory_model_sequ256 = 5, - memory_model_direct_color = 6, - memory_model_yuv = 7, - } memory_model: 8; - unsigned char bank_size; - unsigned char image_pages; - unsigned char reserved1; - /* required for VESA 1.2+ */ - unsigned char red_mask, red_field; - unsigned char green_mask, green_field; - unsigned char blue_mask, blue_field; - unsigned char reserved_mask, reserved_field; - unsigned char direct_color_mode_info; - /* VESA 2.0+ */ - u_int32_t linear_buffer_address; - u_int32_t offscreen_memory_address; - u_int16_t offscreen_memory_size; - unsigned char reserved2[206]; -} __attribute__ ((packed)); + unsigned int version; + unsigned int oem_version; + unsigned int memory_size; + char *oem_name; + char *vendor_name; + char *product_name; + char *product_revision; + unsigned int modes; + unsigned int mode_list[0x100]; +}; /* Modeline information used by XFree86. */ struct vbe_modeline { @@ -211,12 +118,15 @@ struct vbe_edid_monitor_descriptor { struct vbe_edid1_info { unsigned char header[8]; - struct { - u_int16_t char3: 5; - u_int16_t char2: 5; - u_int16_t char1: 5; - u_int16_t zero: 1; - } manufacturer_name __attribute__ ((packed)); + union { + u_int16_t p; + struct { + u_int16_t char3: 5; + u_int16_t char2: 5; + u_int16_t char1: 5; + u_int16_t zero: 1; + } u; + } manufacturer_name; u_int16_t product_code; u_int32_t serial_number; unsigned char week; @@ -282,24 +192,10 @@ struct vbe_edid1_info { #define VBE_LINEAR_FRAMEBUFFER 0x4000 /* Get VESA information. */ -struct vbe_info *vbe_get_vbe_info(); - -/* Get information about a particular video mode, bitwise or with - VBE_LINEAR_FRAMEBUFFER to check if LFB version is supported. */ -struct vbe_mode_info *vbe_get_mode_info(u_int16_t mode); +int vbe_get_vbe_info(struct vbe_info *vbe); /* Check if EDID reads are supported, and do them. */ -int vbe_get_edid_supported(); -struct vbe_edid1_info *vbe_get_edid_info(); - -/* Get the current video mode, -1 on error. */ -int32_t vbe_get_mode(); -/* Set a new video mode, bitwise or with VBE_LINEAR_FRAMEBUFFER. */ -void vbe_set_mode(u_int16_t mode); - -/* Save/restore the SVGA state. Call free() on the state record when done. */ -const void *vbe_save_svga_state(); -void vbe_restore_svga_state(const void *state); +int vbe_get_edid_info(struct vbe_edid1_info *edid); /* Get the ranges of values suitable for the attached monitor. */ void vbe_get_edid_ranges(struct vbe_edid1_info *edid, |