Modules/VESA - Disabled cursor blink to aid timer debugging
[tpg/acess2.git] / KernelLand / Modules / Display / VESA / main.c
index c57d57d..8cb3728 100644 (file)
 \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
-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, 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
@@ -37,7 +39,6 @@ void  Vesa_FlipCursor(void *Arg);
 // === 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
@@ -66,9 +67,38 @@ tTimer       *gpVesaCursorTimer;
  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
@@ -76,7 +106,6 @@ int Vesa_Install(char **Arguments)
        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
@@ -90,15 +119,18 @@ int Vesa_Install(char **Arguments)
                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
@@ -110,22 +142,106 @@ int Vesa_Install(char **Arguments)
        \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
@@ -135,59 +251,21 @@ void Vesa_int_FillModeList(void)
                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, Uint Flags)\r
 {\r
        if( gVesa_Modes[giVesaCurrentMode].framebuffer == 0 ) {\r
                Log_Warning("VESA", "Vesa_Write - Non-LFB Modes not yet supported.");\r
@@ -204,7 +282,6 @@ const char *csaVESA_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
 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
@@ -254,18 +331,24 @@ int Vesa_Int_SetMode(int mode)
        \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
@@ -273,8 +356,8 @@ int Vesa_Int_SetMode(int mode)
        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
@@ -286,6 +369,8 @@ int Vesa_Int_SetMode(int mode)
        \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
@@ -298,14 +383,14 @@ int Vesa_Int_SetMode(int mode)
 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
@@ -324,7 +409,7 @@ int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data)
                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

UCC git Repository :: git.ucc.asn.au