/**\r
* \file drv_bochsvbe.c\r
- * \brief BGA (Bochs Graphic Adapter) Driver\r
- * \note for Acess2\r
+ * \brief BGA (Bochs Graphic Adapter) Driver for Acess2\r
* \warning This driver does NOT support the Bochs PCI VGA driver\r
*/\r
#define DEBUG 0\r
#include <vfs.h>\r
#include <fs_devfs.h>\r
#include <drv_pci.h>\r
-#include <tpl_drv_video.h>\r
+#include <api_drv_video.h>\r
\r
#define INT\r
\r
-// === TYPEDEFS ===\r
-typedef struct {\r
+// === TYPES ===\r
+typedef struct sBGA_Mode {\r
Uint16 width;\r
Uint16 height;\r
Uint16 bpp;\r
- Uint16 flags;\r
Uint32 fbSize;\r
-} t_bga_mode;\r
+} tBGA_Mode;\r
\r
// === CONSTANTS ===\r
-enum eMode_Flags {\r
- MODEFLAG_TEXT = 1\r
-};\r
#define BGA_LFB_MAXSIZE (1024*768*4)\r
#define VBE_DISPI_BANK_ADDRESS 0xA0000\r
#define VBE_DISPI_LFB_PHYSICAL_ADDRESS 0xE0000000\r
int BGA_Ioctl(tVFS_Node *node, int id, void *data);\r
\r
// === GLOBALS ===\r
-MODULE_DEFINE(0, 0x0032, BochsGA, BGA_Install, NULL, NULL);\r
+MODULE_DEFINE(0, 0x0032, BochsGA, BGA_Install, NULL, "PCI", NULL);\r
tDevFS_Driver gBGA_DriverStruct = {\r
NULL, "BochsGA",\r
{\r
}\r
};\r
int giBGA_CurrentMode = -1;\r
+ int giBGA_BufferFormat = 0;\r
tVideo_IOCtl_Pos gBGA_CursorPos = {-1,-1};\r
- int giBGA_DriverId = -1;\r
Uint *gBGA_Framebuffer;\r
-t_bga_mode gBGA_Modes[] = {\r
- {},\r
- { 80,25, 12, MODEFLAG_TEXT, 80*25*8}, // 640 x 480\r
- {100,37, 12, MODEFLAG_TEXT, 100*37*8}, // 800 x 600\r
- {640,480,8, 0, 640*480},\r
- {640,480,32, 0, 640*480*4},\r
- {800,600,8, 0, 800*600},\r
- {800,600,32, 0, 800*600*4},\r
+const tBGA_Mode *gpBGA_CurrentMode;\r
+const tBGA_Mode gBGA_Modes[] = {\r
+ {640,480,32, 640*480*4},\r
+ {800,600,32, 800*600*4},\r
+ {1024,768,32, 1024*768*4}\r
};\r
#define BGA_MODE_COUNT (sizeof(gBGA_Modes)/sizeof(gBGA_Modes[0]))\r
\r
*/\r
int BGA_Install(char **Arguments)\r
{\r
- int bga_version = 0;\r
+ int version = 0;\r
\r
// Check BGA Version\r
- bga_version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID);\r
+ version = BGA_int_ReadRegister(VBE_DISPI_INDEX_ID);\r
+ \r
// NOTE: This driver was written for 0xB0C4, but they seem to be backwards compatable\r
- if(bga_version < 0xB0C4 || bga_version > 0xB0C5) {\r
- Warning("[BGA ] Bochs Adapter Version is not 0xB0C4 or 0xB0C5, instead 0x%x", bga_version);\r
+ if(version != 0xB0C0 && (version < 0xB0C4 || version > 0xB0C5)) {\r
+ Log_Warning("BGA", "Bochs Adapter Version is not 0xB0C4 or 0xB0C5, instead 0x%x", version);\r
return MODULE_ERR_NOTNEEDED;\r
}\r
\r
// Install Device\r
- giBGA_DriverId = DevFS_AddDevice( &gBGA_DriverStruct );\r
- if(giBGA_DriverId == -1) {\r
- Warning("[BGA ] Unable to register with DevFS, maybe already loaded?");\r
+ if(DevFS_AddDevice( &gBGA_DriverStruct ) == -1) {\r
+ Log_Warning("BGA", "Unable to register with DevFS, maybe already loaded?");\r
return MODULE_ERR_MISC;\r
}\r
\r
// Map Framebuffer to hardware address\r
- gBGA_Framebuffer = (void *) MM_MapHWPage(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768); // 768 pages (3Mb)\r
+ gBGA_Framebuffer = (void *) MM_MapHWPages(VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768); // 768 pages (3Mb)\r
\r
return MODULE_ERR_OK;\r
}\r
*/\r
void BGA_Uninstall()\r
{\r
- //DevFS_DelDevice( giBGA_DriverId );\r
- MM_UnmapHWPage( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\r
+ DevFS_DelDevice( &gBGA_DriverStruct );\r
+ MM_UnmapHWPages( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\r
}\r
\r
/**\r
if(giBGA_CurrentMode == -1) return -1;\r
\r
// Check Offset and Length against Framebuffer Size\r
- if(off+len > gBGA_Modes[giBGA_CurrentMode].fbSize)\r
+ if(off+len > gpBGA_CurrentMode->fbSize)\r
return -1;\r
\r
// Copy from Framebuffer\r
\r
// Check Mode\r
if(giBGA_CurrentMode == -1) {\r
- LEAVE('i', -1);\r
- return -1;\r
- }\r
- \r
- // Check Input against Frambuffer Size\r
- if(off + len > gBGA_Modes[giBGA_CurrentMode].fbSize) {\r
- LEAVE('i', -1);\r
- return -1;\r
+ Log_Notice("BGA", "Setting video mode to #0 (640x480x32)");\r
+ BGA_int_UpdateMode(0); // Mode Zero is 640x480\r
}\r
\r
// Text Mode\r
- if( gBGA_Modes[giBGA_CurrentMode].flags & MODEFLAG_TEXT )\r
+ switch( giBGA_BufferFormat )\r
{\r
+ case VIDEO_BUFFMT_TEXT:\r
+ {\r
tVT_Char *chars = Buffer;\r
- int pitch = gBGA_Modes[giBGA_CurrentMode].width * giVT_CharWidth;\r
- int x, y;\r
+ int x, y; // Characters/Rows\r
+ int widthInChars = gpBGA_CurrentMode->width/giVT_CharWidth;\r
Uint32 *dest;\r
\r
off /= sizeof(tVT_Char);\r
- dest = (void*)gBGA_Framebuffer;\r
- x = (off % gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharWidth;\r
- y = (off / gBGA_Modes[giBGA_CurrentMode].width) * giVT_CharHeight;\r
- dest += y * pitch;\r
- dest += x * giVT_CharWidth;\r
len /= sizeof(tVT_Char);\r
+ \r
+ x = (off % widthInChars);\r
+ y = (off / widthInChars);\r
+ \r
+ // Sanity Check\r
+ if(y > gpBGA_CurrentMode->height / giVT_CharHeight) {\r
+ LEAVE('i', 0);\r
+ return 0;\r
+ }\r
+ \r
+ dest = (Uint32 *)gBGA_Framebuffer;\r
+ dest += y * gpBGA_CurrentMode->width * giVT_CharHeight;\r
while(len--)\r
{\r
VT_Font_Render(\r
chars->Ch,\r
- dest, pitch,\r
+ dest + x*giVT_CharWidth, 32, gpBGA_CurrentMode->width*4,\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 ++;\r
+ if( x >= widthInChars ) {\r
x = 0;\r
- y += giVT_CharHeight;\r
- dest += pitch*(giVT_CharHeight-1);\r
+ y ++; // Why am I keeping track of this?\r
+ dest += gpBGA_CurrentMode->width*giVT_CharHeight;\r
}\r
}\r
- }\r
- else\r
- {\r
+ }\r
+ break;\r
+ \r
+ case VIDEO_BUFFMT_FRAMEBUFFER:\r
+ {\r
Uint8 *destBuf = (Uint8*) ((Uint)gBGA_Framebuffer + (Uint)off);\r
\r
- Log("buffer = %p", Buffer);\r
- Log("Updating Framebuffer (%p to %p)",\r
- destBuf, destBuf + (Uint)len);\r
+ if( off + len > gpBGA_CurrentMode->fbSize ) {\r
+ LEAVE('i', 0);\r
+ return 0;\r
+ }\r
+ \r
+ LOG("buffer = %p", Buffer);\r
+ LOG("Updating Framebuffer (%p to %p)", destBuf, destBuf + (Uint)len);\r
\r
\r
// Copy to Frambuffer\r
memcpy(destBuf, Buffer, len);\r
\r
- Log("BGA Framebuffer updated");\r
+ LOG("BGA Framebuffer updated");\r
+ }\r
+ break;\r
+ default:\r
+ LEAVE('i', -1);\r
+ return -1;\r
}\r
\r
LEAVE('i', len);\r
}\r
\r
/**\r
- * \fn INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data)\r
+ * \fn int BGA_Ioctl(tVFS_Node *Node, int ID, void *Data)\r
* \brief Handle messages to the device\r
*/\r
-INT int BGA_Ioctl(tVFS_Node *node, int ID, void *Data)\r
+int BGA_Ioctl(tVFS_Node *Node, int ID, void *Data)\r
{\r
int ret = -2;\r
- ENTER("pNode iId pData", node, ID, Data);\r
+ ENTER("pNode iId pData", Node, ID, Data);\r
\r
switch(ID)\r
{\r
ret = BGA_int_ModeInfo((tVideo_IOCtl_Mode*)Data);\r
break;\r
\r
- // Request Access to LFB\r
- case VIDEO_IOCTL_REQLFB:\r
- ret = BGA_int_MapFB( *(void**)Data );\r
+ case VIDEO_IOCTL_SETBUFFORMAT:\r
+ ret = giBGA_BufferFormat;\r
+ if(Data)\r
+ giBGA_BufferFormat = *(int*)Data;\r
break;\r
\r
case VIDEO_IOCTL_SETCURSOR:\r
gBGA_CursorPos.y = ((tVideo_IOCtl_Pos*)Data)->y;\r
break;\r
\r
+ // Request Access to LFB\r
+// case VIDEO_IOCTL_REQLFB:\r
+// ret = BGA_int_MapFB( *(void**)Data );\r
+// break;\r
+ \r
default:\r
LEAVE('i', -2);\r
return -2;\r
outw(VBE_DISPI_IOPORT_DATA, value);\r
}\r
\r
-INT Uint16 BGA_int_ReadRegister(Uint16 reg)\r
+Uint16 BGA_int_ReadRegister(Uint16 reg)\r
{\r
outw(VBE_DISPI_IOPORT_INDEX, reg);\r
return inw(VBE_DISPI_IOPORT_DATA);\r
}\r
\r
#if 0\r
-INT void BGA_int_SetBank(Uint16 bank)\r
+void BGA_int_SetBank(Uint16 bank)\r
{\r
BGA_int_WriteRegister(VBE_DISPI_INDEX_BANK, bank);\r
}\r
* \fn void BGA_int_SetMode(Uint16 width, Uint16 height, Uint16 bpp)\r
* \brief Sets the video mode from the dimensions and bpp given\r
*/\r
-void BGA_int_SetMode(Uint16 width, Uint16 height)\r
+void BGA_int_SetMode(Uint16 Width, Uint16 Height)\r
{\r
- ENTER("iwidth iheight ibpp", width, height, bpp);\r
+ ENTER("iWidth iheight ibpp", Width, Height, bpp);\r
BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);\r
- BGA_int_WriteRegister(VBE_DISPI_INDEX_XRES, width);\r
- BGA_int_WriteRegister(VBE_DISPI_INDEX_YRES, height);\r
+ BGA_int_WriteRegister(VBE_DISPI_INDEX_XRES, Width);\r
+ BGA_int_WriteRegister(VBE_DISPI_INDEX_YRES, Height);\r
BGA_int_WriteRegister(VBE_DISPI_INDEX_BPP, 32);\r
BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM | VBE_DISPI_LFB_ENABLED);\r
- //BGA_int_WriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_NOCLEARMEM);\r
LEAVE('-');\r
}\r
\r
// Sanity Check\r
if(id < 0 || id >= BGA_MODE_COUNT) return -1;\r
\r
- // Check if it is a text mode\r
- if( gBGA_Modes[id].flags & MODEFLAG_TEXT )\r
- BGA_int_SetMode(\r
- gBGA_Modes[id].width*giVT_CharWidth,\r
- gBGA_Modes[id].height*giVT_CharHeight);\r
- else // Graphics?\r
- BGA_int_SetMode(\r
- gBGA_Modes[id].width,\r
- gBGA_Modes[id].height);\r
+ BGA_int_SetMode(\r
+ gBGA_Modes[id].width,\r
+ gBGA_Modes[id].height);\r
\r
giBGA_CurrentMode = id;\r
+ gpBGA_CurrentMode = &gBGA_Modes[id];\r
return id;\r
}\r
\r
LogF("Mode %i (%ix%ix%i), ", i, gBGA_Modes[i].width, gBGA_Modes[i].height, gBGA_Modes[i].bpp);\r
#endif\r
\r
- // Check if this mode is the same type as what we want\r
- if( !(gBGA_Modes[i].flags & MODEFLAG_TEXT) != !(info->flags & VIDEO_FLAG_TEXT) )\r
- continue;\r
- \r
// Ooh! A perfect match\r
if(gBGA_Modes[i].width == info->width\r
&& gBGA_Modes[i].height == info->height\r
info->height = gBGA_Modes[best].height;\r
info->bpp = gBGA_Modes[best].bpp;\r
\r
- info->flags = 0;\r
- if(gBGA_Modes[best].flags & MODEFLAG_TEXT)\r
- info->flags |= VIDEO_FLAG_TEXT;\r
- \r
return best;\r
}\r
\r
info->height = gBGA_Modes[info->id].height;\r
info->bpp = gBGA_Modes[info->id].bpp;\r
\r
- info->flags = 0;\r
- if(gBGA_Modes[info->id].flags & MODEFLAG_TEXT)\r
- info->flags |= VIDEO_FLAG_TEXT;\r
- \r
return 1;\r
}\r
\r
\r
// Sanity Check\r
if((Uint)Dest > 0xC0000000) return 0;\r
- if(gBGA_Modes[giBGA_CurrentMode].bpp < 15) return 0; // Only non-pallete modes are supported\r
+ if(gpBGA_CurrentMode->bpp < 15) return 0; // Only non-pallete modes are supported\r
\r
// Count required pages\r
- pages = (gBGA_Modes[giBGA_CurrentMode].fbSize + 0xFFF) >> 12;\r
+ pages = (gpBGA_CurrentMode->fbSize + 0xFFF) >> 12;\r
\r
// Check if there is space\r
for( i = 0; i < pages; i++ )\r