* AcessOS 1\r
* Video BIOS Extensions (Vesa) Driver\r
*/\r
-#define DEBUG 1\r
+#define DEBUG 0\r
#define VERSION 0x100\r
\r
#include <acess.h>\r
#include <vm8086.h>\r
#include "common.h"\r
#include <timers.h>\r
+#include <limits.h>\r
\r
// === CONSTANTS ===\r
-#define FLAG_LFB 0x1\r
-#define FLAG_POPULATED 0x2\r
-#define FLAG_VALID 0x4\r
+#ifdef ARCHDIR_is_x86\r
+# define USE_BIOS 1\r
+#else\r
+# define USE_BIOS 0\r
+#endif\r
#define VESA_DEFAULT_FRAMEBUFFER (KERNEL_BASE|0xA0000)\r
#define BLINKING_CURSOR 0\r
#if BLINKING_CURSOR\r
int Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data);\r
void Vesa_int_HideCursor(void);\r
void Vesa_int_ShowCursor(void);\r
+ int Vesa_int_SetCursor(tVideo_IOCtl_Bitmap *Cursor);\r
void Vesa_FlipCursor(void *Arg);\r
Uint16 VBE_int_GetWord(const tVT_Char *Char);\r
void VBE_int_Text_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour);\r
int giVesaCurrentMode = 0;\r
tVesa_Mode gVesa_BootMode = {0x03, 80*8, 25*16, 80*8*2, 12, FLAG_POPULATED, 80*25*2, 0xB8000};\r
tVesa_Mode *gVesa_Modes;\r
-tVesa_Mode *gpVesaCurMode;\r
+tVesa_Mode *gpVesaCurMode = &gVesa_BootMode;\r
int giVesaModeCount = 0;\r
int gbVesaModesChecked;\r
// --- Framebuffer ---\r
// === CODE ===\r
int Vesa_Install(char **Arguments)\r
{\r
- int rv;\r
-\r
for( int i = 0; Arguments && Arguments[i]; i ++ )\r
{\r
if( strcmp(Arguments[i], "nobios") == 0 )\r
}\r
}\r
\r
+ #if USE_BIOS\r
if( !gbVesa_DisableBIOSCalls )\r
{\r
gpVesa_BiosState = VM8086_Init();\r
\r
- if( (rv = VBE_int_GetModeList()) )\r
- return rv;\r
+ int rv = VBE_int_GetModeList();\r
+ if(rv) return rv;\r
}\r
+ #endif\r
\r
#if BLINKING_CURSOR\r
// Create blink timer\r
return MODULE_ERR_OK;\r
}\r
\r
+#if USE_BIOS\r
int VBE_int_GetModeList(void)\r
{\r
tVesa_CallInfo *info;\r
\r
// Allocate Info Block\r
info = VM8086_Allocate(gpVesa_BiosState, 512, &infoPtr.seg, &infoPtr.ofs);\r
+ if( info == NULL ) {\r
+ Log_Warning("VBE", "VM8086 allocation error");\r
+ return MODULE_ERR_NOTNEEDED;\r
+ }\r
// Set Requested Version\r
memcpy(info->signature, "VBE2", 4);\r
// Set Registers\r
}\r
return 0;\r
}\r
+#endif\r
\r
\r
void VBE_int_FillMode_Int(tVesa_Mode *Mode, const tVesa_CallModeInfo *vbeinfo)\r
S_LOG(*vbeinfo, image_count_lfb, "%i");\r
LOG("}");\r
#endif\r
-\r
+ \r
Mode->flags = FLAG_POPULATED;\r
+ // Check if this mode is supported by hardware\r
if( !(vbeinfo->attributes & 1) )\r
{\r
#if DEBUG\r
Mode->bpp = 0;\r
return ;\r
case 0x90:\r
- Mode->flags |= FLAG_LFB;\r
+ Mode->flags |= FLAG_LFB|FLAG_GRAPHICS;\r
Mode->framebuffer = vbeinfo->physbase;\r
Mode->fbSize = vbeinfo->Yres*vbeinfo->pitch;\r
break;\r
\r
void Vesa_int_FillModeList(void)\r
{\r
+ #if USE_BIOS\r
if( !gbVesaModesChecked && !gbVesa_DisableBIOSCalls )\r
{\r
tVesa_CallModeInfo *modeinfo;\r
\r
gbVesaModesChecked = 1;\r
}\r
+ #endif\r
}\r
\r
/**\r
*/\r
size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags)\r
{\r
- // Framebuffer modes - just pass on\r
- if( gpVesaCurMode->flags & FLAG_LFB )\r
- return DrvUtil_Video_WriteLFB(&gVesa_BufInfo, Offset, Length, Buffer);\r
- \r
- // EGA text mode translation\r
- switch( gVesa_BufInfo.BufferFormat )\r
+ switch( gpVesaCurMode->flags & (FLAG_LFB|FLAG_GRAPHICS) )\r
{\r
- case VIDEO_BUFFMT_TEXT: {\r
- int num = Length / sizeof(tVT_Char);\r
- int ofs = Offset / sizeof(tVT_Char);\r
- int i = 0;\r
- const tVT_Char *chars = Buffer;\r
- Uint16 word;\r
- \r
- for( ; num--; i ++, ofs ++)\r
+ case 0:\r
+ // EGA text mode translation\r
+ switch( gVesa_BufInfo.BufferFormat )\r
{\r
- word = VBE_int_GetWord( &chars[i] );\r
- ((Uint16*)gVesa_BufInfo.Framebuffer)[ ofs ] = word;\r
+ case VIDEO_BUFFMT_TEXT: {\r
+ int num = Length / sizeof(tVT_Char);\r
+ int ofs = Offset / sizeof(tVT_Char);\r
+ int i = 0;\r
+ const tVT_Char *chars = Buffer;\r
+ \r
+ for( ; num--; i ++, ofs ++)\r
+ {\r
+ Uint16 word = VBE_int_GetWord( &chars[i] );\r
+ ((Uint16*)gVesa_BufInfo.Framebuffer)[ ofs ] = word;\r
+ }\r
+ \r
+ return Length; }\r
+ case VIDEO_BUFFMT_2DSTREAM:\r
+ return DrvUtil_Video_2DStream(NULL, Buffer, Length,\r
+ &gVBE_Text2DFunctions, sizeof(gVBE_Text2DFunctions));\r
+ default:\r
+ Log_Warning("VBE", "TODO: Alternate modes in EGA text mode");\r
+ return 0;\r
}\r
- \r
- return Length; }\r
- case VIDEO_BUFFMT_2DSTREAM:\r
- return DrvUtil_Video_2DStream(NULL, Buffer, Length,\r
- &gVBE_Text2DFunctions, sizeof(gVBE_Text2DFunctions));\r
+ return 0;\r
+ case FLAG_LFB|FLAG_GRAPHICS:\r
+ // Framebuffer modes - use DrvUtil Video\r
+ return DrvUtil_Video_WriteLFB(&gVesa_BufInfo, Offset, Length, Buffer);\r
default:\r
- Log_Warning("VBE", "TODO: Alternate modes in EGA text mode");\r
+ Log_Warning("VBE", "TODO: _Write %s%s",\r
+ (gpVesaCurMode->flags & FLAG_LFB ? "FLAG_LFB" : ""),\r
+ (gpVesaCurMode->flags & FLAG_GRAPHICS ? "FLAG_GRAPHICS" : "")\r
+ );\r
return 0;\r
}\r
-\r
}\r
\r
const char *csaVESA_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};\r
case VIDEO_IOCTL_SETBUFFORMAT:\r
Vesa_int_HideCursor();\r
ret = gVesa_BufInfo.BufferFormat;\r
- if(Data) gVesa_BufInfo.BufferFormat = *(int*)Data;\r
+ if(Data)\r
+ gVesa_BufInfo.BufferFormat = *(int*)Data;\r
if(gVesa_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)\r
- DrvUtil_Video_SetCursor( &gVesa_BufInfo, &gDrvUtil_TextModeCursor );\r
+ Vesa_int_SetCursor(&gDrvUtil_TextModeCursor);\r
Vesa_int_ShowCursor();\r
return ret;\r
\r
case VIDEO_IOCTL_SETCURSOR: // Set cursor position\r
+ if( !CheckMem(Data, sizeof(tVideo_IOCtl_Pos)) )\r
+ return -EINVAL;\r
Vesa_int_HideCursor();\r
giVesaCursorX = ((tVideo_IOCtl_Pos*)Data)->x;\r
giVesaCursorY = ((tVideo_IOCtl_Pos*)Data)->y;\r
return 0;\r
\r
case VIDEO_IOCTL_SETCURSORBITMAP:\r
- if( gpVesaCurMode->flags & FLAG_LFB )\r
- DrvUtil_Video_SetCursor( &gVesa_BufInfo, Data );\r
- return 0;\r
+ return Vesa_int_SetCursor(Data);\r
}\r
return 0;\r
}\r
#endif\r
\r
Mutex_Acquire( &glVesa_Lock );\r
- \r
+\r
+ #if USE_BIOS\r
if( gbVesa_DisableBIOSCalls )\r
{\r
ASSERT(mode == -1);\r
\r
LOG("Out: AX = %04x", gpVesa_BiosState->AX);\r
}\r
+ #else\r
+ ASSERT(mode == -1);\r
+ #endif\r
\r
// Map Framebuffer\r
if( gpVesaCurMode )\r
{\r
- if( gpVesaCurMode->framebuffer < 1024*1024 )\r
- ;\r
- else\r
- MM_UnmapHWPages((tVAddr)gpVesa_Framebuffer, giVesaPageCount);\r
+ MM_UnmapHWPages(gpVesa_Framebuffer, giVesaPageCount);\r
}\r
giVesaPageCount = (modeptr->fbSize + 0xFFF) >> 12;\r
- if( modeptr->framebuffer < 1024*1024 )\r
- gpVesa_Framebuffer = (void*)(KERNEL_BASE|modeptr->framebuffer);\r
- else\r
- gpVesa_Framebuffer = (void*)MM_MapHWPages(modeptr->framebuffer, giVesaPageCount);\r
+ gpVesa_Framebuffer = MM_MapHWPages(modeptr->framebuffer, giVesaPageCount);\r
\r
Log_Log("VBE", "Setting mode to %i 0x%x (%ix%i %ibpp) %p[0x%x] maps %P",\r
mode, modeptr->code,\r
\r
int VBE_int_MatchModes(tVideo_IOCtl_Mode *ReqMode, tVesa_Mode *ThisMode)\r
{\r
+ if( ThisMode->bpp == 0 ) {\r
+ Log_Warning("VBE", "VESA mode %x (%ix%i) has 0bpp",\r
+ ThisMode->code, ThisMode->width, ThisMode->height);\r
+ return INT_MAX;\r
+ }\r
LOG("Matching %ix%i %ibpp", ThisMode->width, ThisMode->height, ThisMode->bpp);\r
if(ThisMode->width == ReqMode->width && ThisMode->height == ReqMode->height)\r
{\r
\r
void Vesa_int_ShowCursor(void)\r
{\r
- if( gpVesaCurMode->flags & FLAG_LFB )\r
+ if( gpVesaCurMode && gpVesaCurMode->flags & FLAG_LFB )\r
{\r
gbVesa_CursorVisible = (giVesaCursorX >= 0);\r
if(gVesa_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)\r
}\r
}\r
\r
+int Vesa_int_SetCursor(tVideo_IOCtl_Bitmap *Cursor)\r
+{\r
+ if( !CheckMem(Cursor, sizeof(tVideo_IOCtl_Bitmap)) )\r
+ return -EINVAL;\r
+ \r
+ if( gpVesaCurMode && gpVesaCurMode->flags & FLAG_LFB )\r
+ {\r
+ DrvUtil_Video_SetCursor( &gVesa_BufInfo, Cursor );\r
+ }\r
+ else\r
+ {\r
+ }\r
+ return 0;\r
+}\r
+\r
/**\r
* \brief Swaps the text cursor on/off\r
*/\r
if( gVesa_BufInfo.BufferFormat != VIDEO_BUFFMT_TEXT )\r
return ;\r
\r
- if( gpVesaCurMode->flags & FLAG_LFB )\r
+ if( gpVesaCurMode && gpVesaCurMode->flags & FLAG_LFB )\r
{\r
if( gbVesa_CursorVisible )\r
DrvUtil_Video_RemoveCursor(&gVesa_BufInfo);\r