/* vesa.c */ #define VESA #include #include #include #include #include "vidlib.h" #include "vesa.h" int VESAmode(unsigned int mode, char *palette) { _AX=0x4f02; _BX=mode; geninterrupt(0x10); if ( _AH == 0 ) { if (palette != NULL) /* if not NULL */ if (palette == DEFAULTDAC) /* restore defaults */ WriteDACs(_olddacs); else WriteDACs(palette); getVESAinfo(mode); _screen_start=(char far *)0xA0000000L; _screen_width=Vminfo.bytesperline; VESAsetpage(0); return(1); } else return(0); } int isVESA(void) { union REGS regs; struct SREGS sregs; regs.x.ax = 0x4F00; /* VESA BIOS call */ sregs.es = FP_SEG(&Vinfo); /* Place address into parm list */ regs.x.di= FP_OFF(&Vinfo); int86x(0x10, ®s, ®s, &sregs); /* Try VESA BIOS */ /* Check status and signature */ if ((regs.x.ax != 0x004F) || (strncmp(Vinfo.signature,"VESA",4) != 0) ) { return(0); } return(1); } /* returns 1 for a valid mode, 0 if not */ int isVESAmode(int mode) { struct REGS r; struct SREGS s; r.h.ah=0x4f; r.h.al=0; s.es=FP_SEG(&Vinfo); r.x.di=FP_OFF(&Vinfo); int86x(0x10,&r,&r,&s); if (r.x.ax != 0x004f) { return(0); } if (strncmp(Vinfo.signature,"VESA",4) == 0) { while ((*(Vinfo.modeptr) != 0xFFFF) && (*(Vinfo.modeptr) != mode) ) Vinfo.modeptr++; if (*Vinfo.modeptr == mode) { return(1); } else { return(0); } } else { return(0); } } struct vesainfo *getVESAinfo(int mode) { struct REGS r; struct SREGS s; r.h.ah=0x4f; r.h.al=0x01; r.x.cx=mode; s.es=FP_SEG(&Vminfo); r.x.di=FP_OFF(&Vminfo); int86x(0x10,&r,&r,&s); if ( r.x.ax == 0x004F ) { return(&Vinfo); } else { return(NULL); } } int VESAsetpage(unsigned page) /* assume window 0 */ { _AH=0x4F; _AL=5; _BH=0; _BL=0; _DX=page; geninterrupt(0x10); if (_AH == 0) { vesapage=page; VESAnext_break(); return(page); } else { return(0); } } int VESAsetpagew(char window, unsigned page) { _BH=0; _BL=window; _DX=page; (*Vminfo.Windowsetptr)(); vesapage=page; VESAnext_break(); return(1); } int VESAsetpagewbios(char window, unsigned page) { struct REGS r; r.h.ah=0x4f; r.h.al=5; r.h.bh=0; r.h.bl=window; r.x.dx=page; int86(0x10,&r,&r); vesapage=page; VESAnext_break(); return(!r.h.ah); } void VESAnext_break(void) { long ao, ws; ws=(long)Vminfo.size<<10; ao=(long)(vesapage * ws + ws); /* = first byte of next page */ Vnext_break=(unsigned int)(ao/(long)Vminfo.bytesperline); Vnext_break_offset=(unsigned int)((ao-1L) % Vminfo.bytesperline); } int VESAfirst_page(int scan, int offset) { long ao, ws; ws=(long)Vminfo.size<<10; ao=( (long)scan * (long)Vminfo.bytesperline) + offset; return((int)(ao/ws)); }