\r
// === CONSTANTS ===\r
#define FLAG_LFB 0x1\r
+#define FLAG_POPULATED 0x2\r
+#define FLAG_VALID 0x4\r
#define VESA_DEFAULT_FRAMEBUFFER (KERNEL_BASE|0xA0000)\r
-#define BLINKING_CURSOR 1\r
+#define BLINKING_CURSOR 0\r
#if BLINKING_CURSOR\r
# define VESA_CURSOR_PERIOD 1000\r
#endif\r
\r
// === PROTOTYPES ===\r
int Vesa_Install(char **Arguments);\r
-size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);\r
+ int VBE_int_GetModeList(void);\r
+size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags);\r
int Vesa_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
int Vesa_Int_SetMode(int Mode);\r
int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data);\r
int gbVesa_CursorVisible = 0;\r
// --- 2D Video Stream Handlers ---\r
tDrvUtil_Video_BufInfo gVesa_BufInfo;\r
+// --- Settings ---\r
+// int gbVesa_DisableFBCache; // Disables the main-memory framebuffer cache\r
\r
// === CODE ===\r
int Vesa_Install(char **Arguments)\r
+{\r
+ int rv;\r
+\r
+// for( int i = 0; Arguments[i]; i ++ )\r
+// {\r
+// if( strcmp(Aguments[i], "nocache") == 0 )\r
+// gbVesa_DisableFBCache = 1;\r
+// }\r
+ \r
+ gpVesa_BiosState = VM8086_Init();\r
+ \r
+ if( (rv = VBE_int_GetModeList()) )\r
+ return rv;\r
+ \r
+ #if BLINKING_CURSOR\r
+ // Create blink timer\r
+ gpVesaCursorTimer = Time_AllocateTimer( Vesa_FlipCursor, NULL );\r
+ #endif\r
+\r
+ // Install Device\r
+ giVesaDriverId = DevFS_AddDevice( &gVesa_DriverStruct );\r
+ if(giVesaDriverId == -1) return MODULE_ERR_MISC;\r
+\r
+ return MODULE_ERR_OK;\r
+}\r
+\r
+int VBE_int_GetModeList(void)\r
{\r
tVesa_CallInfo *info;\r
tFarPtr infoPtr;\r
int i;\r
\r
// Allocate Info Block\r
- gpVesa_BiosState = VM8086_Init();\r
info = VM8086_Allocate(gpVesa_BiosState, 512, &infoPtr.seg, &infoPtr.ofs);\r
// Set Requested Version\r
memcpy(info->signature, "VBE2", 4);\r
return MODULE_ERR_NOTNEEDED;\r
}\r
\r
- //Log_Debug("VESA", "info->VideoModes = %04x:%04x", info->VideoModes.seg, info->VideoModes.ofs);\r
modes = (Uint16 *) VM8086_GetPointer(gpVesa_BiosState, info->VideoModes.seg, info->VideoModes.ofs);\r
+ LOG("Virtual addres of mode list from %04x:%04x is %p",\r
+ info->VideoModes.seg, info->VideoModes.ofs, modes);\r
+// VM8086_Deallocate( gpVesa_BiosState, info );\r
\r
- // Read Modes\r
+ // Count Modes\r
for( giVesaModeCount = 0; modes[giVesaModeCount] != 0xFFFF; giVesaModeCount++ );\r
+ giVesaModeCount ++; // First text mode\r
gVesa_Modes = (tVesa_Mode *)malloc( giVesaModeCount * sizeof(tVesa_Mode) );\r
\r
- Log_Debug("VESA", "%i Modes", giVesaModeCount);\r
- \r
+ Log_Debug("VBE", "%i Modes", giVesaModeCount);\r
+\r
// Insert Text Mode\r
gVesa_Modes[0].width = 80;\r
gVesa_Modes[0].height = 25;\r
\r
for( i = 1; i < giVesaModeCount; i++ )\r
{\r
- gVesa_Modes[i].code = modes[i];\r
+ gVesa_Modes[i].code = modes[i-1];\r
}\r
-\r
-// VM8086_Deallocate( info );\r
\r
- #if BLINKING_CURSOR\r
- // Create blink timer\r
- gpVesaCursorTimer = Time_AllocateTimer( Vesa_FlipCursor, NULL );\r
+ return 0;\r
+}\r
+\r
+void VBE_int_FillMode_Int(int Index, tVesa_CallModeInfo *vbeinfo, tFarPtr *BufPtr)\r
+{\r
+ tVesa_Mode *mode = &gVesa_Modes[Index];\r
+\r
+ // Get Mode info\r
+ gpVesa_BiosState->AX = 0x4F01;\r
+ gpVesa_BiosState->CX = mode->code;\r
+ gpVesa_BiosState->ES = BufPtr->seg;\r
+ gpVesa_BiosState->DI = BufPtr->ofs;\r
+ VM8086_Int(gpVesa_BiosState, 0x10);\r
+\r
+ if( gpVesa_BiosState->AX != 0x004F ) {\r
+ Log_Error("VESA", "Getting info on mode 0x%x failed (AX=0x%x)",\r
+ mode->code, gpVesa_BiosState->AX);\r
+ return ;\r
+ }\r
+\r
+ #if 0\r
+ #define S_LOG(s, fld, fmt) LOG(" ."#fld" = "fmt, (s).fld)\r
+ LOG("vbeinfo[0x%x] = {", mode->code);\r
+ S_LOG(*vbeinfo, attributes, "0x%02x");\r
+ S_LOG(*vbeinfo, winA, "0x%02x");\r
+ S_LOG(*vbeinfo, winB, "0x%02x");\r
+ S_LOG(*vbeinfo, granularity, "0x%04x");\r
+ S_LOG(*vbeinfo, winsize, "0x%04x");\r
+ S_LOG(*vbeinfo, segmentA, "0x%04x");\r
+ S_LOG(*vbeinfo, segmentB, "0x%04x");\r
+ LOG(" .realFctPtr = %04x:%04x", vbeinfo->realFctPtr.seg, vbeinfo->realFctPtr.ofs);\r
+ S_LOG(*vbeinfo, pitch, "0x%04x");\r
+\r
+ // -- Extended\r
+ S_LOG(*vbeinfo, Xres, "%i");\r
+ S_LOG(*vbeinfo, Yres, "%i");\r
+ S_LOG(*vbeinfo, Wchar, "%i");\r
+ S_LOG(*vbeinfo, Ychar, "%i");\r
+ S_LOG(*vbeinfo, planes, "%i");\r
+ S_LOG(*vbeinfo, bpp, "%i");\r
+ S_LOG(*vbeinfo, banks, "%i");\r
+ S_LOG(*vbeinfo, memory_model, "%i");\r
+ S_LOG(*vbeinfo, bank_size, "%i");\r
+ S_LOG(*vbeinfo, image_pages, "%i");\r
+ // -- VBE 1.2+\r
+ LOG(" Red = %i bits at %i", vbeinfo->red_mask, vbeinfo->red_position );\r
+ LOG(" Green = %i bits at %i", vbeinfo->green_mask, vbeinfo->green_position);\r
+ LOG(" Blue = %i bits at %i", vbeinfo->blue_mask, vbeinfo->blue_position );\r
+ #if 0\r
+ Uint8 rsv_mask, rsv_position;\r
+ Uint8 directcolor_attributes;\r
+ #endif\r
+ // --- VBE 2.0+\r
+ S_LOG(*vbeinfo, physbase, "0x%08x");\r
+ S_LOG(*vbeinfo, offscreen_ptr, "0x%08x");\r
+ S_LOG(*vbeinfo, offscreen_size_kb, "0x%04x");\r
+ // --- VBE 3.0+\r
+ S_LOG(*vbeinfo, lfb_pitch, "0x%04x");\r
+ S_LOG(*vbeinfo, image_count_banked, "%i");\r
+ S_LOG(*vbeinfo, image_count_lfb, "%i");\r
+ LOG("}");\r
#endif\r
\r
- // Install Device\r
- giVesaDriverId = DevFS_AddDevice( &gVesa_DriverStruct );\r
- if(giVesaDriverId == -1) return MODULE_ERR_MISC;\r
+ mode->flags = FLAG_POPULATED;\r
+ if( !(vbeinfo->attributes & 1) ) {\r
+ #if DEBUG\r
+ Log_Log("VESA", "0x%x - not supported", mode->code);\r
+ #endif\r
+ mode->width = 0;\r
+ mode->height = 0;\r
+ mode->bpp = 0;\r
+ return ;\r
+ }\r
\r
- return MODULE_ERR_OK;\r
-}\r
+ // Parse Info\r
+ mode->flags |= FLAG_VALID;\r
+ if ( (vbeinfo->attributes & 0x90) == 0x90 )\r
+ {\r
+ mode->flags |= FLAG_LFB;\r
+ mode->framebuffer = vbeinfo->physbase;\r
+ mode->fbSize = vbeinfo->Yres*vbeinfo->pitch;\r
+ } else {\r
+ mode->framebuffer = 0;\r
+ mode->fbSize = 0;\r
+ }\r
+ \r
+ mode->pitch = vbeinfo->pitch;\r
+ mode->width = vbeinfo->Xres;\r
+ mode->height = vbeinfo->Yres;\r
+ mode->bpp = vbeinfo->bpp;\r
+ \r
+ #if DEBUG\r
+ Log_Log("VESA", "#%i 0x%x - %ix%ix%i (%x)",\r
+ Index, mode->code, mode->width, mode->height, mode->bpp, mode->flags);\r
+ #endif\r
+\r
+} \r
\r
void Vesa_int_FillModeList(void)\r
{\r
tVesa_CallModeInfo *modeinfo;\r
tFarPtr modeinfoPtr;\r
\r
- modeinfo = VM8086_Allocate(gpVesa_BiosState, 512, &modeinfoPtr.seg, &modeinfoPtr.ofs);\r
+ modeinfo = VM8086_Allocate(gpVesa_BiosState, 256, &modeinfoPtr.seg, &modeinfoPtr.ofs);\r
for( i = 1; i < giVesaModeCount; i ++ )\r
{\r
- // Get Mode info\r
- gpVesa_BiosState->AX = 0x4F01;\r
- gpVesa_BiosState->CX = gVesa_Modes[i].code;\r
- gpVesa_BiosState->ES = modeinfoPtr.seg;\r
- gpVesa_BiosState->DI = modeinfoPtr.ofs;\r
- VM8086_Int(gpVesa_BiosState, 0x10);\r
- \r
- // Parse Info\r
- gVesa_Modes[i].flags = 0;\r
- if ( (modeinfo->attributes & 0x90) == 0x90 )\r
- {\r
- gVesa_Modes[i].flags |= FLAG_LFB;\r
- gVesa_Modes[i].framebuffer = modeinfo->physbase;\r
- gVesa_Modes[i].fbSize = modeinfo->Yres*modeinfo->pitch;\r
- } else {\r
- gVesa_Modes[i].framebuffer = 0;\r
- gVesa_Modes[i].fbSize = 0;\r
- }\r
- \r
- gVesa_Modes[i].pitch = modeinfo->pitch;\r
- gVesa_Modes[i].width = modeinfo->Xres;\r
- gVesa_Modes[i].height = modeinfo->Yres;\r
- gVesa_Modes[i].bpp = modeinfo->bpp;\r
- \r
- #if DEBUG\r
- Log_Log("VESA", "0x%x - %ix%ix%i",\r
- gVesa_Modes[i].code, gVesa_Modes[i].width, gVesa_Modes[i].height, gVesa_Modes[i].bpp);\r
- #endif\r
- }\r
- \r
-// VM8086_Deallocate( modeinfo );\r
+ VBE_int_FillMode_Int(i, modeinfo, &modeinfoPtr);\r
+ } \r
+// VM8086_Deallocate( gpVesa_BiosState, modeinfo );\r
\r
gbVesaModesChecked = 1;\r
}\r
/**\r
* \brief Write to the framebuffer\r
*/\r
-size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)\r
+size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)\r
{\r
if( gVesa_Modes[giVesaCurrentMode].framebuffer == 0 ) {\r
Log_Warning("VESA", "Vesa_Write - Non-LFB Modes not yet supported.");\r
int Vesa_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
{\r
int ret;\r
- //Log_Debug("VESA", "Vesa_Ioctl: (Node=%p, ID=%i, Data=%p)", Node, ID, Data);\r
switch(ID)\r
{\r
BASE_IOCTLS(DRV_TYPE_VIDEO, "VESA", VERSION, csaVESA_IOCtls);\r
\r
Vesa_int_FillModeList();\r
\r
+ #if BLINKING_CURSOR\r
Time_RemoveTimer(gpVesaCursorTimer);\r
+ #endif\r
\r
Mutex_Acquire( &glVesa_Lock );\r
\r
gpVesa_BiosState->AX = 0x4F02;\r
gpVesa_BiosState->BX = gVesa_Modes[mode].code;\r
if(gVesa_Modes[mode].flags & FLAG_LFB) {\r
- gpVesa_BiosState->BX |= 0x4000; // Bit 14 - Use LFB\r
+ gpVesa_BiosState->BX |= 1 << 14; // Use LFB\r
}\r
+ LOG("In : AX=%04x/BX=%04x",\r
+ gpVesa_BiosState->AX, gpVesa_BiosState->BX);\r
\r
// Set Mode\r
VM8086_Int(gpVesa_BiosState, 0x10);\r
+\r
+ LOG("Out: AX = %04x", gpVesa_BiosState->AX);\r
\r
// Map Framebuffer\r
if( (tVAddr)gpVesa_Framebuffer != VESA_DEFAULT_FRAMEBUFFER )\r
giVesaPageCount = (gVesa_Modes[mode].fbSize + 0xFFF) >> 12;\r
gpVesa_Framebuffer = (void*)MM_MapHWPages(gVesa_Modes[mode].framebuffer, giVesaPageCount);\r
\r
- Log_Log("VESA", "Setting mode to %i (%ix%i %ibpp) %p[0x%x] maps %P",\r
- mode,\r
+ Log_Log("VESA", "Setting mode to %i 0x%x (%ix%i %ibpp) %p[0x%x] maps %P",\r
+ mode, gVesa_Modes[mode].code,\r
gVesa_Modes[mode].width, gVesa_Modes[mode].height,\r
gVesa_Modes[mode].bpp,\r
gpVesa_Framebuffer, giVesaPageCount << 12, gVesa_Modes[mode].framebuffer\r
\r
Mutex_Release( &glVesa_Lock );\r
\r
+ gVesa_BufInfo.BackBuffer = realloc(gVesa_BufInfo.BackBuffer,\r
+ gVesa_Modes[mode].height * gVesa_Modes[mode].pitch);\r
gVesa_BufInfo.Framebuffer = gpVesa_Framebuffer;\r
gVesa_BufInfo.Pitch = gVesa_Modes[mode].pitch;\r
gVesa_BufInfo.Width = gVesa_Modes[mode].width;\r
int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data)\r
{\r
int i;\r
- int best = -1, bestFactor = 1000;\r
- int factor, tmp;\r
+ int best = -1, tmp;\r
+ unsigned int factor, bestFactor = -1;\r
\r
ENTER("idata->width idata->height idata->bpp", data->width, data->height, data->bpp);\r
\r
Vesa_int_FillModeList();\r
\r
- for(i=0;i<giVesaModeCount;i++)\r
+ for(i = 0; i < giVesaModeCount; i ++)\r
{\r
LOG("Mode %i (%ix%ix%i)", i, gVesa_Modes[i].width, gVesa_Modes[i].height, gVesa_Modes[i].bpp);\r
\r
tmp = gVesa_Modes[i].width * gVesa_Modes[i].height;\r
tmp -= data->width * data->height;\r
tmp = tmp < 0 ? -tmp : tmp;\r
- factor = tmp * 1000 / (data->width * data->height);\r
+ factor = (Uint64)tmp * 1000 / (data->width * data->height);\r
\r
if( data->bpp == 8 && gVesa_Modes[i].bpp != 8 ) continue;\r
if( data->bpp == 16 && gVesa_Modes[i].bpp != 16 ) continue;\r