11 uint32_t paddr = (uint32_t)(ptr); \
12 uint16_t pseg = paddr >> 16; \
13 uint16_t poffs = paddr & 0xffff; \
14 if(pseg == seg && poffs < 512) { \
15 paddr = ((uint32_t)seg << 4) + poffs; \
17 paddr = ((uint32_t)pseg << 4) + poffs; \
19 (ptr) = (void*)paddr; \
22 /* hijack the "VESA" sig field, to pre-cache number of modes */
23 #define NMODES(inf) *(uint16_t*)((inf)->sig)
24 #define NACCMODES(inf) *(uint16_t*)((inf)->sig + 2)
26 int vbe_info(struct vbe_info *info)
32 struct dpmi_regs regs = {0};
34 assert(sizeof *info == 512);
36 if(!(seg = dpmi_alloc(sizeof *info / 16, &sel))) {
39 lowbuf = (void*)((uint32_t)seg << 4);
41 memcpy(lowbuf, "VBE2", 4);
46 dpmi_int(0x10, ®s);
48 if((regs.eax & 0xffff) != 0x4f) {
49 fprintf(stderr, "vbe_get_info (4f00) failed\n");
54 memcpy(info, lowbuf, sizeof *info);
57 FIXPTR(info->oem_name);
59 FIXPTR(info->product);
62 FIXPTR(info->accel_modes);
64 modeptr = info->modes;
65 while(*modeptr != 0xffff) {
66 if(modeptr - info->modes >= 256) {
67 modeptr = info->modes;
72 NMODES(info) = modeptr - info->modes;
74 if(info->caps & VBE_ACCEL) {
75 modeptr = info->accel_modes;
76 while(*modeptr != 0xffff) {
77 if(modeptr - info->accel_modes >= 256) {
78 modeptr = info->accel_modes;
83 NACCMODES(info) = modeptr - info->accel_modes;
88 int vbe_num_modes(struct vbe_info *info)
93 int vbe_mode_info(int mode, struct vbe_mode_info *minf)
98 struct dpmi_regs regs = {0};
100 assert(sizeof *minf == 256);
101 assert(offsetof(struct vbe_mode_info, max_pixel_clock) == 0x3e);
103 if(!(seg = dpmi_alloc(sizeof *minf / 16, &sel))) {
106 lowbuf = (void*)((uint32_t)seg << 4);
111 dpmi_int(0x10, ®s);
113 if((regs.eax & 0xffff) != 0x4f) {
114 fprintf(stderr, "vbe_mode_info (4f01) failed\n");
119 memcpy(minf, lowbuf, sizeof *minf);
124 void vbe_print_info(FILE *fp, struct vbe_info *vinf)
126 fprintf(fp, "vbe version: %u.%u\n", VBE_VER_MAJOR(vinf->ver), VBE_VER_MINOR(vinf->ver));
127 if(VBE_VER_MAJOR(vinf->ver) >= 2) {
128 fprintf(fp, "%s - %s (%s)\n", vinf->vendor, vinf->product, vinf->revstr);
129 if(vinf->caps & VBE_ACCEL) {
130 fprintf(fp, "vbe/af %d.%d\n", VBE_VER_MAJOR(vinf->accel_ver), VBE_VER_MINOR(vinf->accel_ver));
133 fprintf(fp, "oem: %s\n", vinf->oem_name);
135 fprintf(fp, "video memory: %dkb\n", vinf->vmem_blk * 64);
138 fprintf(fp, "caps:");
139 if(vinf->caps & VBE_8BIT_DAC) fprintf(fp, " dac8");
140 if(vinf->caps & VBE_NON_VGA) fprintf(fp, " non-vga");
141 if(vinf->caps & VBE_DAC_BLANK) fprintf(fp, " dac-blank");
142 if(vinf->caps & VBE_ACCEL) fprintf(fp, " af");
143 if(vinf->caps & VBE_MUSTLOCK) fprintf(fp, " af-lock");
144 if(vinf->caps & VBE_HWCURSOR) fprintf(fp, " af-curs");
145 if(vinf->caps & VBE_HWCLIP) fprintf(fp, " af-clip");
146 if(vinf->caps & VBE_TRANSP_BLT) fprintf(fp, " af-tblt");
150 fprintf(fp, "%d video modes available\n", NMODES(vinf));
151 if(vinf->caps & VBE_ACCEL) {
152 fprintf(fp, "%d accelerated (VBE/AF) modes available\n", NACCMODES(vinf));
157 void vbe_print_mode_info(FILE *fp, struct vbe_mode_info *minf)
159 fprintf(fp, "%dx%d %dbpp", minf->xres, minf->yres, minf->bpp);
161 switch(minf->mem_model) {
162 case VBE_TYPE_DIRECT:
163 fprintf(fp, " (rgb");
166 fprintf(fp, " (yuv");
168 fprintf(fp, " %d%d%d)", minf->rsize, minf->gsize, minf->bsize);
170 case VBE_TYPE_PLANAR:
171 fprintf(fp, " (%d planes)", minf->num_planes);
173 case VBE_TYPE_PACKED:
174 fprintf(fp, " (packed)");
177 fprintf(fp, " (%dx%d cells)", minf->xcharsz, minf->ycharsz);
180 fprintf(fp, " (CGA)");
182 case VBE_TYPE_UNCHAIN:
183 fprintf(fp, " (unchained-%d)", minf->num_planes);
186 fprintf(fp, " %dpg", minf->num_img_pages);
188 if(minf->attr & VBE_ATTR_LFB) {
189 fprintf(fp, " lfb@%lx", (unsigned long)minf->fb_addr);
193 if(minf->attr & VBE_ATTR_AVAIL) fprintf(fp, " avail");
194 if(minf->attr & VBE_ATTR_OPTINFO) fprintf(fp, " opt");
195 if(minf->attr & VBE_ATTR_TTY) fprintf(fp, " tty");
196 if(minf->attr & VBE_ATTR_COLOR) fprintf(fp, " color");
197 if(minf->attr & VBE_ATTR_GFX) fprintf(fp, " gfx");
198 if(minf->attr & VBE_ATTR_NOTVGA) fprintf(fp, " non-vga");
199 if(minf->attr & VBE_ATTR_BANKED) fprintf(fp, " banked");
200 if(minf->attr & VBE_ATTR_LFB) fprintf(fp, " lfb");
201 if(minf->attr & VBE_ATTR_2XSCAN) fprintf(fp, " dblscan");
202 if(minf->attr & VBE_ATTR_ILACE) fprintf(fp, " ilace");
203 if(minf->attr & VBE_ATTR_TRIPLEBUF) fprintf(fp, " trplbuf");
204 if(minf->attr & VBE_ATTR_STEREO) fprintf(fp, " stereo");
205 if(minf->attr & VBE_ATTR_STEREO_2FB) fprintf(fp, " stdual");