started backporting the eradicate code
[dosdemo] / src / dos / vbe.c
index f4fabdf..05a5883 100644 (file)
@@ -16,7 +16,7 @@
                } else { \
                        paddr = ((uint32_t)pseg << 4) + poffs; \
                } \
-               (ptr) = (void*)paddr; \
+               (ptr) = (void*)phys_to_virt(paddr); \
        } while(0)
 
 /* hijack the "VESA" sig field, to pre-cache number of modes */
@@ -29,10 +29,10 @@ static int cur_pitch;
 
 int vbe_info(struct vbe_info *info)
 {
-       int i, num;
        void *lowbuf;
        uint16_t seg, sel;
        uint16_t *modeptr;
+       uint32_t offs;
        struct dpmi_regs regs = {0};
 
        assert(sizeof *info == 512);
@@ -40,7 +40,7 @@ int vbe_info(struct vbe_info *info)
        if(!(seg = dpmi_alloc(sizeof *info / 16, &sel))) {
                return -1;
        }
-       lowbuf = (void*)((uint32_t)seg << 4);
+       lowbuf = (void*)phys_to_virt((uint32_t)seg << 4);
 
        memcpy(lowbuf, "VBE2", 4);
 
@@ -63,7 +63,23 @@ int vbe_info(struct vbe_info *info)
        FIXPTR(info->product);
        FIXPTR(info->revstr);
        FIXPTR(info->modes);
-       FIXPTR(info->accel_modes);
+       /* implementations without the accel capability, will use the space taken
+        * by the accel_modes pointer for other data (probably video modes). We
+        * need to check for the capability before "fixing" this pointer, otherwise
+        * we'll shuffle random data.
+        */
+       if(info->caps & VBE_ACCEL) {
+               FIXPTR(info->accel_modes);
+       }
+
+       /* info->modes should be pointing somewhere at the end of the original
+        * low memory buffer. make it point at the same offset in the info
+        * buffer where we copied everything instead.
+        */
+       offs = (char*)info->modes - (char*)lowbuf;
+       if(offs < sizeof *info) {       /* this should always be true */
+               info->modes = (uint16_t*)((char*)info + offs);
+       }
 
        modeptr = info->modes;
        while(*modeptr != 0xffff) {
@@ -96,7 +112,6 @@ int vbe_num_modes(struct vbe_info *info)
 
 int vbe_mode_info(int mode, struct vbe_mode_info *minf)
 {
-       int i, num;
        void *lowbuf;
        uint16_t seg, sel;
        struct dpmi_regs regs = {0};
@@ -107,7 +122,7 @@ int vbe_mode_info(int mode, struct vbe_mode_info *minf)
        if(!(seg = dpmi_alloc(sizeof *minf / 16, &sel))) {
                return -1;
        }
-       lowbuf = (void*)((uint32_t)seg << 4);
+       lowbuf = (void*)phys_to_virt((uint32_t)seg << 4);
 
        regs.eax = 0x4f01;
        regs.ecx = mode;
@@ -191,6 +206,8 @@ void vbe_print_mode_info(FILE *fp, struct vbe_mode_info *minf)
 
        if(minf->attr & VBE_ATTR_LFB) {
                fprintf(fp, " lfb@%lx", (unsigned long)minf->fb_addr);
+       } else {
+               fprintf(fp, " %xkb/bank", (unsigned int)minf->bank_size);
        }
 
        fprintf(fp, " [");
@@ -222,6 +239,8 @@ int vbe_setmode(uint16_t mode)
        if((regs.eax & 0xffff) != 0x4f) {
                return -1;
        }
+
+       cur_pitch = vbe_getpitch();
        return 0;
 }
 
@@ -236,7 +255,7 @@ int vbe_setmode_crtc(uint16_t mode, struct vbe_crtc_info *crtc)
        if(!(seg = dpmi_alloc((sizeof *crtc + 15) / 16, &sel))) {
                return -1;
        }
-       lowbuf = (void*)((uint32_t)seg << 4);
+       lowbuf = (void*)phys_to_virt((uint32_t)seg << 4);
 
        memcpy(lowbuf, crtc, sizeof *crtc);
 
@@ -250,6 +269,8 @@ int vbe_setmode_crtc(uint16_t mode, struct vbe_crtc_info *crtc)
        if((regs.eax & 0xffff) != 0x4f) {
                return -1;
        }
+
+       cur_pitch = vbe_getpitch();
        return 0;
 }
 
@@ -289,7 +310,7 @@ int vbe_save(void *stbuf, int sz, unsigned int flags)
        if(!(seg = dpmi_alloc((sz + 15) / 16, &sel))) {
                return -1;
        }
-       lowbuf = (void*)((uint32_t)seg << 4);
+       lowbuf = (void*)phys_to_virt((uint32_t)seg << 4);
 
        regs.eax = 0x4f04;
        regs.edx = 1;   /* save */
@@ -315,7 +336,7 @@ int vbe_restore(void *stbuf, int sz, unsigned int flags)
        if(!(seg = dpmi_alloc((sz + 15) / 16, &sel))) {
                return -1;
        }
-       lowbuf = (void*)((uint32_t)seg << 4);
+       lowbuf = (void*)phys_to_virt((uint32_t)seg << 4);
 
        memcpy(lowbuf, stbuf, sz);
 
@@ -378,6 +399,7 @@ int vbe_setscanlen(int len_pix)
                return -1;
        }
 
+       cur_pitch = vbe_getpitch();
        return regs.ecx;
 }
 
@@ -432,8 +454,8 @@ enum {
        SDISP_GET                       = 0x01,
        SDISP_ALTSET            = 0x02,
        SDISP_SET_STEREO        = 0x03,
-       SDISP_GETSCHED  = 0x04,
-       SDISP_STEREO_ON = 0x05,
+       SDISP_GETSCHED          = 0x04,
+       SDISP_STEREO_ON         = 0x05,
        SDISP_STEREO_OFF        = 0x06,
        SDISP_SET_VBLANK        = 0x80,
        SDISP_ALTSET_VBLANK     = 0x82,