#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 void *low_mem_buffer;
-
struct vbe_info *vbe_get_info(void)
{
struct vbe_info *info;
struct int86regs regs;
- info = low_mem_buffer;
+ info = (struct vbe_info*)low_mem_buffer;
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);
+ if((regs.eax & 0xffff) != 0x4f) {
+ return 0;
+ }
+
return info;
}
struct vbe_mode_info *mi;
struct int86regs regs;
- mi = 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);
- if(regs.eax & 0xff00) {
+ if((regs.eax & 0xffff) != 0x4f) {
return 0;
}
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);
+}