123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796 |
- /*
- Copyright (C) 1996-1997 Id Software, Inc.
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- //
- // vid_ext.c: extended video modes
- // in this implementation, VESA-specific DOS video stuff
- //
- // TODO: make dependencies on vid_vga.c explicit or eliminate them
- #include <stdlib.h>
- #include <dos.h>
- #include "quakedef.h"
- #include "d_local.h"
- #include "dosisms.h"
- #include "vid_dos.h"
- #include <dpmi.h>
- #define MODE_SUPPORTED_IN_HW 0x0001
- #define COLOR_MODE 0x0008
- #define GRAPHICS_MODE 0x0010
- #define VGA_INCOMPATIBLE 0x0020
- #define LINEAR_FRAME_BUFFER 0x0080
- #define LINEAR_MODE 0x4000
- #define VESA_DONT_WAIT_VSYNC 0 // when page flipping
- #define VESA_WAIT_VSYNC 0x80
- #define MAX_VESA_MODES 30 // we'll just take the first 30 if there
- // are more
- typedef struct {
- int pages[3]; // either 2 or 3 is valid
- int vesamode; // LINEAR_MODE set if linear mode
- void *plinearmem; // linear address of start of frame buffer
- qboolean vga_incompatible;
- } vesa_extra_t;
- static vmode_t vesa_modes[MAX_VESA_MODES] =
- {{NULL, NULL, " ********* VESA modes ********* "}};
- static vesa_extra_t vesa_extra[MAX_VESA_MODES];
- static char names[MAX_VESA_MODES][10];
- extern regs_t regs;
- static int VID_currentpage;
- static int VID_displayedpage;
- static int *VID_pagelist;
- static byte *VID_membase;
- static int VID_banked;
- typedef struct
- {
- int modenum;
- int mode_attributes;
- int winasegment;
- int winbsegment;
- int bytes_per_scanline; // bytes per logical scanline (+16)
- int win; // window number (A=0, B=1)
- int win_size; // window size (+6)
- int granularity; // how finely i can set the window in vid mem (+4)
- int width, height; // displayed width and height (+18, +20)
- int bits_per_pixel; // er, better be 8, 15, 16, 24, or 32 (+25)
- int bytes_per_pixel; // er, better be 1, 2, or 4
- int memory_model; // and better be 4 or 6, packed or direct color (+27)
- int num_pages; // number of complete frame buffer pages (+29)
- int red_width; // the # of bits in the red component (+31)
- int red_pos; // the bit position of the red component (+32)
- int green_width; // etc.. (+33)
- int green_pos; // (+34)
- int blue_width; // (+35)
- int blue_pos; // (+36)
- int pptr;
- int pagesize;
- int numpages;
- } modeinfo_t;
- static modeinfo_t modeinfo;
- // all bytes to avoid problems with compiler field packing
- typedef struct vbeinfoblock_s {
- byte VbeSignature[4];
- byte VbeVersion[2];
- byte OemStringPtr[4];
- byte Capabilities[4];
- byte VideoModePtr[4];
- byte TotalMemory[2];
- byte OemSoftwareRev[2];
- byte OemVendorNamePtr[4];
- byte OemProductNamePtr[4];
- byte OemProductRevPtr[4];
- byte Reserved[222];
- byte OemData[256];
- } vbeinfoblock_t;
- static int totalvidmem;
- static byte *ppal;
- qboolean vsync_exists, de_exists;
- qboolean VID_ExtraGetModeInfo(int modenum);
- int VID_ExtraInitMode (viddef_t *vid, vmode_t *pcurrentmode);
- void VID_ExtraSwapBuffers (viddef_t *vid, vmode_t *pcurrentmode,
- vrect_t *rects);
- /*
- ================
- VGA_BankedBeginDirectRect
- ================
- */
- void VGA_BankedBeginDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode,
- int x, int y, byte *pbitmap, int width, int height)
- {
- if (!lvid->direct)
- return;
- regs.x.ax = 0x4f05;
- regs.x.bx = 0;
- regs.x.dx = VID_displayedpage;
- dos_int86(0x10);
- VGA_BeginDirectRect (lvid, pcurrentmode, x, y, pbitmap, width, height);
- regs.x.ax = 0x4f05;
- regs.x.bx = 0;
- regs.x.dx = VID_currentpage;
- dos_int86(0x10);
- }
- /*
- ================
- VGA_BankedEndDirectRect
- ================
- */
- void VGA_BankedEndDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode,
- int x, int y, int width, int height)
- {
- if (!lvid->direct)
- return;
- regs.x.ax = 0x4f05;
- regs.x.bx = 0;
- regs.x.dx = VID_displayedpage;
- dos_int86(0x10);
- VGA_EndDirectRect (lvid, pcurrentmode, x, y, width, height);
- regs.x.ax = 0x4f05;
- regs.x.bx = 0;
- regs.x.dx = VID_currentpage;
- dos_int86(0x10);
- }
- /*
- ================
- VID_SetVESAPalette
- ================
- */
- void VID_SetVESAPalette (viddef_t *lvid, vmode_t *pcurrentmode,
- unsigned char *pal)
- {
- int i;
- byte *pp;
- UNUSED(lvid);
- UNUSED(pcurrentmode);
- pp = ppal;
- for (i=0 ; i<256 ; i++)
- {
- pp[2] = pal[0] >> 2;
- pp[1] = pal[1] >> 2;
- pp[0] = pal[2] >> 2;
- pp += 4;
- pal += 3;
- }
- regs.x.ax = 0x4F09;
- regs.x.bx = 0;
- regs.x.cx = 256;
- regs.x.dx = 0;
- regs.x.es = ptr2real(ppal) >> 4;
- regs.x.di = ptr2real(ppal) & 0xf;
- dos_int86(0x10);
- if (regs.x.ax != 0x4f)
- Sys_Error ("Unable to load VESA palette\n");
- }
- /*
- ================
- VID_ExtraFarToLinear
- ================
- */
- void *VID_ExtraFarToLinear (void *ptr)
- {
- int temp;
- temp = (int)ptr;
- return real2ptr(((temp & 0xFFFF0000) >> 12) + (temp & 0xFFFF));
- }
- /*
- ================
- VID_ExtraWaitDisplayEnable
- ================
- */
- void VID_ExtraWaitDisplayEnable ()
- {
- while ((inportb (0x3DA) & 0x01) == 1)
- ;
- }
- /*
- ================
- VID_ExtraVidLookForState
- ================
- */
- qboolean VID_ExtraVidLookForState (unsigned state, unsigned mask)
- {
- int i;
- double starttime, time;
- starttime = Sys_FloatTime ();
- do
- {
- for (i=0 ; i<100000 ; i++)
- {
- if ((inportb (0x3DA) & mask) == state)
- return true;
- }
- time = Sys_FloatTime ();
- } while ((time - starttime) < 0.1);
- return false;
- }
- /*
- ================
- VID_ExtraStateFound
- ================
- */
- qboolean VID_ExtraStateFound (unsigned state)
- {
- int i, workingstate;
- workingstate = 0;
- for (i=0 ; i<10 ; i++)
- {
- if (!VID_ExtraVidLookForState(workingstate, state))
- {
- return false;
- }
- workingstate ^= state;
- }
- return true;
- }
- /*
- ================
- 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);
- }
- /*
- ================
- VID_ExtraGetModeInfo
- ================
- */
- qboolean VID_ExtraGetModeInfo(int modenum)
- {
- char *infobuf;
- int numimagepages;
- infobuf = dos_getmemory(256);
- regs.x.ax = 0x4f01;
- regs.x.cx = modenum;
- regs.x.es = ptr2real(infobuf) >> 4;
- regs.x.di = ptr2real(infobuf) & 0xf;
- dos_int86(0x10);
- if (regs.x.ax != 0x4f)
- {
- return false;
- }
- else
- {
- modeinfo.modenum = modenum;
- modeinfo.bits_per_pixel = *(char*)(infobuf+25);
- modeinfo.bytes_per_pixel = (modeinfo.bits_per_pixel+1)/8;
- modeinfo.width = *(short*)(infobuf+18);
- modeinfo.height = *(short*)(infobuf+20);
- // we do only 8-bpp in software
- if ((modeinfo.bits_per_pixel != 8) ||
- (modeinfo.bytes_per_pixel != 1) ||
- (modeinfo.width > MAXWIDTH) ||
- (modeinfo.height > MAXHEIGHT))
- {
- return false;
- }
- modeinfo.mode_attributes = *(short*)infobuf;
- // we only want color graphics modes that are supported by the hardware
- if ((modeinfo.mode_attributes &
- (MODE_SUPPORTED_IN_HW | COLOR_MODE | GRAPHICS_MODE)) !=
- (MODE_SUPPORTED_IN_HW | COLOR_MODE | GRAPHICS_MODE))
- {
- return false;
- }
- // we only work with linear frame buffers, except for 320x200, which can
- // effectively be linear when banked at 0xA000
- if (!(modeinfo.mode_attributes & LINEAR_FRAME_BUFFER))
- {
- if ((modeinfo.width != 320) || (modeinfo.height != 200))
- return false;
- }
- modeinfo.bytes_per_scanline = *(short*)(infobuf+16);
- modeinfo.pagesize = modeinfo.bytes_per_scanline * modeinfo.height;
- if (modeinfo.pagesize > totalvidmem)
- return false;
- // force to one page if the adapter reports it doesn't support more pages
- // than that, no matter how much memory it has--it may not have hardware
- // support for page flipping
- numimagepages = *(unsigned char *)(infobuf+29);
- if (numimagepages <= 0)
- {
- // wrong, but there seems to be an ATI VESA driver that reports 0
- modeinfo.numpages = 1;
- }
- else if (numimagepages < 3)
- {
- modeinfo.numpages = numimagepages;
- }
- else
- {
- modeinfo.numpages = 3;
- }
- if (*(char*)(infobuf+2) & 5)
- {
- modeinfo.winasegment = *(unsigned short*)(infobuf+8);
- modeinfo.win = 0;
- }
- else if (*(char*)(infobuf+3) & 5)
- {
- modeinfo.winbsegment = *(unsigned short*)(infobuf+8);
- modeinfo.win = 1;
- }
- modeinfo.granularity = *(short*)(infobuf+4) * 1024;
- modeinfo.win_size = *(short*)(infobuf+6) * 1024;
- modeinfo.bits_per_pixel = *(char*)(infobuf+25);
- modeinfo.bytes_per_pixel = (modeinfo.bits_per_pixel+1)/8;
- modeinfo.memory_model = *(unsigned char*)(infobuf+27);
- modeinfo.num_pages = *(char*)(infobuf+29) + 1;
- modeinfo.red_width = *(char*)(infobuf+31);
- modeinfo.red_pos = *(char*)(infobuf+32);
- modeinfo.green_width = *(char*)(infobuf+33);
- modeinfo.green_pos = *(char*)(infobuf+34);
- modeinfo.blue_width = *(char*)(infobuf+35);
- modeinfo.blue_pos = *(char*)(infobuf+36);
- modeinfo.pptr = *(long *)(infobuf+40);
- #if 0
- printf("VID: (VESA) info for mode 0x%x\n", modeinfo.modenum);
- printf(" mode attrib = 0x%0x\n", modeinfo.mode_attributes);
- printf(" win a attrib = 0x%0x\n", *(unsigned char*)(infobuf+2));
- printf(" win b attrib = 0x%0x\n", *(unsigned char*)(infobuf+3));
- printf(" win a seg 0x%0x\n", (int) modeinfo.winasegment);
- printf(" win b seg 0x%0x\n", (int) modeinfo.winbsegment);
- printf(" bytes per scanline = %d\n",
- modeinfo.bytes_per_scanline);
- printf(" width = %d, height = %d\n", modeinfo.width,
- modeinfo.height);
- printf(" win = %c\n", 'A' + modeinfo.win);
- printf(" win granularity = %d\n", modeinfo.granularity);
- printf(" win size = %d\n", modeinfo.win_size);
- printf(" bits per pixel = %d\n", modeinfo.bits_per_pixel);
- printf(" bytes per pixel = %d\n", modeinfo.bytes_per_pixel);
- printf(" memory model = 0x%x\n", modeinfo.memory_model);
- printf(" num pages = %d\n", modeinfo.num_pages);
- printf(" red width = %d\n", modeinfo.red_width);
- printf(" red pos = %d\n", modeinfo.red_pos);
- printf(" green width = %d\n", modeinfo.green_width);
- printf(" green pos = %d\n", modeinfo.green_pos);
- printf(" blue width = %d\n", modeinfo.blue_width);
- printf(" blue pos = %d\n", modeinfo.blue_pos);
- printf(" phys mem = %x\n", modeinfo.pptr);
- #endif
- }
- dos_freememory(infobuf);
- return true;
- }
- /*
- ================
- VID_ExtraInitMode
- ================
- */
- int VID_ExtraInitMode (viddef_t *lvid, vmode_t *pcurrentmode)
- {
- vesa_extra_t *pextra;
- int pageoffset;
- pextra = pcurrentmode->pextradata;
- if (vid_nopageflip.value)
- lvid->numpages = 1;
- else
- lvid->numpages = pcurrentmode->numpages;
- // clean up any old vid buffer lying around, alloc new if needed
- if (!VGA_FreeAndAllocVidbuffer (lvid, lvid->numpages == 1))
- return -1; // memory alloc failed
- // clear the screen and wait for the next frame. VGA_pcurmode, which
- // VGA_ClearVideoMem relies on, is guaranteed to be set because mode 0 is
- // always the first mode set in a session
- if (VGA_pcurmode)
- VGA_ClearVideoMem (VGA_pcurmode->planar);
- // set the mode
- regs.x.ax = 0x4f02;
- regs.x.bx = pextra->vesamode;
- dos_int86(0x10);
- if (regs.x.ax != 0x4f)
- return 0;
- VID_banked = !(pextra->vesamode & LINEAR_MODE);
- VID_membase = pextra->plinearmem;
- VGA_width = lvid->width;
- VGA_height = lvid->height;
- VGA_rowbytes = lvid->rowbytes;
- lvid->colormap = host_colormap;
- VID_pagelist = &pextra->pages[0];
- // wait for display enable by default only when triple-buffering on a VGA-
- // compatible machine that actually has a functioning display enable status
- vsync_exists = VID_ExtraStateFound (0x08);
- de_exists = VID_ExtraStateFound (0x01);
- if (!pextra->vga_incompatible &&
- (lvid->numpages == 3) &&
- de_exists &&
- (_vid_wait_override.value == 0.0))
- {
- Cvar_SetValue ("vid_wait", (float)VID_WAIT_DISPLAY_ENABLE);
- VID_displayedpage = 0;
- VID_currentpage = 1;
- }
- else
- {
- if ((lvid->numpages == 1) && (_vid_wait_override.value == 0.0))
- {
- Cvar_SetValue ("vid_wait", (float)VID_WAIT_NONE);
- VID_displayedpage = VID_currentpage = 0;
- }
- else
- {
- Cvar_SetValue ("vid_wait", (float)VID_WAIT_VSYNC);
- VID_displayedpage = 0;
- if (lvid->numpages > 1)
- VID_currentpage = 1;
- else
- VID_currentpage = 0;
- }
- }
- // TODO: really should be a call to a function
- pageoffset = VID_pagelist[VID_displayedpage];
- regs.x.ax = 0x4f07;
- regs.x.bx = 0x80; // wait for vsync so we know page 0 is visible
- regs.x.cx = pageoffset % VGA_rowbytes;
- regs.x.dx = pageoffset / VGA_rowbytes;
- dos_int86(0x10);
- if (VID_banked)
- {
- regs.x.ax = 0x4f05;
- regs.x.bx = 0;
- regs.x.dx = VID_currentpage;
- dos_int86(0x10);
- VGA_pagebase = VID_membase;
- }
- else
- {
- VGA_pagebase = VID_membase + VID_pagelist[VID_currentpage];
- }
- if (lvid->numpages > 1)
- {
- lvid->buffer = VGA_pagebase;
- lvid->conbuffer = lvid->buffer;
- }
- else
- {
- lvid->rowbytes = lvid->width;
- }
- lvid->direct = VGA_pagebase;
- lvid->conrowbytes = lvid->rowbytes;
- lvid->conwidth = lvid->width;
- lvid->conheight = lvid->height;
- lvid->maxwarpwidth = WARP_WIDTH;
- lvid->maxwarpheight = WARP_HEIGHT;
- VGA_pcurmode = pcurrentmode;
- D_InitCaches (vid_surfcache, vid_surfcachesize);
- return 1;
- }
- /*
- ================
- VID_ExtraSwapBuffers
- ================
- */
- void VID_ExtraSwapBuffers (viddef_t *lvid, vmode_t *pcurrentmode,
- vrect_t *rects)
- {
- int pageoffset;
- UNUSED(rects);
- UNUSED(pcurrentmode);
- pageoffset = VID_pagelist[VID_currentpage];
- // display the newly finished page
- if (lvid->numpages > 1)
- {
- // page flipped
- regs.x.ax = 0x4f07;
-
- if (vid_wait.value != VID_WAIT_VSYNC)
- {
- if ((vid_wait.value == VID_WAIT_DISPLAY_ENABLE) && de_exists)
- VID_ExtraWaitDisplayEnable ();
-
- regs.x.bx = VESA_DONT_WAIT_VSYNC;
- }
- else
- {
- regs.x.bx = VESA_WAIT_VSYNC; // double buffered has to wait
- }
- regs.x.cx = pageoffset % VGA_rowbytes;
- regs.x.dx = pageoffset / VGA_rowbytes;
- dos_int86(0x10);
-
- VID_displayedpage = VID_currentpage;
- if (++VID_currentpage >= lvid->numpages)
- VID_currentpage = 0;
-
- //
- // set the new write window if this is a banked mode; otherwise, set the
- // new address to which to write
- //
- if (VID_banked)
- {
- regs.x.ax = 0x4f05;
- regs.x.bx = 0;
- regs.x.dx = VID_currentpage;
- dos_int86(0x10);
- }
- else
- {
- lvid->direct = lvid->buffer; // direct drawing goes to the
- // currently displayed page
- lvid->buffer = VID_membase + VID_pagelist[VID_currentpage];
- lvid->conbuffer = lvid->buffer;
- }
-
- VGA_pagebase = lvid->buffer;
- }
- else
- {
- // non-page-flipped
- if (vsync_exists && (vid_wait.value == VID_WAIT_VSYNC))
- {
- VGA_WaitVsync ();
- }
- while (rects)
- {
- VGA_UpdateLinearScreen (
- lvid->buffer + rects->x + (rects->y * lvid->rowbytes),
- VGA_pagebase + rects->x + (rects->y * VGA_rowbytes),
- rects->width,
- rects->height,
- lvid->rowbytes,
- VGA_rowbytes);
- rects = rects->pnext;
- }
- }
- }
|