\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
#if BLINKING_CURSOR\r
\r
// === PROTOTYPES ===\r
int Vesa_Install(char **Arguments);\r
+ int VBE_int_GetModeList(void);\r
size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);\r
int Vesa_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
int Vesa_Int_SetMode(int Mode);\r
\r
// === CODE ===\r
int Vesa_Install(char **Arguments)\r
+{\r
+ int rv;\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
+// 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
+ #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
+ // -- 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
\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
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
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