6 #ifndef _INCLUDE_VES2_H_
7 #define _INCLUDE_VES2_H_
9 #if (!defined PLATFORM_DOS)
10 #error Do not include this file. It is for the DOS target only.
26 char VESASignature[4];
28 long OemStringPtr, Capabilities, VideoModePtr;
29 short TotalMemory, OemSoftwareRev;
30 long OemVendorNamePtr, OemProductNamePtr, OemProductRevPtr;
31 char reserved[222], OemDATA[256];
37 char WinAAtributes, WinBAttributes;
38 short WinGranularity, WinSize, WinASegment, WinBSegment;
40 short BytesPerScanLine, XResolution, YResolution;
41 char XCharSize, YCharSize, NumberOfPlanes, BitsPerPixel;
42 char NumberOfBanks, MemoryModel, BankSize, NumberOfImagePages;
44 char RedMaskSize, RedFieldPosition;
45 char GreenMaskSize, GreenFieldPosition;
46 char BlueMaskSize, BlueFieldPosition;
47 char RsvdMaskSize, RsvdFieldPosition, DirectColorModeInfo;
48 long PhysBasePtr, OffScreenMemOffset;
49 short OffScreenMemSize;
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; };
56 typedef struct {
unsigned short es, cs, ss, ds; }
RMSREGS;
60 long edi, esi, ebp, reserved, ebx, edx, ecx, eax;
61 short flags, es, ds, fs, gs, ip, cs, sp, ss;
66 long VESABuf_sel = 0, VESABuf_rseg;
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;
79 static long backlinaddress = 0;
81 void faketimerhandler(
void);
83 void qlimitrate(
void);
84 #pragma aux qlimitrate =\
89 modify exact [eax edx]\
91 void backupsegs(
void);
93 #pragma aux backupsegs =\
99 void restoresegs(
void);
100 #pragma aux restoresegs =\
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]\
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]\
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]\
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;
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();
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;
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;
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();
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;
219 static void ExitVBEBuf(
void)
222 r.w.ax = 0x101; r.w.dx = VESABuf_sel;
223 backupsegs(); int386(0x31,&r,&r); restoresegs();
226 void VBE_callESDI(
RMREGS *regs,
void *buffer,
long size)
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;
240 sregs.es = VESABuf_rseg;
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);
254 if (regs.x.ax != 0x004f)
return(0);
255 if ((modeInfo->ModeAttributes&1) == 0)
return(0);
259 GetPtrToLFB(
long physAddr)
261 #define LIMIT (4096*1024)-1
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); }
269 r.w.ax = 9; r.w.bx = sel; r.w.cx = 0x8092;
270 backupsegs(); int386(0x31,&r,&r); restoresegs();
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;
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); }
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); }
289 void getvalidvesamodes(
void)
296 if (vesachecked)
return;
302 strncpy(vgaInfo.VESASignature,
"VBE2",4);
305 if ((regs.x.ax != 0x004f) || (strncmp(vgaInfo.VESASignature,
"VESA",4)))
311 p = (
short *)(((vgaInfo.VideoModePtr&0xffff0000)>>12)+((vgaInfo.VideoModePtr)&0xffff));
313 while (*p != -1) *p2++ = *p++;
316 for(p=modelist;*p!=-1;p++)
318 regs.x.ax = 0x4f01; regs.x.cx = *p;
320 if (regs.x.ax != 0x004f)
continue;
321 if (!(modeInfo.ModeAttributes&1))
continue;
322 if (modeInfo.MemoryModel != 4)
continue;
323 if (modeInfo.BitsPerPixel != 8)
continue;
324 if (modeInfo.NumberOfPlanes != 1)
continue;
326 validmode[validmodecnt] = *p;
327 validmodexdim[validmodecnt] = modeInfo.XResolution;
328 validmodeydim[validmodecnt] = modeInfo.YResolution;
332 for(i=1;i<validmodecnt;i++)
334 if (validmodeydim[i] < validmodeydim[j])
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;
341 for(i=1;i<validmodecnt;i++)
343 if (validmodexdim[i] < validmodexdim[j])
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;
351 int setvesa(
long x,
long y)
364 for(k=0;k<validmodecnt;k++)
366 regs.x.ax = 0x4f01; regs.x.cx = validmode[k];
368 if (regs.x.ax != 0x004f)
continue;
369 if (!(modeInfo.ModeAttributes&1))
continue;
371 if (modeInfo.MemoryModel != 4)
continue;
372 if (modeInfo.BitsPerPixel != 8)
continue;
373 if (modeInfo.NumberOfPlanes != 1)
continue;
374 if (modeInfo.XResolution != x)
continue;
375 if (modeInfo.YResolution != y)
continue;
377 bytesperline = modeInfo.BytesPerScanLine;
378 maxpages = min(modeInfo.NumberOfImagePages+1,64);
381 regs.x.bx = validmode[k] | ((modeInfo.ModeAttributes&128)<<7);
382 DPMI_int86(0x10,®s,®s);
384 if (modeInfo.ModeAttributes&32) vgacompatible = 0;
385 else vgacompatible = 1;
387 regs.x.ax = 0x4f0a; regs.x.bx = 0;
388 DPMI_int86x(0x10,®s,®s,&sregs);
389 if (regs.x.ax == 0x004f)
391 i = (((long)sregs.es)<<4)+((
long)regs.x.di);
393 setactiveentry = ((long)p1[0]) + i;
394 setvisualentry = ((long)p1[1]) + i;
395 setpaletteentry = ((long)p1[2]) + i;
400 if (modeInfo.ModeAttributes&128)
402 GetPtrToLFB(modeInfo.PhysBasePtr);
405 buffermode = (maxpages<=1);
406 imageSize = bytesperline*yres;
407 if (!buffermode) frameplace = globlinplace;
408 else frameplace = FP_OFF(screen);
410 for(i=0;i<maxpages;i++)
412 activepagelookup[i] = globlinplace+j;
419 switch(modeInfo.WinGranularity)
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;
431 if ((x == 320) && (y == 200) && (maxpages >= 2))
435 frameplace = 0xa0000;
440 imageSize = bytesperline*yres;
441 frameplace = FP_OFF(screen);
446 origbuffermode = buffermode;
449 for(i=0;i<maxpages;i++)
451 dived = div(j,bytesperline);
452 visualpagelookup[i][0] = (short)dived.rem;
453 visualpagelookup[i][1] = (
short)dived.quot;
461 long setdacbits(
long newdacbits)
465 if ((vgaInfo.Capabilities&1) == 0)
return(6L);
467 regs.x.bx = (((long)newdacbits)<<8);
468 DPMI_int86(0x10,®s,®s);
469 return((
long)regs.h.bh);
472 #define setvesapage(i) \
474 if (setactiveentry) \
475 vesasetactive(0x4f05,0L,0L,i); \
478 regs.x.ax = 0x4f05; regs.x.bx = 0; regs.x.dx = i; \
479 DPMI_int86(0x10,®s,®s); \
483 void setactivepage(
long dapagenum)
487 if ((origbuffermode == 0) && (linearmode == 0))
489 frameplace = 0xa0000;
490 setvesapage(dapagenum<<davesapageshift);
492 if (buffermode != 0) { frameplace = FP_OFF(screen);
return; }
493 if (linearmode != 0) { frameplace = activepagelookup[dapagenum];
return; }
496 static long curpag = 0;
497 void setvisualpage(
long dapagenum)
500 long i, p, dx, cx1, cy1, cx2, cy2, delta, x, y, y1, y2, ny1, ny2;
504 cx1 = windowx1; cy1 = windowy1; cx2 = windowx2; cy2 = windowy2;
505 if (permanentupdate) { cx1 = 0; cy1 = 0; cx2 = xdim-1; cy2 = ydim-1; }
510 delta = activepagelookup[dapagenum&0x7fffffff]-FP_OFF(screen);
511 if (permanentupdate == 0)
513 y1 = startumost[cx1]; y2 = y1;
514 for(x=cx1;x<=cx2;x++)
516 ny1 = startumost[x]-1; ny2 = startdmost[x];
523 y1++;
if ((y1&31) == 0) faketimerhandler();
525 i = p+ylookup[y1]+ves2lastx[y1];
526 copybufbyte((
void *)i,(
void *)(i+delta),x-ves2lastx[y1]);
534 y1++;
if ((y1&31) == 0) faketimerhandler();
536 i = p+ylookup[y1]+ves2lastx[y1];
537 copybufbyte((
void *)i,(
void *)(i+delta),x-ves2lastx[y1]);
539 while (y1 > ny1) ves2lastx[y1--] = x;
543 y2--;
if ((y2&31) == 0) faketimerhandler();
545 i = p+ylookup[y2]+ves2lastx[y2];
546 copybufbyte((
void *)i,(
void *)(i+delta),x-ves2lastx[y2]);
548 while (y2 < ny2) ves2lastx[y2++] = x;
554 y1++;
if ((y1&31) == 0) faketimerhandler();
556 i = p+ylookup[y1]+ves2lastx[y1];
557 copybufbyte((
void *)i,(
void *)(i+delta),x-ves2lastx[y1]);
560 y1 = startumost[x+1]; y2 = y1;
565 y1++;
if ((y1&31) == 0) faketimerhandler();
567 i = p+ylookup[y1]+ves2lastx[y1];
568 copybufbyte((
void *)i,(
void *)(i+delta),cx2+1-ves2lastx[y1]);
573 p += ylookup[cy1]+cx1;
574 delta = activepagelookup[dapagenum&0x7fffffff]-FP_OFF(screen);
575 for(y=cy1;y<=cy2;y++)
577 copybufbyte((
void *)p,(
void *)(p+delta),dx);
579 if ((y&31) == 0) faketimerhandler();
585 p = ylookup[cy1]+cx1;
586 for(y=cy1;y<=cy2;y++)
588 if ((p>>16) != curpag)
592 setvesapage(curpag<<davesapageshift);
596 i = (p&65535)+dx-65536;
598 copybufbyte((
void *)(p+FP_OFF(screen)),(
void *)((p&65535)+0xa0000),dx);
601 copybufbyte((
void *)(p+FP_OFF(screen)),(
void *)(0xb0000-(dx-i)),dx-i);
603 curpag = ((p+dx-1)>>16);
604 setvesapage(curpag<<davesapageshift);
607 copybufbyte((
void *)(p+(dx-i)+FP_OFF(screen)),(
void *)0xa0000,i);
614 if (origbuffermode == 0)
618 i = imageSize*(dapagenum&0x7fffffff);
621 if (dapagenum >= 0) qlimitrate();
622 vesasetvisual(0x4f07,0L,i>>2,i>>18);
625 { vesasetvisual(0x4f07,0x80,i>>2,i>>18); }
631 regs.x.cx = visualpagelookup[dapagenum&0x7fffffff][0];
632 regs.x.dx = visualpagelookup[dapagenum&0x7fffffff][1];
636 if (dapagenum >= 0) qlimitrate();
637 DPMI_int86(0x10,®s,®s);
640 { regs.x.bx = 0x80; DPMI_int86(0x10,®s,®s); }
642 if (dapagenum >= 0) faketimerhandler();
646 void uninitvesa(
void)
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"); }
662 #if 0 // doesn't appear to be used anymore. --ryan.
663 #pragma aux setpalettequick =\
667 "lea ecx, [ecx+ecx*2]",\
670 parm [eax][ecx][esi]\
671 modify exact [ecx edx esi]
674 int VBE_setPalette(
long start,
long num,
char *dapal)
682 if ((
unsigned)((blackband&255)-start) < (
unsigned)num)
684 dapal[(((blackband&255)-start)<<2)+0] = 0;
685 dapal[(((blackband&255)-start)<<2)+1] = 0;
686 dapal[(((blackband&255)-start)<<2)+2] = 0;
688 if ((
unsigned)((whiteband&255)-start) < (unsigned)num)
690 dapal[(((whiteband&255)-start)<<2)+0] = 255;
691 dapal[(((whiteband&255)-start)<<2)+1] = 255;
692 dapal[(((whiteband&255)-start)<<2)+2] = 255;
695 if ((vgacompatible) || (vgaInfo.VESAVersion < 0x200) || (vidoption != 1))
697 j = 0; k = (start<<2);
700 palquick[j] = dapal[k+2];
701 palquick[j+1] = dapal[k+1];
702 palquick[j+2] = dapal[k];
707 for(i=(num>>1);i>0;i--)
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]);
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]);
726 i = (vesasetpalette(0x4f09,(vgaInfo.Capabilities&4)<<5,
727 num,start,0L,dapal)&65535);
731 regs.x.ax = 0x4f09; regs.h.bl = ((vgaInfo.Capabilities&4)<<5);
732 regs.x.cx = num; regs.x.dx = start;
733 VBE_callESDI(®s,dapal,
sizeof(dapal)*num);
736 if (i != 0x004f)
return(0);
740 VBE_getPalette(
long start,
long num,
char *dapal)
745 if ((vgacompatible) || (vgaInfo.VESAVersion < 0x200) || (vidoption != 1))
750 dapal[2] = (char) kinp(0x3c9);
751 dapal[1] = (char) kinp(0x3c9);
752 dapal[0] = (char) kinp(0x3c9);
758 regs.x.ax = 0x4f09; regs.h.bl = 1;
759 regs.x.cx = num; regs.x.dx = start;
760 VBE_callESDI(®s,dapal,
sizeof(dapal)*num);
762 if (i != 0x004f)
return(0);
766 #endif // _INCLUDE_VES2_H_