static void *sys_physmap(unsigned long phys_addr, size_t len) { int ret; __dpmi_meminfo mi; /* enable 4GB limit on DS descriptor */ if (!__djgpp_nearptr_enable()) { return ERROR_PTR; } if ((phys_addr + len - 1) < (1024 * 1024)) { /* we need to use another method to map first 1MB */ return map_first_meg(phys_addr, len); } mi.address = phys_addr; mi.size = len; ret = __dpmi_physical_address_mapping (&mi); if (ret != 0) { return ERROR_PTR; } return (void *) mi.address + __djgpp_conventional_base; }
static int selector_for_phys_mem (uint32 base, uint32 num_bytes) { int sel; uint32 seg_lim; __dpmi_meminfo minfo; /* Allocate a descriptor. */ sel = __dpmi_allocate_ldt_descriptors (1); if (sel == -1) return -1; seg_lim = ((num_bytes + 4095) & ~4095) - 1; /* Map the physical memory into linear address space. */ minfo.handle = 0; /* unused */ minfo.size = seg_lim + 1; minfo.address = base; if (__dpmi_physical_address_mapping (&minfo) != 0) return -1; if (__dpmi_set_segment_base_address (sel, minfo.address) == -1) return -1; if (__dpmi_set_segment_limit (sel, seg_lim) == -1) return -1; return sel; }
/** * Switches graphics to XGA. Provided by VBETEST.C. **/ void init_graphics(void) { __dpmi_meminfo info; __dpmi_regs reg; ModeInfoBlock *mb; mb=get_mode_info(0x4105); //Gets XGA mode info if (!mb) { printf("Get XGA mode info failed.\n"); exit(1); } if (!(mb->ModeAttributes & 0x80)) { printf("Linear frame buffer not supported for XGA mode.\n"); exit(1); } width=mb->XResolution; height=mb->YResolution; info.size=width*height; info.address=mb->PhysBasePtr; if(__dpmi_physical_address_mapping(&info) == -1) { printf("Physical mapping of address 0x%x failed!\n",mb->PhysBasePtr); exit(2); } ADDR=info.address; /* Updated by above call */ printf("XGA mode 0x4105: %d x %d, linear frame: 0x%x\n",width,height,ADDR); delay(1500); reg.x.ax=0x4f02; //Sets ax for XGA reg.x.bx=0x4105; //Sets bx for XGA __dpmi_int(0x10,®); /* set the mode */ if(reg.h.al != 0x4f || reg.h.ah) { printf("Mode set failed!\n"); exit(3); } }
/* ================ VID_InitExtra ================ */ void VID_InitExtra (void) { int nummodes; short *pmodenums; vbeinfoblock_t *pinfoblock; __dpmi_meminfo phys_mem_info; pinfoblock = dos_getmemory(sizeof(vbeinfoblock_t)); *(long *)pinfoblock->VbeSignature = 'V' + ('B'<<8) + ('E'<<16) + ('2'<<24); // see if VESA support is available regs.x.ax = 0x4f00; regs.x.es = ptr2real(pinfoblock) >> 4; regs.x.di = ptr2real(pinfoblock) & 0xf; dos_int86(0x10); if (regs.x.ax != 0x4f) return; // no VESA support if (pinfoblock->VbeVersion[1] < 0x02) return; // not VESA 2.0 or greater Con_Printf ("VESA 2.0 compliant adapter:\n%s\n", VID_ExtraFarToLinear (*(byte **)&pinfoblock->OemStringPtr[0])); totalvidmem = *(unsigned short *)&pinfoblock->TotalMemory[0] << 16; pmodenums = (short *) VID_ExtraFarToLinear (*(byte **)&pinfoblock->VideoModePtr[0]); // find 8 bit modes until we either run out of space or run out of modes nummodes = 0; while ((*pmodenums != -1) && (nummodes < MAX_VESA_MODES)) { if (VID_ExtraGetModeInfo (*pmodenums)) { vesa_modes[nummodes].pnext = &vesa_modes[nummodes+1]; if (modeinfo.width > 999) { if (modeinfo.height > 999) { sprintf (&names[nummodes][0], "%4dx%4d", modeinfo.width, modeinfo.height); names[nummodes][9] = 0; } else { sprintf (&names[nummodes][0], "%4dx%3d", modeinfo.width, modeinfo.height); names[nummodes][8] = 0; } } else { if (modeinfo.height > 999) { sprintf (&names[nummodes][0], "%3dx%4d", modeinfo.width, modeinfo.height); names[nummodes][8] = 0; } else { sprintf (&names[nummodes][0], "%3dx%3d", modeinfo.width, modeinfo.height); names[nummodes][7] = 0; } } vesa_modes[nummodes].name = &names[nummodes][0]; vesa_modes[nummodes].width = modeinfo.width; vesa_modes[nummodes].height = modeinfo.height; vesa_modes[nummodes].aspect = ((float)modeinfo.height / (float)modeinfo.width) * (320.0 / 240.0); vesa_modes[nummodes].rowbytes = modeinfo.bytes_per_scanline; vesa_modes[nummodes].planar = 0; vesa_modes[nummodes].pextradata = &vesa_extra[nummodes]; vesa_modes[nummodes].setmode = VID_ExtraInitMode; vesa_modes[nummodes].swapbuffers = VID_ExtraSwapBuffers; vesa_modes[nummodes].setpalette = VID_SetVESAPalette; if (modeinfo.mode_attributes & LINEAR_FRAME_BUFFER) { // add linear bit to mode for linear modes vesa_extra[nummodes].vesamode = modeinfo.modenum | LINEAR_MODE; vesa_extra[nummodes].pages[0] = 0; vesa_extra[nummodes].pages[1] = modeinfo.pagesize; vesa_extra[nummodes].pages[2] = modeinfo.pagesize * 2; vesa_modes[nummodes].numpages = modeinfo.numpages; vesa_modes[nummodes].begindirectrect = VGA_BeginDirectRect; vesa_modes[nummodes].enddirectrect = VGA_EndDirectRect; phys_mem_info.address = (int)modeinfo.pptr; phys_mem_info.size = 0x400000; if (__dpmi_physical_address_mapping(&phys_mem_info)) goto NextMode; vesa_extra[nummodes].plinearmem = real2ptr (phys_mem_info.address); } else { // banked at 0xA0000 vesa_extra[nummodes].vesamode = modeinfo.modenum; vesa_extra[nummodes].pages[0] = 0; vesa_extra[nummodes].plinearmem = real2ptr(modeinfo.winasegment<<4); vesa_modes[nummodes].begindirectrect = VGA_BankedBeginDirectRect; vesa_modes[nummodes].enddirectrect = VGA_BankedEndDirectRect; vesa_extra[nummodes].pages[1] = modeinfo.pagesize; vesa_extra[nummodes].pages[2] = modeinfo.pagesize * 2; vesa_modes[nummodes].numpages = modeinfo.numpages; } vesa_extra[nummodes].vga_incompatible = modeinfo.mode_attributes & VGA_INCOMPATIBLE; nummodes++; } NextMode: pmodenums++; } // add the VESA modes at the start of the mode list (if there are any) if (nummodes) { vesa_modes[nummodes-1].pnext = pvidmodes; pvidmodes = &vesa_modes[0]; numvidmodes += nummodes; ppal = dos_getmemory(256*4); } dos_freememory(pinfoblock); }
static int driver_init(char *title, int w, int h, int depth_arg, int refresh_rate, int flags) { int depth = MAX(8, depth_arg); int is_rgb, bpp; int red_pos, blue_pos; fb_dos_detect(); fb_dos_vesa_detect(); if (flags & DRIVER_OPENGL) return -1; if (!fb_dos.nearptr_ok) return -1; if (!fb_dos.vesa_ok) return -1; if (fb_dos_vesa_set_mode(w, h, depth, TRUE)) return -1; refresh_rate = 60; /* FIXME */ fb_dos_lock_data(&video, sizeof(video)); fb_dos_lock_data(&blitter, sizeof(blitter)); data_locked = TRUE; /* Lin* fields are only required for VBE 3.0 */ if( fb_dos.vesa_mode_info.LinRedFieldPosition == 0 && fb_dos.vesa_mode_info.LinBlueFieldPosition == 0) { red_pos = fb_dos.vesa_mode_info.RedFieldPosition; blue_pos = fb_dos.vesa_mode_info.BlueFieldPosition; } else { red_pos = fb_dos.vesa_mode_info.LinRedFieldPosition; blue_pos = fb_dos.vesa_mode_info.LinBlueFieldPosition; } is_rgb = (depth > 8) && (red_pos == 0); if (blue_pos == 10 || red_pos == 10) bpp = 15; else if (blue_pos == 11 || red_pos == 11) bpp = 16; else bpp = fb_dos.vesa_mode_info.BitsPerPixel; blitter = fb_hGetBlitter(fb_dos.vesa_mode_info.BitsPerPixel, is_rgb); if (!blitter) return -1; fb_dos.update = driver_update; fb_dos.update_len = (unsigned int)end_of_driver_update - (unsigned int)driver_update; fb_dos.set_palette = fb_dos_vesa_set_palette; __djgpp_nearptr_enable(); nearptr_enabled = TRUE; mapping.address = fb_dos.vesa_mode_info.PhysBasePtr; mapping.size = fb_dos.vesa_info.total_memory << 16; if (__dpmi_physical_address_mapping(&mapping) != 0) return -1; video = (unsigned char *)(mapping.address - __djgpp_base_address); return fb_dos_init(title, w, h, depth, refresh_rate, flags); }