#include #include #include // ---- VESA data structures typedef struct { char vbe_signature[4]; // == "VESA" uint16_t vbe_version; v86_farptr_t oem_string_ptr; uint8_t capabilities[4]; v86_farptr_t video_mode_ptr; uint16_t total_memory; // as # of 64KB blocks } __attribute__((packed)) vbe_info_block_t; typedef struct { uint16_t attributes; uint8_t winA, winB; uint16_t granularity; uint16_t winsize; uint16_t segmentA, segmentB; v86_farptr_t real_fct_ptr; uint16_t pitch; // bytes per scanline uint16_t Xres, Yres; uint8_t Wchar, Ychar, planes, bpp, banks; uint8_t memory_model, bank_size, image_pages; uint8_t reserved0; uint8_t red_mask, red_position; uint8_t green_mask, green_position; uint8_t blue_mask, blue_position; uint8_t rsv_mask, rsv_position; uint8_t directcolor_attributes; uint32_t physbase; // the offset of the framebuffer in physical memory! uint32_t reserved1; uint16_t reserved2; } __attribute__((packed)) vbe_mode_info_block_t; // ---- VESA code void vesa_detect(fs_t *iofs) { if (!v86_begin_session()) return; vbe_info_block_t *i = (vbe_info_block_t*)v86_alloc(512); memset(i, 0, 512); strncpy(i->vbe_signature, "VBE2", 4); v86_regs.ax = 0x4F00; v86_regs.es = V86_SEG_OF_LIN(i); v86_regs.di = V86_OFF_OF_LIN(i); if (v86_bios_int(0x10)) { if (v86_regs.ax == 0x004F) { dbg_printf("Detected VESA (sig %s, ver 0x%x, oem %s) with %d kb ram.\n", i->vbe_signature, i->vbe_version, v86_lin_of_fp(i->oem_string_ptr), 64 * i->total_memory); vbe_mode_info_block_t *mi = (vbe_mode_info_block_t*)v86_alloc(256); uint16_t *modes = (uint16_t*)v86_lin_of_fp(i->video_mode_ptr); for (int n = 0; modes[n] != 0xFFFF; n++) { v86_regs.ax = 0x4F01; v86_regs.cx = modes[n]; v86_regs.es = V86_SEG_OF_LIN(mi); v86_regs.di = V86_OFF_OF_LIN(mi); if (v86_bios_int(0x10) && v86_regs.ax == 0x004F) { dbg_printf("Mode 0x%x : %dx%dx%d at 0x%p\n", modes[n], mi->Xres, mi->Yres, mi->bpp, mi->physbase); } else { dbg_printf("Mode 0x%x : could not get info\n", modes[n]); } } } else { dbg_printf("Error in BIOS int 0x10/0x4F00.\n"); } } else { dbg_printf("Could not call BIOS int 0x10.\n"); } v86_end_session(); } /* vim: set ts=4 sw=4 tw=0 noet :*/