12 #include <sys/nearptr.h>
14 #define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) - __djgpp_base_address + (uint32_t)(o))
16 #define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) + (uint32_t)(o))
19 #define VBEPTR(x) REALPTR(((x) & 0xffff0000) >> 16, (x) & 0xffff)
20 #define VBEPTR_SEG(x) (((x) & 0xffff0000) >> 16)
21 #define VBEPTR_OFF(x) ((x) & 0xffff)
23 #define SAME_BPP(a, b) \
24 ((a) == (b) || ((a) == 16 && (b) == 15) || ((a) == 15 && (b) == 16) || \
25 ((a) == 32 && (b) == 24) || ((a) == 24 && (b) == 32))
27 static unsigned int make_mask(int sz, int pos);
29 static struct vbe_info *vbe_info;
30 static struct vbe_mode_info *mode_info;
31 static int pal_bits = 6;
33 void *set_video_mode(int xsz, int ysz, int bpp)
36 static uint16_t *modes;
41 __djgpp_nearptr_enable();
44 /* check for VBE2 support and output some info */
46 if(!(vbe_info = vbe_get_info())) {
47 fprintf(stderr, "VESA BIOS Extensions not available\n");
51 printf("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff);
52 if(vbe_info->version < 0x200) {
53 fprintf(stderr, "This program requires VBE 2.0 or greater. Try running UniVBE\n");
57 printf("Graphics adapter: %s, %s (%s)\n", (char*)VBEPTR(vbe_info->oem_vendor_name_ptr),
58 (char*)VBEPTR(vbe_info->oem_product_name_ptr), (char*)VBEPTR(vbe_info->oem_product_rev_ptr));
59 printf("Video memory: %dkb\n", vbe_info->total_mem << 6);
61 modes = VBEPTR(vbe_info->vid_mode_ptr);
64 for(i=0; i<1024; i++) { /* impose an upper limit to avoid inf-loops */
65 if(modes[i] == 0xffff) {
66 break; /* reached the end */
69 mode_info = vbe_get_mode_info(modes[i] | VBE_MODE_LFB);
70 if(!mode_info || mode_info->xres != xsz || mode_info->yres != ysz) {
73 if(SAME_BPP(mode_info->bpp, bpp)) {
79 mode_info = vbe_get_mode_info(best);
81 fprintf(stderr, "Requested video mode (%dx%d %dbpp) is unavailable\n", xsz, ysz, bpp);
85 if(vbe_set_mode(best | VBE_MODE_LFB) == -1) {
86 fprintf(stderr, "Failed to set video mode %dx%d %dbpp\n", mode_info->xres, mode_info->yres, mode_info->bpp);
90 /* attempt to set 8 bits of color per component in palettized modes */
92 pal_bits = vbe_set_palette_bits(8);
93 printf("palette bits per color primary: %d\n", pal_bits);
97 fbsize = xsz * ysz * mode_info->num_img_pages * (bpp / CHAR_BIT);
98 return (void*)dpmi_mmap(mode_info->fb_addr, fbsize);
101 int set_text_mode(void)
107 int get_color_depth(void)
112 return mode_info->bpp;
115 int get_color_bits(int *rbits, int *gbits, int *bbits)
120 *rbits = mode_info->rmask_size;
121 *gbits = mode_info->gmask_size;
122 *bbits = mode_info->bmask_size;
126 int get_color_mask(unsigned int *rmask, unsigned int *gmask, unsigned int *bmask)
131 *rmask = make_mask(mode_info->rmask_size, mode_info->rpos);
132 *gmask = make_mask(mode_info->gmask_size, mode_info->gpos);
133 *bmask = make_mask(mode_info->bmask_size, mode_info->bpos);
137 int get_color_shift(int *rshift, int *gshift, int *bshift)
142 *rshift = mode_info->rpos;
143 *gshift = mode_info->gpos;
144 *bshift = mode_info->bpos;
148 void set_palette(int idx, int r, int g, int b)
154 vbe_set_palette(idx, col, 1, pal_bits);
158 void wait_vsync_asm(void);
159 #pragma aux wait_vsync_asm = \
171 void wait_vsync(void)
178 void wait_vsync(void)
181 "mov $0x3da, %%dx\n\t"
194 static unsigned int make_mask(int sz, int pos)
196 unsigned int i, mask = 0;
198 for(i=0; i<sz; i++) {