![]()
|
typedef struct VBE_VgaInfo
{ char VESASignature[4];
short VESAVersion;
char *OemStringPtr;
ulong Capabilities;
ulong VideoModePtr;
short TotalMemory;
//VBE 2.0
short OemSoftwareRev;
char *OemVendorNamePtr;
char *OemProductNamePtr;
char *OemProductRevPtr;
char reserved[222];
char OemData[256];
};
|
VBE_VgaInfo vesainfo;
long VESAVerMaj,VESAVerMin;
int Video::Detect_VESA()
{__dpmi_regs r;
strncpy(vesainfo.VESASignature,"VESA",4); //or VBE2
r.x.ax=0x4F00;
r.x.di=__tb&0x0f;
r.x.es=(__tb >>4)&0xFFFF;
dosmemput(&vesainfo,sizeof(vesainfo),__tb);
__dpmi_int(0x10,&r);
dosmemget(__tb,sizeof(vesainfo),&vesainfo);
if(r.h.ah||strncmp("VESA",vesainfo.VESASignature,4)||vesainfo.VESAVersion <0x100)
{ return 0; //VESA NOT present
}
VESAVerMaj=vesainfo.VESAVersion >>8;
VESAVerMin=vesainfo.VESAVersion & 0x0f;
if(VESAVerMaj > 2.0)
{GetPMInterface();
Bankptr = &Video::SetBankAlt;
}
else
{Bankptr = &Video::SetBankBIOS;
}
return 1;
}
|
void Video::PrintVESAInfo()
{ char buffer[255];
short modes[255];
long temp;
short t;
cout<<"VESA "<<VESAVerMaj<<"."<<VESAVerMin<<endl;
cout<<"Video Memory: "<<dec<<(long)(vesainfo.TotalMemory*64)<<"k"<<endl;
temp=vesainfo.OemStringPtr;
t = __dpmi_segment_to_descriptor((temp>>16));
movedata(t,(temp&0xFFFF),_my_ds(),(int)&buffer,255);
cout<<buffer<<endl;
temp=vesainfo.OemVendorNamePtr;
t = __dpmi_segment_to_descriptor(temp>>16);
movedata(t,(temp&0xFFFF),_my_ds(),(int)&buffer,255);
cout<<buffer<<endl;
temp=vesainfo.OemProductNamePtr;
t = __dpmi_segment_to_descriptor(temp>>16);
movedata(t,(temp&0xFFFF),_my_ds(),(int)&buffer,255);
cout<<buffer<<endl;
temp=vesainfo.OemProductRevPtr;
t = __dpmi_segment_to_descriptor(temp>>16);
movedata(t,(temp&0xFFFF),_my_ds(),(int)&buffer,255);
cout<<buffer<<endl;
} |
typedef struct VBE_ModeInfo
{short ModeAttributes;
char WinAAttributes;
char WinBAttributes;
short WinGranularity;
short WinSize;
ushort WinASegment;
ushort WinBSegment;
void *WinFuncPtr;
short BytesPerScanLine;
short XRes;
short YRes;
char XCharSize;
char YCharSize;
char NumberOfPlanes;
char BitsPerPixel;
char NumberOfBanks;
char MemoryModel;
char BankSize;
char NumberOfImagePages;
char res1;
char RedMaskSize;
char RedFieldPosition;
char GreenMaskSize;
char GreenFieldPosition;
char BlueMaskSize;
char BlueFieldPosition;
char RsvedMaskSize;
char RsvedFieldPosition;
//VBE 2.0
ulong PhysBasePtr;
ulong OffScreenMemOffset;
short OffScreenMemSize;
//VBE 2.1
short LinbytesPerScanLine;
char BankNumberOfImagePages;
char LinNumberOfImagePages;
char LinRedMaskSize;
char LinRedFieldPosition;
char LingreenMaskSize;
char LinGreenFieldPosition;
char LinBlueMaskSize;
char LinBlueFieldPosition;
char LinRsvdMaskSize;
char LinRsvdFieldPosition;
char res2[194];
};
VBE_ModeInfo modeinfo;
|
int Video::GetVESAModeInfo(short mode)
{__dpmi_regs r;
r.x.ax=0x4F01;
r.x.cx=mode;
r.x.di=__tb & 0x0F;
r.x.es=(__tb >>4)&0xFFFF;
__dpmi_int(0x10,&r);
dosmemget(__tb,sizeof(modeinfo),&modeinfo);
if(r.h.ah)
{return 0; //failure!
}
return 1;
} |
void Video::GetAvailableVESAModes()
{ long temp;
short t,*m,count=0;
temp=vesainfo.VideoModePtr;
m=(short *)MK_FP(temp>>16,temp&0xFFFF);
while(m[count] != -1)
{ count++;
}
NumberOfModes = count;
cout<<NumberOfModes<<" Video Modes Available\n";
Modes = new short[NumberOfModes];
if(Modes ==NULL)
{ cout<<"Error allocating Mode Number Listing!\n";
}
for(temp=0;temp<NumberOfModes;temp++)
{ Modes[temp]=m[temp];
}
ModeList = new VBE_ModeInfo[NumberOfModes];
if(ModeList == NULL)
{ cout<<"Error allocating ModeList!\n"; }
for(count=0;count<NumberOfModes;count++)
{GetVESAModeInfo(Modes[count]);
memmove(&ModeList[count],&modeinfo,sizeof(VBE_ModeInfo));
}
}
void * Video::MK_FP(unsigned short seg, unsigned short ofs)
{if(!(_crt0_startup_flags & _CRT0_FLAG_NEARPTR))
if(!__djgpp_nearptr_enable())
return (void*)0;
return (void *)(seg*16+ofs+__djgpp_conventional_base);
}
|
unsigned short Video::GetModeIndex(short Xres,short Yres,short Depth)
{ unsigned short temp=666;
for(short count=0;count<NumberOfModes;count++)
{ if((ModeList[count].XRes == Xres) &&
(ModeList[count].YRes == Yres) &&
(ModeList[count].BitsPerPixel == Depth))
{ temp=count;
}
}
return temp;
}
void Video::VESAMode(short index)
{ __dpmi_regs r;
memset(&r,0,sizeof(__dpmi_regs));
r.x.ax=0x4F02;
r.x.bx=Modes[index];
UsingLinearFrameBuffer(index);
if(LinearFrameBuffer)
{r.x.bx+=0x4000; //bit 14 0100 0000 0000 0000
}
if(!ClearMem)
{r.x.bx+=0x8000; //bit 15 1000 0000 0000 0000
}
__dpmi_int(0x10,&r);
if(r.x.ax !=0x004f)
{VideoMode(80,25,8);
cout<<"Failure to set VESA video mode "<<hex<<Modes[index]<<endl;
sleep(4);
RevertToSavedModeData();
VideoMode(Screen_Width,Screen_Height,Screen_BitsPerPixel);
}
VideoModeIndex=index;
CurrentVideoMode=Modes[VideoModeIndex];
Screen_Width = ModeList[VideoModeIndex].XRes;
Screen_Height = ModeList[VideoModeIndex].YRes;
Screen_Size = Screen_Width*Screen_Height;
XCenter = (Screen_Width>>1);
YCenter = (Screen_Height>>1);
//Only used when no LFB is present
NumberOfBanks=Screen_Size>>16;
MemAfterBanks=Screen_Size&65535;
if(LinearFrameBuffer)
{MapLFB(index);
Move2Vid=&Video::MoveMemStandard;
}
else
{Move2Vid = &Video::MoveMemVESABanked;
}
SaveModeData(); //success so save!
cout<<"Current mode = "<<CurrentVideoMode<<endl;
}
|
void Video::UsingLinearFrameBuffer(short index)
{ if(ModeList[index].ModeAttributes & 0x80)
{LinearFrameBuffer = 1;
cout<<hex<<Modes[index]<<"h uses a LFB"<<dec<<endl;
}
else
{LinearFrameBuffer = 0;
}
}
void Video::SaveModeData()
{savedmode = CurrentVideoMode;
savedxres = Screen_Width;
savedyres = Screen_Height;
saveddepth= Screen_BitsPerPixel;
savedindex= VideoModeIndex;
}
void Video::RevertToSavedModeData()
{CurrentVideoMode = savedmode;
Screen_Width = savedxres;
Screen_Height = savedyres;
Screen_BitsPerPixel= saveddepth;
VideoModeIndex = savedindex;
}
|
In Class constructor
my_video_ds=__dpmi_allocate_ldt_descriptors(1);
__dpmi_set_segment_base_address(my_video_ds,0xA000+__djgpp_conventional_base);
__dpmi_set_segment_limit(my_video_ds,2000000);
void Video::MapLFB(short index)
{ __dpmi_meminfo info;
info.size=vesainfo.TotalMemory<<16;
cout<<"Mapping "<<info.size<<" bytes for Linear Frame Buffer"<<endl;
info.address=(unsigned long)ModeList[index].PhysBasePtr;
cout<<"Pointer to LFB = "<<hex<<ModeList[index].PhysBasePtr<<"h"<<dec<<endl;
if(__dpmi_physical_address_mapping(&info)!=0)
{ cout<<"Can't map Linear Frame Buffer!\n";
}
__dpmi_free_ldt_descriptor(my_video_ds); //allocated in constructor so erase
my_video_ds=__dpmi_allocate_ldt_descriptors(1);
__dpmi_set_segment_base_address(my_video_ds,info.address);
__dpmi_set_segment_limit(my_video_ds,info.size-1);
cout<<"Base address = "<<hex<<info.address<<dec<<endl;
video_screen=(unsigned char *)((unsigned long)info.address+__djgpp_conventional_base);
} |
typedef struct PM_Int
{ unsigned short SetWindow Packed;
unsigned short SetDisplayStart Packed;
unsigned short SetPalette Packed;
unsigned short IOPrivInfo Packed;
};
void (*pm_bank)(char);
void (*pm_setstart)(char);
void (*pm_setpalette)(char);
PM_Int* pm_info;
void Video::GetPMInterface()
{__dpmi_regs regs;
regs.x.ax=0x4F0A;
regs.x.bx=0;
__dpmi_int(0x10,®s);
if(regs.h.ah)
{ cout<<"\nError gaining access to VESA Protected Mode Interface!\n";
}
if(pm_info != NULL)
{ free(pm_info);
}
pm_info = (PM_Int *)malloc(regs.x.cx);
_go32_dpmi_lock_data(pm_info,regs.x.cx);
dosmemget((regs.x.es*16)+regs.x.di,regs.x.cx,pm_info);
pm_bank = (void*)((char*)pm_info+pm_info->SetWindow);
pm_setstart = (void*)((char*)pm_info+pm_info->SetDisplayStart);
pm_setpalette=(void*)((char*)pm_info+pm_info->SetPalette);
return;
} |