tSpinlock glVesa_Lock;\r
tVM8086 *gpVesa_BiosState;\r
int giVesaCurrentMode = -1;\r
+ int giVesaCurrentFormat = VIDEO_BUFFMT_TEXT;\r
int giVesaDriverId = -1;\r
char *gVesaFramebuffer = (void*)0xC00A0000;\r
tVesa_Mode *gVesa_Modes;\r
gVesa_Modes[0].height = 25;\r
gVesa_Modes[0].bpp = 12;\r
gVesa_Modes[0].code = 0x3;\r
- gVesa_Modes[0].flags = VIDEO_FLAG_TEXT;\r
+ gVesa_Modes[0].flags = 1;\r
gVesa_Modes[0].fbSize = 80*25*2;\r
gVesa_Modes[0].framebuffer = 0xB8000;\r
\r
{\r
Uint8 *fb = (Uint8 *)(KERNEL_BASE|0xB8000);\r
Uint32 *buf = Buffer;\r
+ int rem;\r
+ \r
+ if( giVesaCurrentFormat != VIDEO_BUFFMT_TEXT ) {\r
+ Log_Warning("VESA", "Vesa_Write - Mode 0 is not framebuffer");\r
+ LEAVE('i', -1);\r
+ return -1;\r
+ }\r
+ \r
if( Offset + Length > 25*80*8 ) {\r
Log_Warning("VESA", "Vesa_Write - Framebuffer Overflow");\r
LEAVE('i', 0);\r
}\r
\r
fb += 2*Offset;\r
- for(; Length > 0; Length -= 8, fb += 2)\r
+ for(rem = Length / sizeof(tVT_Char); rem --; fb += 2)\r
{\r
if( *buf < 0x80 )\r
*fb = *buf & 0x7F;\r
fb[1] |= (*buf & 0x007000) > 0x003000 ? 0x10 : 0;\r
buf ++;\r
}\r
+ Length /= sizeof(tVT_Char);\r
+ Length *= sizeof(tVT_Char);\r
+ LEAVE('X', Length);\r
+ return Length;\r
}\r
\r
if( gVesa_Modes[giVesaCurrentMode].framebuffer == 0 ) {\r
LEAVE('i', 0);\r
return 0;\r
}\r
- if(gVesa_Modes[giVesaCurrentMode].fbSize < Offset+Length)\r
+ \r
+ // Text Mode\r
+ switch( giVesaCurrentFormat )\r
{\r
- Log_Warning("VESA", "Vesa_Write - Framebuffer Overflow");\r
- LEAVE('i', 0);\r
- return 0;\r
- }\r
+ case VIDEO_BUFFMT_TEXT:\r
+ {\r
+ tVT_Char *chars = Buffer;\r
+ int pitch = gVesa_Modes[giVesaCurrentMode].width * giVT_CharWidth;\r
+ int x, y;\r
+ Uint32 *dest;\r
+ int rem;\r
+ \r
+ Offset /= sizeof(tVT_Char);\r
+ dest = (void*)gVesaFramebuffer;\r
+ x = (Offset % gVesa_Modes[giVesaCurrentMode].width) * giVT_CharWidth;\r
+ y = (Offset / gVesa_Modes[giVesaCurrentMode].width) * giVT_CharHeight;\r
+ \r
+ // Sanity Check\r
+ if(y > gVesa_Modes[giVesaCurrentMode].height) {\r
+ LEAVE('i', 0);\r
+ return 0;\r
+ }\r
+ \r
+ dest += y * pitch;\r
+ dest += x * giVT_CharWidth;\r
+ for( rem = Length / sizeof(tVT_Char); rem--; )\r
+ {\r
+ VT_Font_Render(\r
+ chars->Ch,\r
+ dest, pitch,\r
+ VT_Colour12to24(chars->BGCol),\r
+ VT_Colour12to24(chars->FGCol)\r
+ );\r
+ \r
+ dest += giVT_CharWidth;\r
+ \r
+ chars ++;\r
+ x += giVT_CharWidth;\r
+ if( x >= pitch ) {\r
+ x = 0;\r
+ y += giVT_CharHeight;\r
+ dest += pitch*(giVT_CharHeight-1);\r
+ }\r
+ }\r
+ Length /= sizeof(tVT_Char);\r
+ Length *= sizeof(tVT_Char);\r
+ }\r
+ break;\r
\r
- memcpy(gVesaFramebuffer + Offset, Buffer, Length);\r
+ case VIDEO_BUFFMT_FRAMEBUFFER:\r
+ {\r
+ Uint8 *destBuf = (Uint8*) ((Uint)gVesaFramebuffer + (Uint)Offset);\r
+ \r
+ if(gVesa_Modes[giVesaCurrentMode].fbSize < Offset+Length)\r
+ {\r
+ Log_Warning("VESA", "Vesa_Write - Framebuffer Overflow");\r
+ LEAVE('i', 0);\r
+ return 0;\r
+ }\r
+ \r
+ LOG("buffer = %p", Buffer);\r
+ LOG("Updating Framebuffer (%p to %p)", destBuf, destBuf + (Uint)Length);\r
+ \r
+ \r
+ // Copy to Frambuffer\r
+ memcpy(destBuf, Buffer, Length);\r
+ \r
+ LOG("BGA Framebuffer updated");\r
+ }\r
+ break;\r
+ default:\r
+ LEAVE('i', -1);\r
+ return -1;\r
+ }\r
\r
LEAVE('X', Length);\r
return Length;\r
*/\r
int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data)\r
{\r
+ int ret;\r
switch(ID)\r
{\r
case DRV_IOCTL_TYPE: return DRV_TYPE_VIDEO;\r
case VIDEO_IOCTL_MODEINFO:\r
return Vesa_Int_ModeInfo((tVideo_IOCtl_Mode*)Data);\r
\r
+ case VIDEO_IOCTL_SETBUFFORMAT:\r
+ ret = giVesaCurrentFormat;\r
+ if(Data) giVesaCurrentFormat = *(int*)Data;\r
+ return ret;\r
+ \r
case VIDEO_IOCTL_REQLFB: // Request Linear Framebuffer\r
return 0;\r
}\r
\r
ENTER("idata->width idata->height idata->bpp", data->width, data->height, data->bpp);\r
\r
- if(data->flags & VIDEO_FLAG_TEXT) {\r
- LEAVE('i', 0);\r
- return 0;\r
- }\r
- \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