X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=drv_vbe.c;h=59ec306b92e63924a35fd8bd8ccd8456c981e97f;hb=898a618bf25182f1e3b456303c3c2613c170856e;hp=e051692325e577c4f2d899dd8f6d64efbb1f5baa;hpb=ee6be1955413171a03391c6b171d50bb3f2a5001;p=vidsys diff --git a/drv_vbe.c b/drv_vbe.c index e051692..59ec306 100644 --- a/drv_vbe.c +++ b/drv_vbe.c @@ -16,16 +16,19 @@ static int getmode(void); static const char *memsize_str(long sz); static int get_mode_info(int mode, struct vbe_mode_info *mi); static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info *vbemi); +static unsigned int calc_mask(int nbits, int pos); -static struct vid_driver drv = {"vbe", 2}; +static struct vid_driver drv; static struct vid_drvops drvops = {init, cleanup, setmode, getmode}; -static struct vid_modeinfo *modes; -static int num_modes; static unsigned int vbe_ver; +static int cur_mode; + void vid_register_vbe(void) { + drv.name = "vbe"; + drv.prio = 2; drv.ops = &drvops; vid_drvlist[vid_numdrv++] = &drv; @@ -42,6 +45,8 @@ static int init(void) int i, count; struct vid_modeinfo modeinf; + cur_mode = -1; + vbe = dpmi_lowbuf(); bufseg = (intptr_t)vbe >> 4; @@ -57,7 +62,7 @@ static int init(void) vbe_ver = vbe->ver; - printf("Found VBE %d.%d\n", vbe_ver >> 8, vbe_ver & 0xff); + printf("Found VBE %d.%d\n", VBE_VER_MAJOR(vbe_ver), VBE_VER_MINOR(vbe_ver)); printf("OEM: %s\n", (char*)farptr_to_linear(vbe->oem_name)); if(vbe_ver >= 0x0200) { printf("%s - %s (%s)\n", (char*)farptr_to_linear(vbe->vendor), @@ -81,31 +86,59 @@ static int init(void) modelist[i] = vbe_modelist[i]; } - printf("found %d modes\n", count); - return 0; - num_modes = 0; + if(!(drv.modes = malloc(count * sizeof *drv.modes))) { + fprintf(stderr, "failed to allocate mode list\n"); + free(modelist); + return -1; + } + + drv.num_modes = 0; for(i=0; iattr & VBE_ATTR_AVAIL)) { + return -1; /* ignore unsupported modes */ + } + if(!(vbemi->attr & VBE_ATTR_GFX)) { + return -1; /* ignore text modes */ + } + if(vbemi->attr & VBE_ATTR_LFB) { + mi->lfb = 1; + } + + mi->drv = &drv; + mi->modeno = mode; + mi->vmem_addr = 0xa0000; + if(vbe_ver >= 0x0102) { mi->width = vbemi->xres; mi->height = vbemi->yres; mi->bpp = vbemi->bpp; + mi->rshift = vbemi->rpos; + mi->gshift = vbemi->gpos; + mi->bshift = vbemi->bpos; + mi->rmask = calc_mask(vbemi->rsize, vbemi->rpos); + mi->gmask = calc_mask(vbemi->gsize, vbemi->gpos); + mi->bmask = calc_mask(vbemi->bsize, vbemi->bpos); + mi->pages = vbemi->num_img_pages + 1; + + if(vbe_ver >= 0x0200) { + mi->vmem_addr = vbemi->fb_addr; + mi->vmem_size = vbemi->scanline_bytes * mi->height * mi->pages; + } } else { if((mode & 0xff) > 7) { return -1; @@ -168,5 +231,20 @@ static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info mi->height = stdmode[mode & 0xff].height; mi->bpp = stdmode[mode & 0xff].bpp; } + mi->ncolors = 1 << mi->bpp; + mi->pitch = vbemi->scanline_bytes; + mi->win_size = vbemi->win_size; + mi->win_gran = vbemi->win_gran; return 0; } + +static unsigned int calc_mask(int nbits, int pos) +{ + int i; + unsigned int mask = 0; + + for(i=0; i