9 #define farptr_to_linear(rmaddr) \
10 ((((intptr_t)(rmaddr) >> 12) & 0xffff0) + ((intptr_t)(rmaddr) & 0xffff))
12 static int init(void);
13 static void cleanup(void);
14 static int setmode(int mode);
15 static int getmode(void);
16 static const char *memsize_str(long sz);
17 static int get_mode_info(int mode, struct vbe_mode_info *mi);
18 static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info *vbemi);
20 static struct vid_driver drv = {"vbe", 2};
21 static struct vid_drvops drvops = {init, cleanup, setmode, getmode};
22 static struct vid_modeinfo *modes;
24 static unsigned int vbe_ver;
27 void vid_register_vbe(void)
31 vid_drvlist[vid_numdrv++] = &drv;
37 struct dpmi_regs regs = {0};
39 struct vbe_mode_info vbemi;
40 unsigned short bufseg;
41 uint16_t *vbe_modelist, *modelist;
43 struct vid_modeinfo modeinf;
46 bufseg = (intptr_t)vbe >> 4;
48 /* call VBE function 00 (get controller information) */
49 memcpy(vbe->sig, "VBE2", 4); /* denote we want VBE 2.0 info */
52 dpmi_rmint(0x10, ®s);
53 if(regs.eax != 0x4f || memcmp(vbe->sig, "VESA", 4) != 0) {
54 fprintf(stderr, "failed to get VBE controller information\n");
60 printf("Found VBE %d.%d\n", vbe_ver >> 8, vbe_ver & 0xff);
61 printf("OEM: %s\n", (char*)farptr_to_linear(vbe->oem_name));
62 if(vbe_ver >= 0x0200) {
63 printf("%s - %s (%s)\n", (char*)farptr_to_linear(vbe->vendor),
64 (char*)farptr_to_linear(vbe->product),
65 (char*)farptr_to_linear(vbe->revstr));
67 printf("Video RAM: %s\n", memsize_str((long)vbe->vmem_blk * 65536));
69 vbe_modelist = (uint16_t*)farptr_to_linear(vbe->modelist_addr);
71 for(i=0; i<1024; i++) {
72 if(vbe_modelist[i] == 0xffff) break;
76 if(!(modelist = malloc(count * sizeof *modelist))) {
77 fprintf(stderr, "failed to allocate mode list\n");
80 for(i=0; i<count; i++) {
81 modelist[i] = vbe_modelist[i];
84 printf("found %d modes\n", count);
87 for(i=0; i<count; i++) {
88 if(get_mode_info(modelist[i], &vbemi) == -1) {
91 conv_vbeinfo(modelist[i], modes + num_modes++, &vbemi);
97 static void cleanup(void)
101 static int setmode(int mode)
106 static int getmode(void)
111 static const char *memsize_str(long sz)
113 static const char *suffix[] = {"bytes", "kb", "mb", "gb", 0};
117 while(sz > 1024 && suffix[cnt + 1]) {
122 sprintf(buf, "%ld %s", sz, suffix[cnt]);
126 static int get_mode_info(int mode, struct vbe_mode_info *mi)
128 struct dpmi_regs regs = {0};
129 struct vbe_mode_info *miptr;
132 miptr = dpmi_lowbuf();
133 bufseg = (intptr_t)miptr >> 4;
138 dpmi_rmint(0x10, ®s);
139 if(regs.eax != 0x4f) {
147 static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info *vbemi)
149 static const struct { int width, height, bpp; } stdmode[] = {
150 {640, 400, 8}, /* 100h */
151 {640, 480, 8}, /* 101h */
152 {800, 600, 4}, /* 102h */
153 {800, 600, 8}, /* 103h */
154 {1024, 768, 4}, /* 104h */
155 {1024, 768, 8}, /* 105h */
156 {1280, 1024, 4}, /* 106h */
157 {1280, 1024, 8} /* 107h */
159 if(vbe_ver >= 0x0102) {
160 mi->width = vbemi->xres;
161 mi->height = vbemi->yres;
162 mi->bpp = vbemi->bpp;
164 if((mode & 0xff) > 7) {
167 mi->width = stdmode[mode & 0xff].width;
168 mi->height = stdmode[mode & 0xff].height;
169 mi->bpp = stdmode[mode & 0xff].bpp;