#include <modules.h>\r
#include <vm8086.h>\r
#include "common.h"\r
+#include <timers.h>\r
\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
-Uint64 Vesa_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);\r
-Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 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);\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
// === GLOBALS ===\r
MODULE_DEFINE(0, VERSION, Vesa, Vesa_Install, NULL, "PCI", "VM8086", NULL);\r
tVFS_NodeType gVesa_NodeType = {\r
- .Read = Vesa_Read,\r
.Write = Vesa_Write,\r
.IOCtl = Vesa_IOCtl\r
};\r
// --- Cursor Control ---\r
int giVesaCursorX = -1;\r
int giVesaCursorY = -1;\r
- int giVesaCursorTimer = -1; // Invalid timer\r
+#if BLINKING_CURSOR\r
+tTimer *gpVesaCursorTimer;\r
+#endif\r
int gbVesa_CursorVisible = 0;\r
// --- 2D Video Stream Handlers ---\r
tDrvUtil_Video_BufInfo gVesa_BufInfo;\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
+ 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
+ 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
-// VM8086_Deallocate( info );\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
- // Install Device\r
- giVesaDriverId = DevFS_AddDevice( &gVesa_DriverStruct );\r
- if(giVesaDriverId == -1) return MODULE_ERR_MISC;\r
+ mode->pitch = vbeinfo->pitch;\r
+ mode->width = vbeinfo->Xres;\r
+ mode->height = vbeinfo->Yres;\r
+ mode->bpp = vbeinfo->bpp;\r
\r
- return MODULE_ERR_OK;\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
\r
-/* Read from the framebuffer\r
- */\r
-Uint64 Vesa_Read(tVFS_Node *Node, Uint64 off, Uint64 len, void *buffer)\r
-{\r
- #if DEBUG >= 2\r
- Log("Vesa_Read: () - NULL\n");\r
- #endif\r
- return 0;\r
-}\r
-\r
/**\r
* \brief Write to the framebuffer\r
*/\r
-Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer)\r
+size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer)\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
- Time_RemoveTimer(giVesaCursorTimer);\r
- giVesaCursorTimer = -1;\r
+ Time_RemoveTimer(gpVesaCursorTimer);\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
DrvUtil_Video_RemoveCursor( &gVesa_BufInfo );\r
#if BLINKING_CURSOR\r
- if(giVesaCursorTimer != -1) {\r
- Time_RemoveTimer(giVesaCursorTimer);\r
- giVesaCursorTimer = -1;\r
+ if(gpVesaCursorTimer) {\r
+ Time_RemoveTimer(gpVesaCursorTimer);\r
}\r
#endif\r
}\r
giVesaCursorY*giVT_CharHeight\r
);\r
#if BLINKING_CURSOR\r
- giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, NULL);\r
+ Time_ScheduleTimer( gpVesaCursorTimer, VESA_CURSOR_PERIOD );\r
#endif\r
}\r
else\r
gbVesa_CursorVisible = !gbVesa_CursorVisible;\r
\r
#if BLINKING_CURSOR\r
- giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Arg);\r
+ Time_ScheduleTimer( gpVesaCursorTimer, VESA_CURSOR_PERIOD );\r
#endif\r
}\r
\r