8 #include <sys/nearptr.h>
9 #define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) - __djgpp_base_address + ((uint32_t)(o)))
11 #define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) + ((uint32_t)(o)))
14 #define SAME_BPP(a, b) \
15 ((a) == (b) || ((a) == 16 && (b) == 15) || ((a) == 15 && (b) == 16) || \
16 ((a) == 32 && (b) == 24) || ((a) == 24 && (b) == 32))
18 static int vbe_init_ver;
19 static struct vbe_info vbe;
20 static int mode, pgsize, fbsize;
21 static struct vbe_mode_info mode_info;
23 static void *vpgaddr[2];
27 static int init_vbe(void)
31 if(vbe_info(&vbe) == -1) {
32 fprintf(stderr, "failed to retrieve VBE information\n");
36 vbe_print_info(stdout, &vbe);
38 num = vbe_num_modes(&vbe);
39 for(i=0; i<num; i++) {
40 struct vbe_mode_info minf;
42 if(vbe_mode_info(vbe.modes[i], &minf) == -1) {
45 printf("%04x: ", vbe.modes[i]);
46 vbe_print_mode_info(stdout, &minf);
50 vbe_init_ver = VBE_VER_MAJOR(vbe.ver);
54 void *set_video_mode(int xsz, int ysz, int bpp, int nbuf)
57 int best_match_mode = -1;
58 struct vbe_mode_info minf;
61 if(init_vbe() == -1) {
62 fprintf(stderr, "failed to initialize VBE\n");
65 if(vbe_init_ver < 2) {
66 fprintf(stderr, "VBE >= 2.0 required\n");
72 nmodes = vbe_num_modes(&vbe);
73 for(i=0; i<nmodes; i++) {
74 if(vbe_mode_info(vbe.modes[i] | VBE_MODE_LFB, &minf) == -1) {
77 if(minf.xres != xsz || minf.yres != ysz) continue;
82 if(SAME_BPP(minf.bpp, bpp)) {
83 best_match_mode = mode;
88 if(best_match_mode == -1) {
89 fprintf(stderr, "failed to find requested video mode (%dx%d %d bpp)\n", xsz, ysz, bpp);
92 mode = best_match_mode;
95 vbe_mode_info(mode, &mode_info);
96 printf("setting video mode %x: (%dx%d %d)\n", (unsigned int)mode, mode_info.xres,
97 mode_info.yres, mode_info.bpp);
99 if(vbe_setmode(mode | VBE_MODE_LFB) == -1) {
100 fprintf(stderr, "failed to set video mode\n");
104 if(nbuf < 1) nbuf = 1;
105 if(nbuf > 2) nbuf = 2;
106 pgcount = nbuf > mode_info.num_img_pages ? mode_info.num_img_pages : nbuf;
108 pgsize = mode_info.xres * mode_info.yres * (bpp / 8);
109 fbsize = pgcount * pgsize;
111 vpgaddr[0] = (void*)dpmi_mmap(mode_info.fb_addr, fbsize);
112 memset(vpgaddr[0], 0xaa, fbsize);
115 vpgaddr[1] = (char*)vpgaddr[0] + pgsize;
117 page_flip(FLIP_NOW); /* start with the second page visible */
126 int set_text_mode(void)
132 void *page_flip(int vsync)
135 /* page flipping not supported */
139 vbe_swap(fbidx ? pgsize : 0, vsync ? VBE_SWAP_VBLANK : VBE_SWAP_NOW);
140 fbidx = (fbidx + 1) & 1;
142 return vpgaddr[fbidx];