} 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 */
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);
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);
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) {
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};
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;
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, " [");
if((regs.eax & 0xffff) != 0x4f) {
return -1;
}
+
+ cur_pitch = vbe_getpitch();
return 0;
}
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);
if((regs.eax & 0xffff) != 0x4f) {
return -1;
}
+
+ cur_pitch = vbe_getpitch();
return 0;
}
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 */
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);
return -1;
}
+ cur_pitch = vbe_getpitch();
return regs.ecx;
}
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,