The Build Engine
ves2.h
1 // "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman
2 // Ken Silverman's official web site: "http://www.advsys.net/ken"
3 // See the included license file "BUILDLIC.TXT" for license info.
4 // This file has been modified from Ken Silverman's original release
5 
6 #ifndef _INCLUDE_VES2_H_
7 #define _INCLUDE_VES2_H_
8 
9 #if (!defined PLATFORM_DOS)
10 #error Do not include this file. It is for the DOS target only.
11 #endif
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <conio.h>
17 #include <dos.h>
18 
19 #include "build.h"
20 #include "pragmas.h"
21 
22 #pragma pack(push,1);
23 
24 typedef struct
25 {
26  char VESASignature[4];
27  short VESAVersion;
28  long OemStringPtr, Capabilities, VideoModePtr;
29  short TotalMemory, OemSoftwareRev;
30  long OemVendorNamePtr, OemProductNamePtr, OemProductRevPtr;
31  char reserved[222], OemDATA[256];
32 } VBE_vgaInfo;
33 
34 typedef struct
35 {
36  short ModeAttributes;
37  char WinAAtributes, WinBAttributes;
38  short WinGranularity, WinSize, WinASegment, WinBSegment;
39  long WinFuncPtr;
40  short BytesPerScanLine, XResolution, YResolution;
41  char XCharSize, YCharSize, NumberOfPlanes, BitsPerPixel;
42  char NumberOfBanks, MemoryModel, BankSize, NumberOfImagePages;
43  char res1;
44  char RedMaskSize, RedFieldPosition;
45  char GreenMaskSize, GreenFieldPosition;
46  char BlueMaskSize, BlueFieldPosition;
47  char RsvdMaskSize, RsvdFieldPosition, DirectColorModeInfo;
48  long PhysBasePtr, OffScreenMemOffset;
49  short OffScreenMemSize;
50  char res2[206];
51 } VBE_modeInfo;
52 
53 struct _RMWORDREGS { unsigned short ax, bx, cx, dx, si, di, cflag; };
54 struct _RMBYTEREGS { unsigned char al, ah, bl, bh, cl, ch, dl, dh; };
55 typedef union { struct _RMWORDREGS x; struct _RMBYTEREGS h; } RMREGS;
56 typedef struct { unsigned short es, cs, ss, ds; } RMSREGS;
57 
58 typedef struct
59 {
60  long edi, esi, ebp, reserved, ebx, edx, ecx, eax;
61  short flags, es, ds, fs, gs, ip, cs, sp, ss;
62 } _RMREGS;
63 
64 #pragma pack(pop);
65 
66 long VESABuf_sel = 0, VESABuf_rseg;
67 short modelist[256];
68 char *screen = NULL, vesachecked = 0;
69 long xres, yres, bytesperline, frameplace, imageSize, maxpages;
70 long buffermode, origbuffermode, linearmode;
71 long setactiveentry = 0, setvisualentry = 0, setpaletteentry = 0;
72 char permanentupdate = 0, vgacompatible;
73 short visualpagelookup[64][2];
74 long activepagelookup[64];
75 static long ves2lastx[MAXYDIM];
76 static long davesapageshift;
77 static VBE_vgaInfo vgaInfo;
78 long globlinplace;
79 static long backlinaddress = 0; //Save address for free operation (0x801)
80 
81 void faketimerhandler(void);
82 
83 void qlimitrate(void);
84 #pragma aux qlimitrate =\
85  "mov dx, 0x3da",\
86  "wait1: in al, dx",\
87  "test al, 1",\
88  "jnz wait1",\
89  modify exact [eax edx]\
90 
91 void backupsegs(void);
92 short ods, oes, oss;
93 #pragma aux backupsegs =\
94  "mov ods, ds",\
95  "mov oes, es",\
96  "mov oss, ss",\
97  modify [eax]\
98 
99 void restoresegs(void);
100 #pragma aux restoresegs =\
101  "mov ds, ods",\
102  "mov es, oes",\
103  "mov ss, oss",\
104  modify [eax]\
105 
106 /* //64-bit copybufbyte
107 #pragma aux copybufbyte =\
108  "cmp ecx, 8",\
109  "jae longcopy",\
110  "test cl, 1",\
111  "jz shortskip1",\
112  "movsb",\
113  "shortskip1: shr ecx, 2",\
114  "jnc shortskip2",\
115  "movsw",\
116  "shortskip2: rep movsd",\
117  "jmp endit",\
118  "longcopy: test edi, 1",\
119  "jz skip1",\
120  "movsb",\
121  "dec ecx",\
122  "skip1: test edi, 2",\
123  "jz skip2",\
124  "movsw",\
125  "sub ecx, 2",\
126  "skip2: test edi, 4",\
127  "jz skip3",\
128  "movsd",\
129  "sub ecx, 4",\
130  "skip3: mov ebx, ecx",\
131  "shr ecx, 3",\
132  "jz skip4",\
133  "begloop: fld qword ptr [esi]",\
134  "fstp qword ptr [edi]",\
135  "add esi, 8",\
136  "add edi, 8",\
137  "dec ecx",\
138  "jnz begloop",\
139  "skip4: test bl, 4",\
140  "jz skip5",\
141  "movsd",\
142  "skip5: test bl, 2",\
143  "jz skip6",\
144  "movsw",\
145  "skip6: test bl, 1",\
146  "jz endit",\
147  "movsb",\
148  "endit:",\
149  parm [esi][edi][ecx]\
150  modify [ebx]\
151 */
152 
153 
154 void vesasetactive(long i1, long i2, long i3, long i4);
155 #pragma aux vesasetactive =\
156  "call dword ptr [setactiveentry]",\
157  parm [eax][ebx][ecx][edx]\
158 
159 void vesasetvisual(long i1, long i2, long i3, long i4);
160 #pragma aux vesasetvisual =\
161  "call dword ptr [setvisualentry]",\
162  parm [eax][ebx][ecx][edx]\
163 
164 long vesasetpalette(long i1, long i2, long i3, long i4, long i5, char *i6);
165 #pragma aux vesasetpalette =\
166  "call dword ptr [setpaletteentry]",\
167  parm [eax][ebx][ecx][edx][esi][edi]\
168 
169 long DPMI_int86(long intno, RMREGS *in, RMREGS *out)
170 {
171  _RMREGS rmregs;
172  union REGS r;
173  struct SREGS sr;
174 
175  memset(&rmregs,0,sizeof(rmregs));
176  rmregs.eax = in->x.ax; rmregs.ebx = in->x.bx;
177  rmregs.ecx = in->x.cx; rmregs.edx = in->x.dx;
178  rmregs.esi = in->x.si; rmregs.edi = in->x.di;
179 
180  segread(&sr);
181  r.w.ax = 0x300; r.h.bl = intno; r.h.bh = 0; r.w.cx = 0; sr.es = sr.ds;
182  r.x.edi = (unsigned)&rmregs;
183  backupsegs(); int386x(0x31,&r,&r,&sr); restoresegs();
184 
185  out->x.ax = rmregs.eax; out->x.bx = rmregs.ebx;
186  out->x.cx = rmregs.ecx; out->x.dx = rmregs.edx;
187  out->x.si = rmregs.esi; out->x.di = rmregs.edi;
188  out->x.cflag = rmregs.flags&1;
189  return(out->x.ax);
190 }
191 
192 long DPMI_int86x(long intno, RMREGS *in, RMREGS *out, RMSREGS *sregs)
193 {
194  _RMREGS rmregs;
195  union REGS r;
196  struct SREGS sr;
197 
198  memset(&rmregs, 0, sizeof(rmregs));
199  rmregs.eax = in->x.ax; rmregs.ebx = in->x.bx;
200  rmregs.ecx = in->x.cx; rmregs.edx = in->x.dx;
201  rmregs.esi = in->x.si; rmregs.edi = in->x.di;
202  rmregs.es = sregs->es;
203  rmregs.ds = sregs->ds;
204 
205  segread(&sr);
206  r.w.ax = 0x300; r.h.bl = intno; r.h.bh = 0; r.w.cx = 0; sr.es = sr.ds;
207  r.x.edi = (unsigned)&rmregs;
208  backupsegs(); int386x(0x31,&r,&r,&sr); restoresegs();
209 
210  out->x.ax = rmregs.eax; out->x.bx = rmregs.ebx;
211  out->x.cx = rmregs.ecx; out->x.dx = rmregs.edx;
212  out->x.si = rmregs.esi; out->x.di = rmregs.edi;
213  sregs->es = rmregs.es; sregs->cs = rmregs.cs;
214  sregs->ss = rmregs.ss; sregs->ds = rmregs.ds;
215  out->x.cflag = rmregs.flags&1;
216  return(out->x.ax);
217 }
218 
219 static void ExitVBEBuf(void)
220 {
221  union REGS r;
222  r.w.ax = 0x101; r.w.dx = VESABuf_sel; //DPMI free real seg
223  backupsegs(); int386(0x31,&r,&r); restoresegs();
224 }
225 
226 void VBE_callESDI(RMREGS *regs, void *buffer, long size)
227 {
228  RMSREGS sregs;
229  union REGS r;
230 
231  if (!VESABuf_sel) //Init Real mode buffer
232  {
233  r.w.ax = 0x100; r.w.bx = 1024>>4;
234  backupsegs(); int386(0x31,&r,&r); restoresegs();
235  if (r.w.cflag) { printf("DPMI_allocRealSeg failed!\n"); exit(0); }
236  VESABuf_sel = r.w.dx;
237  VESABuf_rseg = r.w.ax;
238  atexit(ExitVBEBuf);
239  }
240  sregs.es = VESABuf_rseg;
241  regs->x.di = 0;
242  _fmemcpy(MK_FP(VESABuf_sel,0),buffer,size);
243  DPMI_int86x(0x10,regs,regs,&sregs);
244  _fmemcpy(buffer,MK_FP(VESABuf_sel,0),size);
245 }
246 
247 long VBE_getModeInfo(long mode, VBE_modeInfo *modeInfo)
248 {
249  RMREGS regs;
250 
251  regs.x.ax = 0x4f01;
252  regs.x.cx = mode;
253  VBE_callESDI(&regs, modeInfo, sizeof(VBE_modeInfo));
254  if (regs.x.ax != 0x004f) return(0);
255  if ((modeInfo->ModeAttributes&1) == 0) return(0); //1 is vbeMdAvailable
256  return(1);
257 }
258 
259 GetPtrToLFB(long physAddr)
260 {
261  #define LIMIT (4096*1024)-1
262  long sel;
263  union REGS r;
264 
265  r.w.ax = 0; r.w.cx = 1;
266  backupsegs(); int386(0x31,&r,&r); restoresegs();
267  if (r.x.cflag) { printf("DPMI_allocSelector() failed!\n"); exit(0); }
268  sel = r.w.ax;
269  r.w.ax = 9; r.w.bx = sel; r.w.cx = 0x8092;
270  backupsegs(); int386(0x31,&r,&r); restoresegs();
271 
272  r.w.ax = 0x800; r.w.bx = physAddr >> 16; r.w.cx = physAddr & 0xffff;
273  r.w.si = LIMIT>>16; r.w.di = LIMIT&0xffff;
274  backupsegs(); int386(0x31,&r,&r); restoresegs();
275  if (r.x.cflag) { printf("DPMI_mapPhysicalToLinear() failed!\n"); exit(0); }
276  backlinaddress = globlinplace = ((long)r.w.bx<<16)+r.w.cx;
277 
278  r.w.ax = 7; r.w.bx = sel;
279  r.w.cx = globlinplace>>16; r.w.dx = globlinplace&0xffff;
280  backupsegs(); int386(0x31,&r,&r); restoresegs();
281  if (r.x.cflag) { printf("DPMI_setSelectorBase() failed!\n"); exit(0); }
282 
283  r.w.ax = 8; r.w.bx = sel;
284  r.w.cx = LIMIT>>16; r.w.dx = LIMIT&0xffff;
285  backupsegs(); int386(0x31,&r,&r); restoresegs();
286  if (r.x.cflag) { printf("DPMI_setSelectorLimit() failed!\n"); exit(0); }
287 }
288 
289 void getvalidvesamodes(void)
290 {
291  long i, j, k;
292  short *p, *p2;
293  VBE_modeInfo modeInfo;
294  RMREGS regs;
295 
296  if (vesachecked) return;
297  vesachecked = 1;
298 
299  validmodecnt = 0;
300  modelist[0] = -1;
301 
302  strncpy(vgaInfo.VESASignature,"VBE2",4);
303  regs.x.ax = 0x4f00;
304  VBE_callESDI(&regs,&vgaInfo,sizeof(VBE_vgaInfo));
305  if ((regs.x.ax != 0x004f) || (strncmp(vgaInfo.VESASignature,"VESA",4)))
306  return;
307 
308  //if (vgaInfo.VESAVersion < 0x200) return;
309 
310  //LfbMapRealPointer
311  p = (short *)(((vgaInfo.VideoModePtr&0xffff0000)>>12)+((vgaInfo.VideoModePtr)&0xffff));
312  p2 = modelist;
313  while (*p != -1) *p2++ = *p++;
314  *p2 = -1;
315 
316  for(p=modelist;*p!=-1;p++)
317  {
318  regs.x.ax = 0x4f01; regs.x.cx = *p;
319  VBE_callESDI(&regs,&modeInfo,sizeof(VBE_modeInfo));
320  if (regs.x.ax != 0x004f) continue;
321  if (!(modeInfo.ModeAttributes&1)) continue; //1 is vbeMdAvailable
322  if (modeInfo.MemoryModel != 4) continue; //4 is vbeMemPK
323  if (modeInfo.BitsPerPixel != 8) continue;
324  if (modeInfo.NumberOfPlanes != 1) continue;
325 
326  validmode[validmodecnt] = *p;
327  validmodexdim[validmodecnt] = modeInfo.XResolution;
328  validmodeydim[validmodecnt] = modeInfo.YResolution;
329  validmodecnt++;
330  }
331 
332  for(i=1;i<validmodecnt;i++)
333  for(j=0;j<i;j++)
334  if (validmodeydim[i] < validmodeydim[j])
335  {
336  k = validmode[i]; validmode[i] = validmode[j]; validmode[j] = k;
337  k = validmodexdim[i]; validmodexdim[i] = validmodexdim[j]; validmodexdim[j] = k;
338  k = validmodeydim[i]; validmodeydim[i] = validmodeydim[j]; validmodeydim[j] = k;
339  }
340 
341  for(i=1;i<validmodecnt;i++)
342  for(j=0;j<i;j++)
343  if (validmodexdim[i] < validmodexdim[j])
344  {
345  k = validmode[i]; validmode[i] = validmode[j]; validmode[j] = k;
346  k = validmodexdim[i]; validmodexdim[i] = validmodexdim[j]; validmodexdim[j] = k;
347  k = validmodeydim[i]; validmodeydim[i] = validmodeydim[j]; validmodeydim[j] = k;
348  }
349 }
350 
351 int setvesa(long x, long y)
352 {
353  div_t dived;
354  long i, j, k;
355  //short *p, *p1, *p2;
356  short *p1;
357  VBE_modeInfo modeInfo;
358  RMREGS regs;
359  RMSREGS sregs;
360 
361  getvalidvesamodes();
362 
363  xres = x; yres = y;
364  for(k=0;k<validmodecnt;k++)
365  {
366  regs.x.ax = 0x4f01; regs.x.cx = validmode[k];
367  VBE_callESDI(&regs,&modeInfo,sizeof(VBE_modeInfo));
368  if (regs.x.ax != 0x004f) continue;
369  if (!(modeInfo.ModeAttributes&1)) continue; //1 is vbeMdAvailable
370 
371  if (modeInfo.MemoryModel != 4) continue; //4 is vbeMemPK
372  if (modeInfo.BitsPerPixel != 8) continue;
373  if (modeInfo.NumberOfPlanes != 1) continue;
374  if (modeInfo.XResolution != x) continue;
375  if (modeInfo.YResolution != y) continue;
376 
377  bytesperline = modeInfo.BytesPerScanLine;
378  maxpages = min(modeInfo.NumberOfImagePages+1,64);
379 
380  regs.x.ax = 0x4f02;
381  regs.x.bx = validmode[k] | ((modeInfo.ModeAttributes&128)<<7);
382  DPMI_int86(0x10,&regs,&regs);
383 
384  if (modeInfo.ModeAttributes&32) vgacompatible = 0;
385  else vgacompatible = 1;
386 
387  regs.x.ax = 0x4f0a; regs.x.bx = 0;
388  DPMI_int86x(0x10,&regs,&regs,&sregs);
389  if (regs.x.ax == 0x004f) //cx is length of protected mode code
390  {
391  i = (((long)sregs.es)<<4)+((long)regs.x.di);
392  p1 = (short *)i;
393  setactiveentry = ((long)p1[0]) + i;
394  setvisualentry = ((long)p1[1]) + i;
395  setpaletteentry = ((long)p1[2]) + i;
396  //p1[2] is useless palette function - see vesprot.asm for code
397  }
398 
399  //Linear mode
400  if (modeInfo.ModeAttributes&128) //128 is vbeMdLinear
401  {
402  GetPtrToLFB(modeInfo.PhysBasePtr);
403 
404  linearmode = 1;
405  buffermode = (maxpages<=1);
406  imageSize = bytesperline*yres;
407  if (!buffermode) frameplace = globlinplace;
408  else frameplace = FP_OFF(screen);
409  j = 0;
410  for(i=0;i<maxpages;i++)
411  {
412  activepagelookup[i] = globlinplace+j;
413  j += imageSize;
414  }
415  }
416  else //Banked mode
417  {
418  //Get granularity
419  switch(modeInfo.WinGranularity)
420  {
421  case 64: davesapageshift = 0; break;
422  case 32: davesapageshift = 1; break;
423  case 16: davesapageshift = 2; break;
424  case 8: davesapageshift = 3; break;
425  case 4: davesapageshift = 4; break;
426  case 2: davesapageshift = 5; break;
427  case 1: davesapageshift = 6; break;
428  }
429 
430  linearmode = 0;
431  if ((x == 320) && (y == 200) && (maxpages >= 2))
432  {
433  buffermode = 0;
434  imageSize = 65536;
435  frameplace = 0xa0000;
436  }
437  else
438  {
439  buffermode = 1;
440  imageSize = bytesperline*yres;
441  frameplace = FP_OFF(screen);
442  maxpages = 1;
443  }
444  }
445 
446  origbuffermode = buffermode;
447 
448  j = 0;
449  for(i=0;i<maxpages;i++)
450  {
451  dived = div(j,bytesperline);
452  visualpagelookup[i][0] = (short)dived.rem;
453  visualpagelookup[i][1] = (short)dived.quot;
454  j += imageSize;
455  }
456  return(0);
457  }
458  return(-1);
459 }
460 
461 long setdacbits(long newdacbits)
462 {
463  RMREGS regs;
464 
465  if ((vgaInfo.Capabilities&1) == 0) return(6L);
466  regs.x.ax = 0x4f08;
467  regs.x.bx = (((long)newdacbits)<<8);
468  DPMI_int86(0x10,&regs,&regs);
469  return((long)regs.h.bh);
470 }
471 
472 #define setvesapage(i) \
473 { \
474  if (setactiveentry) \
475  vesasetactive(0x4f05,0L,0L,i); \
476  else \
477  { \
478  regs.x.ax = 0x4f05; regs.x.bx = 0; regs.x.dx = i; \
479  DPMI_int86(0x10,&regs,&regs); \
480  } \
481 }
482 
483 void setactivepage(long dapagenum)
484 {
485  RMREGS regs;
486 
487  if ((origbuffermode == 0) && (linearmode == 0))
488  {
489  frameplace = 0xa0000;
490  setvesapage(dapagenum<<davesapageshift);
491  }
492  if (buffermode != 0) { frameplace = FP_OFF(screen); return; }
493  if (linearmode != 0) { frameplace = activepagelookup[dapagenum]; return; }
494 }
495 
496 static long curpag = 0;
497 void setvisualpage(long dapagenum)
498 {
499  RMREGS regs;
500  long i, /*j,*/ p, dx, cx1, cy1, cx2, cy2, delta, x, y, y1, y2, ny1, ny2;
501 
502  if (buffermode != 0)
503  {
504  cx1 = windowx1; cy1 = windowy1; cx2 = windowx2; cy2 = windowy2;
505  if (permanentupdate) { cx1 = 0; cy1 = 0; cx2 = xdim-1; cy2 = ydim-1; }
506  dx = cx2-cx1+1;
507  if (linearmode)
508  {
509  p = FP_OFF(screen);
510  delta = activepagelookup[dapagenum&0x7fffffff]-FP_OFF(screen);
511  if (permanentupdate == 0)
512  {
513  y1 = startumost[cx1]; y2 = y1;
514  for(x=cx1;x<=cx2;x++)
515  {
516  ny1 = startumost[x]-1; ny2 = startdmost[x];
517  if (ny1 < ny2-1)
518  {
519  if (ny1 >= y2)
520  {
521  while (y1 < y2-1)
522  {
523  y1++; if ((y1&31) == 0) faketimerhandler();
524  //x,y1
525  i = p+ylookup[y1]+ves2lastx[y1];
526  copybufbyte((void *)i,(void *)(i+delta),x-ves2lastx[y1]);
527  }
528  y1 = ny1;
529  }
530  else
531  {
532  while (y1 < ny1)
533  {
534  y1++; if ((y1&31) == 0) faketimerhandler();
535  //x-1,y1
536  i = p+ylookup[y1]+ves2lastx[y1];
537  copybufbyte((void *)i,(void *)(i+delta),x-ves2lastx[y1]);
538  }
539  while (y1 > ny1) ves2lastx[y1--] = x;
540  }
541  while (y2 > ny2)
542  {
543  y2--; if ((y2&31) == 0) faketimerhandler();
544  //x-1,y2
545  i = p+ylookup[y2]+ves2lastx[y2];
546  copybufbyte((void *)i,(void *)(i+delta),x-ves2lastx[y2]);
547  }
548  while (y2 < ny2) ves2lastx[y2++] = x;
549  }
550  else
551  {
552  while (y1 < y2-1)
553  {
554  y1++; if ((y1&31) == 0) faketimerhandler();
555  //x-1,y1
556  i = p+ylookup[y1]+ves2lastx[y1];
557  copybufbyte((void *)i,(void *)(i+delta),x-ves2lastx[y1]);
558  }
559  if (x == cx2) break;
560  y1 = startumost[x+1]; y2 = y1;
561  }
562  }
563  while (y1 < y2-1)
564  {
565  y1++; if ((y1&31) == 0) faketimerhandler();
566  //cx2+1,y1
567  i = p+ylookup[y1]+ves2lastx[y1];
568  copybufbyte((void *)i,(void *)(i+delta),cx2+1-ves2lastx[y1]);
569  }
570  }
571  else
572  {
573  p += ylookup[cy1]+cx1;
574  delta = activepagelookup[dapagenum&0x7fffffff]-FP_OFF(screen);
575  for(y=cy1;y<=cy2;y++)
576  {
577  copybufbyte((void *)p,(void *)(p+delta),dx);
578  p += ylookup[1];
579  if ((y&31) == 0) faketimerhandler();
580  }
581  }
582  }
583  else
584  {
585  p = ylookup[cy1]+cx1;
586  for(y=cy1;y<=cy2;y++)
587  {
588  if ((p>>16) != curpag)
589  {
590  curpag = (p>>16);
591 
592  setvesapage(curpag<<davesapageshift);
593  faketimerhandler();
594  }
595 
596  i = (p&65535)+dx-65536;
597  if (i <= 0)
598  copybufbyte((void *)(p+FP_OFF(screen)),(void *)((p&65535)+0xa0000),dx);
599  else
600  {
601  copybufbyte((void *)(p+FP_OFF(screen)),(void *)(0xb0000-(dx-i)),dx-i);
602 
603  curpag = ((p+dx-1)>>16);
604  setvesapage(curpag<<davesapageshift);
605  faketimerhandler();
606 
607  copybufbyte((void *)(p+(dx-i)+FP_OFF(screen)),(void *)0xa0000,i);
608  }
609  p += ylookup[1];
610  }
611  }
612  permanentupdate = 0;
613  }
614  if (origbuffermode == 0)
615  {
616  if (setvisualentry)
617  {
618  i = imageSize*(dapagenum&0x7fffffff);
619  if (vgacompatible)
620  {
621  if (dapagenum >= 0) qlimitrate();
622  vesasetvisual(0x4f07,0L,i>>2,i>>18);
623  }
624  else
625  { vesasetvisual(0x4f07,0x80,i>>2,i>>18); }
626 
627  }
628  else
629  {
630  regs.x.ax = 0x4f07;
631  regs.x.cx = visualpagelookup[dapagenum&0x7fffffff][0]; //X-coordinate
632  regs.x.dx = visualpagelookup[dapagenum&0x7fffffff][1]; //Y-coordinate
633  if (vgacompatible)
634  {
635  regs.x.bx = 0;
636  if (dapagenum >= 0) qlimitrate();
637  DPMI_int86(0x10,&regs,&regs);
638  }
639  else
640  { regs.x.bx = 0x80; DPMI_int86(0x10,&regs,&regs); }
641  }
642  if (dapagenum >= 0) faketimerhandler();
643  }
644 }
645 
646 void uninitvesa(void)
647 {
648  if (backlinaddress)
649  {
650  union REGS r;
651  r.w.ax = 0x801;
652  r.w.bx = (backlinaddress >> 16);
653  r.w.cx = (backlinaddress & 0xffff);
654  backupsegs(); int386(0x31,&r,&r); restoresegs();
655  if (r.x.cflag) { printf("Free Physical Address failed!\n"); }
656  backlinaddress = 0;
657  }
658  VESABuf_sel = 0;
659  vesachecked = 0;
660 }
661 
662 #if 0 // doesn't appear to be used anymore. --ryan.
663 #pragma aux setpalettequick =\
664  "mov edx, 0x3c8",\
665  "out dx, al",\
666  "inc edx",\
667  "lea ecx, [ecx+ecx*2]",\
668  "cld",\
669  "rep outsb",\
670  parm [eax][ecx][esi]\
671  modify exact [ecx edx esi]
672 #endif
673 
674 int VBE_setPalette(long start, long num, char *dapal)
675 {
676  RMREGS regs;
677  long i, j, k;
678  char palquick[768];
679 
680  if (stereomode == 1)
681  {
682  if ((unsigned)((blackband&255)-start) < (unsigned)num)
683  {
684  dapal[(((blackband&255)-start)<<2)+0] = 0;
685  dapal[(((blackband&255)-start)<<2)+1] = 0;
686  dapal[(((blackband&255)-start)<<2)+2] = 0;
687  }
688  if ((unsigned)((whiteband&255)-start) < (unsigned)num)
689  {
690  dapal[(((whiteband&255)-start)<<2)+0] = 255;
691  dapal[(((whiteband&255)-start)<<2)+1] = 255;
692  dapal[(((whiteband&255)-start)<<2)+2] = 255;
693  }
694  }
695  if ((vgacompatible) || (vgaInfo.VESAVersion < 0x200) || (vidoption != 1))
696  {
697  j = 0; k = (start<<2);
698  for(i=0;i<num;i++)
699  {
700  palquick[j] = dapal[k+2];
701  palquick[j+1] = dapal[k+1];
702  palquick[j+2] = dapal[k];
703  j += 3; k += 4;
704  }
705  //setpalettequick(start,num,palquick);
706  koutp(0x3c8,start);
707  for(i=(num>>1);i>0;i--)
708  {
709  koutp(0x3c9,(long) dapal[2]);
710  while (kinp(0x3da)&1); while (!(kinp(0x3da)&1));
711  koutp(0x3c9,(long) dapal[1]); koutp(0x3c9,(long) dapal[0]);
712  koutp(0x3c9,(long) dapal[6]); koutp(0x3c9,(long) dapal[5]); koutp(0x3c9,(long) dapal[4]);
713  dapal += 8;
714  }
715  if (num&1)
716  {
717  koutp(0x3c9,(long) dapal[2]);
718  while (kinp(0x3da)&1); while (!(kinp(0x3da)&1));
719  koutp(0x3c9,(long) dapal[1]); koutp(0x3c9,(long) dapal[0]);
720  }
721  return(1);
722  }
723 
724  if (setpaletteentry)
725  {
726  i = (vesasetpalette(0x4f09,(vgaInfo.Capabilities&4)<<5,
727  num,start,0L,dapal)&65535);
728  }
729  else
730  {
731  regs.x.ax = 0x4f09; regs.h.bl = ((vgaInfo.Capabilities&4)<<5);
732  regs.x.cx = num; regs.x.dx = start;
733  VBE_callESDI(&regs,dapal,sizeof(dapal)*num);
734  i = regs.x.ax;
735  }
736  if (i != 0x004f) return(0);
737  return(1);
738 }
739 
740 VBE_getPalette(long start, long num, char *dapal)
741 {
742  RMREGS regs;
743  long i;
744 
745  if ((vgacompatible) || (vgaInfo.VESAVersion < 0x200) || (vidoption != 1))
746  {
747  koutp(0x3c7,start);
748  for(i=num;i>0;i--)
749  {
750  dapal[2] = (char) kinp(0x3c9);
751  dapal[1] = (char) kinp(0x3c9);
752  dapal[0] = (char) kinp(0x3c9);
753  dapal += 4;
754  }
755  return(1);
756  }
757 
758  regs.x.ax = 0x4f09; regs.h.bl = 1;
759  regs.x.cx = num; regs.x.dx = start;
760  VBE_callESDI(&regs,dapal,sizeof(dapal)*num);
761  i = regs.x.ax;
762  if (i != 0x004f) return(0);
763  return(1);
764 }
765 
766 #endif // _INCLUDE_VES2_H_
767 
768 // end of ves2.h ...
769 
770