X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fdos%2Fvbe.c;h=05a5883b25c4e5a8b2d6739db9667c2151cd6c08;hp=f4fabdf55094beffd0e0293704655f5c2fe88dd5;hb=93f68e445b0a4f10f2b15383aafed8a216a4a228;hpb=57348c2e13f4de9e49f8428b9fec3f47f863a257 diff --git a/src/dos/vbe.c b/src/dos/vbe.c index f4fabdf..05a5883 100644 --- a/src/dos/vbe.c +++ b/src/dos/vbe.c @@ -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,