fallback to banked modes if LFB is not available
[eradicate] / src / dos / gfx.c
index b4e4add..61ac7db 100644 (file)
@@ -1,5 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include "cdpmi.h"
 #include "gfx.h"
 #include "vbe.h"
 #include "vga.h"
@@ -65,6 +67,7 @@ int init_video(void)
                vmptr->xsz = minf.xres;
                vmptr->ysz = minf.yres;
                vmptr->bpp = minf.bpp;
+               vmptr->pitch = minf.scanline_bytes;
                if(minf.mem_model == VBE_TYPE_DIRECT) {
                        vmptr->rbits = minf.rsize;
                        vmptr->gbits = minf.gsize;
@@ -76,6 +79,15 @@ int init_video(void)
                        vmptr->gmask = calc_mask(minf.gsize, minf.gpos);
                        vmptr->bmask = calc_mask(minf.bsize, minf.bpos);
                }
+               if(minf.attr & VBE_ATTR_LFB) {
+                       vmptr->fb_addr = minf.fb_addr;
+               } else {
+                       vmptr->bank_size = (uint32_t)minf.bank_size * 1024;
+                       if(!vmptr->bank_size) {
+                               vmptr->bank_size = 65536;
+                       }
+               }
+               vmptr->max_pages = minf.num_img_pages;
 
                printf("%04x: ", vbe.modes[i]);
                vbe_print_mode_info(stdout, &minf);
@@ -137,11 +149,11 @@ int find_video_mode(int mode)
 void *set_video_mode(int idx, int nbuf)
 {
        unsigned int mode;
-       struct vbe_mode_info minf;
        struct video_mode *vm = vmodes + idx;
 
        printf("setting video mode %x (%dx%d %d bpp)\n", (unsigned int)vm->mode,
                        vm->xsz, vm->ysz, vm->bpp);
+       fflush(stdout);
 
        mode = vm->mode | VBE_MODE_LFB;
        if(vbe_setmode(mode) == -1) {
@@ -153,24 +165,37 @@ void *set_video_mode(int idx, int nbuf)
                printf("Warning: failed to get a linear framebuffer. falling back to banked mode\n");
        }
 
-       vbe_mode_info(mode, &minf);
-
        curmode = vm;
        if(nbuf < 1) nbuf = 1;
        if(nbuf > 2) nbuf = 2;
-       pgcount = nbuf > minf.num_img_pages ? minf.num_img_pages : nbuf;
+       pgcount = nbuf > vm->max_pages ? vm->max_pages : nbuf;
        pgsize = (vm->xsz * vm->bpp / 8) * vm->ysz;
        fbsize = pgcount * pgsize;
 
-       vpgaddr[0] = (void*)dpmi_mmap(minf.fb_addr, fbsize);
-       memset(vpgaddr[0], 0xaa, fbsize);
+       printf("pgcount: %d, pgsize: %d, fbsize: %d\n", pgcount, pgsize, fbsize);
+       printf("phys addr: %p\n", (void*)vm->fb_addr);
+       fflush(stdout);
 
-       if(pgcount > 1) {
-               vpgaddr[1] = (char*)vpgaddr[0] + pgsize;
-               fbidx = 1;
-               page_flip(FLIP_NOW);    /* start with the second page visible */
+       if(vm->fb_addr) {
+               vpgaddr[0] = (void*)dpmi_mmap(vm->fb_addr, fbsize);
+               if(!vpgaddr[0]) {
+                       fprintf(stderr, "failed to map framebuffer (phys: %lx, size: %d)\n",
+                                       (unsigned long)vm->fb_addr, fbsize);
+                       set_text_mode();
+                       return 0;
+               }
+               memset(vpgaddr[0], 0xaa, fbsize);
+
+               if(pgcount > 1) {
+                       vpgaddr[1] = (char*)vpgaddr[0] + pgsize;
+                       fbidx = 1;
+                       page_flip(FLIP_NOW);    /* start with the second page visible */
+               } else {
+                       fbidx = 0;
+                       vpgaddr[1] = 0;
+               }
        } else {
-               fbidx = 0;
+               vpgaddr[0] = (void*)0xa0000;
                vpgaddr[1] = 0;
        }
        return vpgaddr[0];