X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fvbe.c;h=cbb940d09a090d4d7599f7a2a2d98976cc7bef7c;hb=0a37e241149d011e038aceb3faac568b405f8ecd;hp=d4847d2a2226dfcd5e368e77d9cb9f66fd0e64a6;hpb=a26564bc44eab32bea085e08fc83b7a1ab15f93f;p=bootcensus diff --git a/src/vbe.c b/src/vbe.c index d4847d2..cbb940d 100644 --- a/src/vbe.c +++ b/src/vbe.c @@ -4,13 +4,12 @@ #include "vbe.h" #include "asmops.h" #include "int86.h" +#include "boot.h" #define SEG_ADDR(s) ((uint32_t)(s) << 4) #define MODE_LFB (1 << 14) -extern unsigned char low_mem_buffer[]; - struct vbe_info *vbe_get_info(void) { struct vbe_info *info; @@ -21,7 +20,7 @@ struct vbe_info *vbe_get_info(void) memcpy(info->sig, "VBE2", 4); memset(®s, 0, sizeof regs); - regs.es = (uint32_t)low_mem_buffer >> 4; + regs.es = (uint32_t)info >> 4; regs.eax = 0x4f00; int86(0x10, ®s); @@ -37,10 +36,10 @@ struct vbe_mode_info *vbe_get_mode_info(int mode) struct vbe_mode_info *mi; struct int86regs regs; - mi = (struct vbe_mode_info*)low_mem_buffer; + mi = (struct vbe_mode_info*)(low_mem_buffer + 512); memset(®s, 0, sizeof regs); - regs.es = (uint32_t)low_mem_buffer >> 4; + regs.es = (uint32_t)mi >> 4; regs.eax = 0x4f01; regs.ecx = mode; int86(0x10, ®s); @@ -83,3 +82,51 @@ void print_mode_info(struct vbe_mode_info *mi) printf("blue bits: %d (mask: %x)\n", (int)mi->bmask_size, maskbits[mi->bmask_size] << mi->bpos); printf("framebuffer address: %x\n", (unsigned int)mi->fb_addr); } + +int vbe_get_edid(struct vbe_edid *edid) +{ + struct int86regs regs; + + memset(®s, 0, sizeof regs); + regs.es = (uint32_t)low_mem_buffer >> 4; + regs.eax = 0x4f15; + regs.ebx = 1; + int86(0x10, ®s); + + if((regs.eax & 0xffff) != 0x4f) { + return -1; + } + memcpy(edid, low_mem_buffer, sizeof *edid); + return 0; +} + +int edid_preferred_resolution(struct vbe_edid *edid, int *xres, int *yres) +{ + if(memcmp(edid->magic, VBE_EDID_MAGIC, 8) != 0) { + return -1; + } + + *xres = (int)edid->timing[0].hactive_lsb | ((int)(edid->timing[0].hact_hblank_msb & 0xf0) << 4); + *yres = (int)edid->timing[0].vactive_lsb | ((int)(edid->timing[0].vact_vblank_msb & 0xf0) << 4); + return 0; +} + +void print_edid(struct vbe_edid *edid) +{ + char vendor[4]; + int xres, yres; + + if(memcmp(edid->magic, VBE_EDID_MAGIC, 8) != 0) { + printf("invalid EDID magic\n"); + return; + } + + vendor[0] = (edid->vendor >> 10) & 0x1f; + vendor[1] = (edid->vendor >> 5) & 0x1f; + vendor[2] = edid->vendor & 0x1f; + vendor[3] = 0; + printf("Manufacturer: %s\n", vendor); + + edid_preferred_resolution(edid, &xres, &yres); + printf("Preferred resolution: %dx%d\n", xres, yres); +}