-BUILD_NUM = 1802
+BUILD_NUM = 1811
//MM_SetFlags( i * 0x1000, MM_PFLAG_RO, MM_PFLAG_RO ); // Set Read Only
}
MM_Map( 0, 0 ); // IVT / BDA
- for(i=0x70;i<0x80;i++) {
+ for(i=0x10;i<0x9F;i++) {
MM_Map( i * 0x1000, i * 0x1000 ); MM_DerefPhys( i * 0x1000 );
}
MM_Map( 0x9F000, 0x9F000 ); // Stack / EBDA
int Flags; //!< Flags (see VT_FLAG_*)
short Width; //!< Virtual Width
short Height; //!< Virtual Height
- short RealWidth; //!< Real Width
- short RealHeight; //!< Real Height
int ViewPos; //!< View Buffer Offset (Text Only)
int WritePos; //!< Write Buffer Offset (Text Only)
Uint32 CurColour; //!< Current Text Colour
- char Name[2]; //!< Name of the terminal
int InputRead; //!< Input buffer read position
int InputWrite; //!< Input buffer write position
tVT_Char *Text;
Uint32 *Buffer;
};
+ char Name[2]; //!< Name of the terminal
tVFS_Node Node;
} tVTerm;
// --- Terminals ---
tVTerm gVT_Terminals[NUM_VTS];
int giVT_CurrentTerminal = 0;
+// --- Video State ---
+short giVT_RealWidth; //!< Real Width
+short giVT_RealHeight; //!< Real Height
+ int gbVT_TextMode = 1;
// --- Driver Handles ---
char *gsVT_OutputDevice = NULL;
char *gsVT_InputDevice = NULL;
VT_int_PutString(term, Buffer, Length);
break;
case TERM_MODE_FB:
- if( term->RealWidth > term->Width || term->RealHeight > term->Height )
+ if( giVT_RealWidth > term->Width || giVT_RealHeight > term->Height )
{
#if 0
int x, y, h;
return -1;
}
-/**
- * \fn void VT_SetTerminal(int ID)
- * \brief Set the current terminal
- */
-void VT_SetTerminal(int ID)
+void VT_SetResolution(int IsTextMode, int Width, int Height)
{
tVideo_IOCtl_Mode mode = {0};
- int modeNum;
+ int tmp;
// Create the video mode
- mode.width = gVT_Terminals[ ID ].Width;
- mode.height = gVT_Terminals[ ID ].Height;
- // - Text Mode
- if(gVT_Terminals[ ID ].Mode == TERM_MODE_TEXT) {
- mode.bpp = 12;
- mode.flags = VIDEO_FLAG_TEXT;
- }
- // - Framebuffer or 3D
- else {
- mode.bpp = 32;
- mode.flags = 0;
- }
+ mode.width = Width;
+ mode.height = Height;
+ mode.bpp = 32;
+ mode.flags = 0;
// Set video mode
VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_FINDMODE, &mode );
- modeNum = mode.id;
- gVT_Terminals[ ID ].RealWidth = mode.width;
- gVT_Terminals[ ID ].RealHeight = mode.height;
- VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &modeNum );
+ tmp = mode.id;
+ giVT_RealWidth = mode.width;
+ giVT_RealHeight = mode.height;
+ VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_GETSETMODE, &tmp );
+
+
+ if(IsTextMode)
+ tmp = VIDEO_BUFFMT_TEXT;
+ else
+ tmp = VIDEO_BUFFMT_FRAMEBUFFER;
+ VFS_IOCtl( giVT_OutputDevHandle, VIDEO_IOCTL_SETBUFFORMAT, &tmp );
+}
+
+/**
+ * \fn void VT_SetTerminal(int ID)
+ * \brief Set the current terminal
+ */
+void VT_SetTerminal(int ID)
+{
// Update current terminal ID
Log_Log("VTerm", "Changed terminal from %i to %i", giVT_CurrentTerminal, ID);
giVT_CurrentTerminal = ID;
if( Term->Mode == TERM_MODE_TEXT )
{
- if(UpdateAll) {
- VFS_WriteAt(
- giVT_OutputDevHandle,
- 0,
- Term->Width*Term->Height*sizeof(tVT_Char),
- &Term->Text[Term->ViewPos]
- );
- } else {
- int pos = Term->WritePos - Term->WritePos % Term->Width;
- VFS_WriteAt(
- giVT_OutputDevHandle,
- (pos - Term->ViewPos)*sizeof(tVT_Char),
- Term->Width*sizeof(tVT_Char),
- &Term->Text[pos]
- );
+ if(gbVT_TextMode)
+ {
+ if(UpdateAll) {
+ VFS_WriteAt(
+ giVT_OutputDevHandle,
+ 0,
+ Term->Width*Term->Height*sizeof(tVT_Char),
+ &Term->Text[Term->ViewPos]
+ );
+ } else {
+ int pos = Term->WritePos - Term->WritePos % Term->Width;
+ VFS_WriteAt(
+ giVT_OutputDevHandle,
+ (pos - Term->ViewPos)*sizeof(tVT_Char),
+ Term->Width*sizeof(tVT_Char),
+ &Term->Text[pos]
+ );
+ }
+ }
+ else
+ {
+ //TODO: Do VT Rendered Text
+ #if 0
+ if( UpdateAll ) {
+ VT_RenderText(0, Term->Width*Term->Height, &Term->Text[Term->ViewPos]);
+ }
+ else {
+ int pos = Term->WritePos - Term->WritePos % Term->Width;
+ VT_RenderText(
+ pos - Term->ViewPos,
+ Term->Width,
+ &Term->Text[pos]
+ );
+ }
+ #endif
}
}
else
// Alignment Check
if( head->Size & (BLOCK_SIZE-1) ) {
#if WARNINGS
- Warning("Size of heap address %p is invalid not aligned (0x%x)", head, head->Size);
+ Log_Warning("Heap", "Size of heap address %p is invalid not aligned (0x%x)", head, head->Size);
Heap_Dump();
#endif
RELEASE(&glHeap);
// Error check
if(head->Magic != MAGIC_FREE) {
#if WARNINGS
- Warning("Magic of heap address %p is invalid (0x%x)", head, head->Magic);
+ Log_Warning("Heap", "Magic of heap address %p is invalid (0x%x)", head, head->Magic);
Heap_Dump();
#endif
RELEASE(&glHeap); // Release spinlock
head->Magic = MAGIC_USED;
RELEASE(&glHeap); // Release spinlock
#if DEBUG_TRACE
- LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
+ Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", head->Data, head->Size, __builtin_return_address(0));
#endif
- return best->Data;
+ return head->Data;
}
// Break out of loop
if(best->Size == Bytes) {
RELEASE(&glHeap); // Release spinlock
#if DEBUG_TRACE
- LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
+ Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", best->Data, best->Size, __builtin_return_address(0));
#endif
return best->Data;
}
RELEASE(&glHeap); // Release spinlock
#if DEBUG_TRACE
- LOG("RETURN %p, to %p", best->Data, __builtin_return_address(0));
+ Log("[Heap ] Malloc'd %p (%i bytes), returning to %p", best->Data, best->Size, __builtin_return_address(0));
#endif
return best->Data;
}
tHeapFoot *foot;
#if DEBUG_TRACE
- LOG("Ptr = %p", Ptr);
- LOG("Returns to %p", __builtin_return_address(0));
+ Log_Log("Heap", "free: Ptr = %p", Ptr);
+ Log_Log("Heap", "free: Returns to %p", __builtin_return_address(0));
#endif
// Alignment Check
while( (Uint)head < (Uint)gHeapEnd )
{
foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) );
- Log("%p (0x%x): 0x%08lx 0x%lx", head, MM_GetPhysAddr((Uint)head), head->Size, head->Magic);
- Log("%p 0x%lx", foot->Head, foot->Magic);
- Log("");
+ Log_Log("Heap", "%p (0x%x): 0x%08lx 0x%lx", head, MM_GetPhysAddr((Uint)head), head->Size, head->Magic);
+ Log_Log("Heap", "%p 0x%lx", foot->Head, foot->Magic);
+ Log_Log("Heap", "");
// Sanity Check Header
if(head->Size == 0) {
- Log("HALTED - Size is zero");
+ Log_Warning("Heap", "HALTED - Size is zero");
break;
}
if(head->Size & (BLOCK_SIZE-1)) {
- Log("HALTED - Size is malaligned");
+ Log_Warning("Heap", "HALTED - Size is malaligned");
break;
}
if(head->Magic != MAGIC_FREE && head->Magic != MAGIC_USED) {
- Log("HALTED - Head Magic is Bad");
+ Log_Warning("Heap", "HALTED - Head Magic is Bad");
break;
}
// Check footer
if(foot->Magic != MAGIC_FOOT) {
- Log("HALTED - Foot Magic is Bad");
+ Log_Warning("Heap", "HALTED - Foot Magic is Bad");
break;
}
if(head != foot->Head) {
- Log("HALTED - Footer backlink is invalid");
+ Log_Warning("Heap", "HALTED - Footer backlink is invalid");
break;
}
// === FUNCTIONS ===
/**
* \fn int DevFS_AddDevice(tDevFS_Driver *Dev)
- * \brief Registers a device in the Device filesystem
- * \param Dev Pointer to a persistant structure that represents the driver
+ * \brief Registers a device in the Device Filesystem
+ * \param Device Pointer to a persistant structure that represents the driver
* \return Boolean success
*/
-extern int DevFS_AddDevice(tDevFS_Driver *Dev);
+extern int DevFS_AddDevice(tDevFS_Driver *Device);
+
+/**
+ * \brief Unregisters a device with the Device Filesystem
+ */
+extern void DevFS_DelDevice(tDevFS_Driver *Device);
#endif
* but they may choose not to allow direct user access to the framebuffer.\r
* \r
* \section Screen Contents\r
- * Reads and writes to the driver's file while in component colour modes\r
+ * Writes to the driver's file while in component colour modes\r
* must correspond to a change of the contents of the screen. The framebuffer\r
* must start at offset 0 in the file.\r
* In pallete colour modes the LFB is preceded by a 1024 byte pallete (allowing\r
* room for 256 entries of 32-bits each)\r
-*/\r
+ * Reading from the screen must either return zero, or read from the\r
+ * framebuffer.\r
+ * \r
+ * \section Mode Support\r
+ * All video drivers must support at least one text mode (Mode #0)\r
+ * For each graphics mode the driver exposes, there must be a corresponding\r
+ * text mode with the same resolution, this mode will be used when the\r
+ * user switches to a text Virtual Terminal while in graphics mode.\r
+ */\r
#ifndef _TPL_VIDEO_H\r
#define _TPL_VIDEO_H\r
\r
*/\r
VIDEO_IOCTL_MODEINFO,\r
\r
+ /**\r
+ * ioctl(..., int *NewFormat)\r
+ * \brief Switches between Text, Framebuffer and 3D modes\r
+ * \param NewFormat Pointer to the new format code (see eTplVideo_BufFormats)\r
+ * \return Original format\r
+ * \r
+ * Enabes and disables the video text mode, changing the behavior of\r
+ * writes to the device file.\r
+ */\r
+ VIDEO_IOCTL_SETBUFFORMAT,\r
+ \r
/**\r
* ioctl(..., tVideo_IOCtl_Pos *pos)\r
* \brief Sets the cursor position\r
Uint8 flags; //!< Mode Flags\r
} tVideo_IOCtl_Mode;\r
\r
-//! \name Video Mode flags\r
-//! \{\r
-/**\r
- * \brief Text Mode Flag\r
- * \note A text mode should have the ::sVideo_IOCtl_Mode.bpp set to 12\r
- */\r
-#define VIDEO_FLAG_TEXT 0x1\r
/**\r
- * \brief Slow (non-accellerated mode)\r
+ * \brief Buffer Format Codes\r
*/\r
-#define VIDEO_FLAG_SLOW 0x2\r
-//! \}\r
+enum eTplVideo_BufFormats\r
+{\r
+ VIDEO_BUFFMT_TEXT,\r
+ VIDEO_BUFFMT_FRAMEBUFFER,\r
+ VIDEO_BUFFMT_3DSTREAM\r
+};\r
\r
/**\r
* \brief Describes a position in the video framebuffer\r
#include <fs_devfs.h>
// === PROTOTYPES ===
- int DevFS_AddDevice(tDevFS_Driver *Dev);
+ int DevFS_AddDevice(tDevFS_Driver *Device);
+void DevFS_DelDevice(tDevFS_Driver *Device);
tVFS_Node *DevFS_InitDevice(char *Device, char **Options);
char *DevFS_ReadDir(tVFS_Node *Node, int Pos);
tVFS_Node *DevFS_FindDir(tVFS_Node *Node, char *Name);
};
tDevFS_Driver *gDevFS_Drivers = NULL;
int giDevFS_NextID = 1;
+tSpinlock glDevFS_ListLock;
// === CODE ===
/**
- * \fn int DevFS_AddDevice(tDevFS_Driver *Dev)
+ * \fn int DevFS_AddDevice(tDevFS_Driver *Device)
*/
-int DevFS_AddDevice(tDevFS_Driver *Dev)
+int DevFS_AddDevice(tDevFS_Driver *Device)
{
- Dev->Next = gDevFS_Drivers;
- gDevFS_Drivers = Dev;
- gDevFS_RootNode.Size ++;
- return giDevFS_NextID++;
+ int ret = 0;
+ tDevFS_Driver *dev;
+
+ LOCK( &glDevFS_ListLock );
+
+ // Check if the device is already registered or the name is taken
+ for( dev = gDevFS_Drivers; dev; dev = dev->Next )
+ {
+ if(dev == Device) break;
+ if(strcmp(dev->Name, Device->Name) == 0) break;
+ }
+
+ if(dev) {
+ if(dev == Device)
+ Log_Warning("DevFS", "Device %p '%s' attempted to register itself twice",
+ dev, dev->Name);
+ else
+ Log_Warning("DevFS", "Device %p attempted to register '%s' which was owned by %p",
+ Device, dev->Name, dev);
+ ret = 0; // Error
+ }
+ else {
+ Device->Next = gDevFS_Drivers;
+ gDevFS_Drivers = Device;
+ gDevFS_RootNode.Size ++;
+ ret = giDevFS_NextID ++;
+ }
+ RELEASE( &glDevFS_ListLock );
+
+ return ret;
+}
+
+/**
+ * \brief Delete a device from the DevFS folder
+ */
+void DevFS_DelDevice(tDevFS_Driver *Device)
+{
+ tDevFS_Driver *prev = NULL, *dev;
+
+ LOCK( &glDevFS_ListLock );
+ // Search list for device
+ for(dev = gDevFS_Drivers;
+ dev && dev != Device;
+ prev = dev, dev = dev->Next
+ );
+
+ // Check if it was found
+ if(dev)
+ {
+ if(prev)
+ prev->Next = Device->Next;
+ else
+ gDevFS_Drivers = Device->Next;
+ }
+ else
+ Log_Warning("DevFS", "Attempted to unregister device %p '%s' which was not registered",
+ Device, Device->Name);
+
+ RELEASE( &glDevFS_ListLock );
}
/**
dev = dev->Next
);
- return strdup(dev->Name);
+ if(dev)
+ return strdup(dev->Name);
+ else
+ return NULL;
}
/**
// --- EXPORTS ---
EXPORT(DevFS_AddDevice);
+EXPORT(DevFS_DelDevice);
#define INT\r
\r
// === TYPES ===\r
-typedef struct {\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
}\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
+tBGA_Mode gpBGA_CurrentMode;\r
+const tBGA_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
+ {1024,768,32, 0, 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 < 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
*/\r
void BGA_Uninstall()\r
{\r
- //DevFS_DelDevice( giBGA_DriverId );\r
+ DevFS_DelDevice( &gBGA_DriverStruct );\r
MM_UnmapHWPage( VBE_DISPI_LFB_PHYSICAL_ADDRESS, 768 );\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
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
- }\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 pitch = gpBGA_CurrentMode->width * giVT_CharWidth;\r
int x, y;\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
+ x = (off % gpBGA_CurrentMode->width) * giVT_CharWidth;\r
+ y = (off / gpBGA_CurrentMode->width) * giVT_CharHeight;\r
+ \r
+ // Sanity Check\r
+ if(y > gpBGA_CurrentMode->height) {\r
+ LEAVE('i', 0);\r
+ return 0;\r
+ }\r
+ \r
dest += y * pitch;\r
dest += x * giVT_CharWidth;\r
len /= sizeof(tVT_Char);\r
dest += pitch*(giVT_CharHeight-1);\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
gBGA_Modes[id].height);\r
\r
giBGA_CurrentMode = id;\r
+ gpBGA_CurrentMode = &gBGA_Modes[id];\r
return id;\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
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
hdr->Destination = Address;
hdr->HeaderChecksum = IPv4_Checksum(hdr, sizeof(tIPv4Header));
- Log("[IPv4 ] Sending packet to %i.%i.%i.%i",
+ Log_Log("IPv4", "Sending packet to %i.%i.%i.%i",
Address.B[0], Address.B[1], Address.B[2], Address.B[3]);
Link_SendPacket(Iface->Adapter, IPV4_ETHERNET_ID, to, bufSize, buf);
return 1;
int dataLength;
if(Length < sizeof(tIPv4Header)) return;
- //Log("[IPv4 ] Version = %i", hdr->Version);
- Log("[IPv4 ] HeaderLength = %i", hdr->HeaderLength);
- Log("[IPv4 ] DiffServices = %i", hdr->DiffServices);
- Log("[IPv4 ] TotalLength = %i", ntohs(hdr->TotalLength) );
- //Log("[IPv4 ] Identifcation = %i", ntohs(hdr->Identifcation) );
- //Log("[IPv4 ] TTL = %i", hdr->TTL );
- Log("[IPv4 ] Protocol = %i", hdr->Protocol );
- //Log("[IPv4 ] HeaderChecksum = 0x%x", ntohs(hdr->HeaderChecksum) );
- Log("[IPv4 ] Source = %i.%i.%i.%i",
+ //Log_Log("IPv4", "Version = %i", hdr->Version);
+ Log_Log("IPv4", "HeaderLength = %i", hdr->HeaderLength);
+ Log_Log("IPv4", "DiffServices = %i", hdr->DiffServices);
+ Log_Log("IPv4", "TotalLength = %i", ntohs(hdr->TotalLength) );
+ //Log_Log("IPv4", "Identifcation = %i", ntohs(hdr->Identifcation) );
+ //Log_Log("IPv4", "TTL = %i", hdr->TTL );
+ Log_Log("IPv4", "Protocol = %i", hdr->Protocol );
+ //Log_Log("IPv4", "HeaderChecksum = 0x%x", ntohs(hdr->HeaderChecksum) );
+ Log_Log("IPv4", "Source = %i.%i.%i.%i",
hdr->Source.B[0], hdr->Source.B[1], hdr->Source.B[2], hdr->Source.B[3] );
- Log("[IPv4 ] Destination = %i.%i.%i.%i",
+ Log_Log("IPv4", "Destination = %i.%i.%i.%i",
hdr->Destination.B[0], hdr->Destination.B[1],
hdr->Destination.B[2], hdr->Destination.B[3] );
// Check that the version IS IPv4
if(hdr->Version != 4) {
- Log("[IPv4 ] hdr->Version(%i) != 4", hdr->Version);
+ Log_Log("IPv4", "hdr->Version(%i) != 4", hdr->Version);
return;
}
// Check Packet length
if( ntohs(hdr->TotalLength) > Length) {
- Log("[IPv4 ] hdr->TotalLength(%i) > Length(%i)", ntohs(hdr->TotalLength), Length);
+ Log_Log("IPv4", "hdr->TotalLength(%i) > Length(%i)", ntohs(hdr->TotalLength), Length);
return;
}
// Get Interface (allowing broadcasts)
iface = IPv4_GetInterface(Adapter, hdr->Destination, 1);
if(!iface) {
- Log("[IPv4 ] Ignoring Packet (Not for us)");
+ Log_Log("IPv4", "Ignoring Packet (Not for us)");
return; // Not for us? Well, let's ignore it
}
if( gaIPv4_Callbacks[hdr->Protocol] )
gaIPv4_Callbacks[hdr->Protocol] (iface, &hdr->Source, dataLength, data);
else
- Log("[IPv4 ] Unknown Protocol %i", hdr->Protocol);
+ Log_Log("IPv4", "Unknown Protocol %i", hdr->Protocol);
}
/**
for( i = giRegisteredTypes; i -- ; )
{
if(gaRegisteredTypes[i].Type == Type) {
- Warning("[NET ] Attempt to register 0x%x twice", Type);
+ Log_Warning("NET", "Attempt to register 0x%x twice", Type);
return ;
}
// Ooh! Free slot!
{
tmp = realloc(gaRegisteredTypes, (giRegisteredTypes+1)*sizeof(*gaRegisteredTypes));
if(!tmp) {
- Warning("[NET ] Out of heap space!");
+ Log_Warning("NET", "Out of heap space!");
return ;
}
i = giRegisteredTypes;
Uint8 buf[bufSize]; // dynamic stack arrays ftw!
tEthernetHeader *hdr = (void*)buf;
- Log("[NET ] Sending %i bytes to %02x:%02x:%02x:%02x:%02x:%02x (Type 0x%x)",
+ Log_Log("NET", "Sending %i bytes to %02x:%02x:%02x:%02x:%02x:%02x (Type 0x%x)",
Length, To.B[0], To.B[1], To.B[2], To.B[3], To.B[4], To.B[5], Type);
hdr->Dest = To;
int tid = Proc_SpawnWorker(); // Create a new worker thread
if(tid < 0) {
- Warning("[NET ] Unable to create watcher thread for '%s'", Adapter->Device);
+ Log_Warning("NET", "Unable to create watcher thread for '%s'", Adapter->Device);
return ;
}
if(tid > 0) {
- Log("[NET ] Watching '%s' using tid %i", Adapter->Device, tid);
+ Log_Log("NET", "Watching '%s' using tid %i", Adapter->Device, tid);
return ;
}
if(ret == -1) break;
if(ret <= sizeof(tEthernetHeader)) {
- Log("[NET ] Recieved an undersized packet");
+ Log_Log("NET", "Recieved an undersized packet");
continue;
}
- Log("[NET ] Packet from %02x:%02x:%02x:%02x:%02x:%02x",
+ Log_Log("NET", "Packet from %02x:%02x:%02x:%02x:%02x:%02x",
hdr->Src.B[0], hdr->Src.B[1], hdr->Src.B[2],
hdr->Src.B[3], hdr->Src.B[4], hdr->Src.B[5]
);
- Log("[NET ] to %02x:%02x:%02x:%02x:%02x:%02x",
+ Log_Log("NET", "to %02x:%02x:%02x:%02x:%02x:%02x",
hdr->Dest.B[0], hdr->Dest.B[1], hdr->Dest.B[2],
hdr->Dest.B[3], hdr->Dest.B[4], hdr->Dest.B[5]
);
checksum = *(Uint32*)&hdr->Data[ret-sizeof(tEthernetHeader)-4];
- Log("[NET ] Checksum 0x%08x", checksum);
+ Log_Log("NET", "Checksum 0x%08x", checksum);
// Check if there is a registered callback for this packet type
for( i = giRegisteredTypes; i--; )
}
// No? Ignore it
if( i == -1 ) {
- Log("[NET ] Unregistered type 0x%x", ntohs(hdr->Type));
+ Log_Log("NET", "Unregistered type 0x%x", ntohs(hdr->Type));
continue;
}
);
}
- Log("[NET ] Watcher terminated (file closed)");
+ Log_Log("NET", "Watcher terminated (file closed)");
}
// From http://www.cl.cam.ac.uk/research/srg/bluebook/21/crc/node6.html
{
tSocketFile *file = gIP_FileTemplates;
while(Pos-- && file) {
- Log("IPStack_Iface_ReadDir: %s", file->Name);
file = file->Next;
}
for(;file;file = file->Next)
{
if( strcmp(file->Name, Name) == 0 ) break;
- Log("IPStack_Iface_FindDir: strcmp('%s', '%s')", file->Name, Name);
}
if(!file) return NULL;
int IPStack_AddInterface(char *Device)
{
tInterface *iface;
+ tAdapter *card;
ENTER("sDevice", Device);
+ card = IPStack_GetAdapter(Device);
+
iface = malloc(sizeof(tInterface));
if(!iface) {
LEAVE('i', -2);
// Create Node
iface->Node.ImplPtr = iface;
- iface->Node.ImplInt = giIP_NextIfaceId++;
iface->Node.Flags = VFS_FFLAG_DIRECTORY;
iface->Node.Size = -1;
iface->Node.NumACLs = 1;
return -1; // Return ERR_YOUFAIL
}
+ // Delay setting ImplInt until after the adapter is opened
+ // Keeps things simple
+ iface->Node.ImplInt = giIP_NextIfaceId++;
+
// Append to list
LOCK( &glIP_Interfaces );
if( gIP_Interfaces ) {
tTCPListener *srv;
tTCPConnection *conn;
- Log("[TCP ] SourcePort = %i, DestPort = %i",
+ Log_Log("TCP", "SourcePort = %i, DestPort = %i",
ntohs(hdr->SourcePort), ntohs(hdr->DestPort));
- Log("[TCP ] SequenceNumber = 0x%x", ntohl(hdr->SequenceNumber));
- Log("[TCP ] AcknowlegementNumber = 0x%x", ntohl(hdr->AcknowlegementNumber));
- Log("[TCP ] DataOffset = %i", hdr->DataOffset >> 4);
- Log("[TCP ] Flags = {");
- Log("[TCP ] CWR = %B, ECE = %B",
+ Log_Log("TCP", "SequenceNumber = 0x%x", ntohl(hdr->SequenceNumber));
+ Log_Log("TCP", "AcknowlegementNumber = 0x%x", ntohl(hdr->AcknowlegementNumber));
+ Log_Log("TCP", "DataOffset = %i", hdr->DataOffset >> 4);
+ Log_Log("TCP", "Flags = {");
+ Log_Log("TCP", " CWR = %B, ECE = %B",
!!(hdr->Flags & TCP_FLAG_CWR), !!(hdr->Flags & TCP_FLAG_ECE));
- Log("[TCP ] URG = %B, ACK = %B",
+ Log_Log("TCP", " URG = %B, ACK = %B",
!!(hdr->Flags & TCP_FLAG_URG), !!(hdr->Flags & TCP_FLAG_ACK));
- Log("[TCP ] PSH = %B, RST = %B",
+ Log_Log("TCP", " PSH = %B, RST = %B",
!!(hdr->Flags & TCP_FLAG_PSH), !!(hdr->Flags & TCP_FLAG_RST));
- Log("[TCP ] SYN = %B, FIN = %B",
+ Log_Log("TCP", " SYN = %B, FIN = %B",
!!(hdr->Flags & TCP_FLAG_SYN), !!(hdr->Flags & TCP_FLAG_FIN));
- Log("[TCP ] }");
- Log("[TCP ] WindowSize = %i", htons(hdr->WindowSize));
- Log("[TCP ] Checksum = 0x%x", htons(hdr->Checksum));
- Log("[TCP ] UrgentPointer = 0x%x", htons(hdr->UrgentPointer));
+ Log_Log("TCP", "}");
+ Log_Log("TCP", "WindowSize = %i", htons(hdr->WindowSize));
+ Log_Log("TCP", "Checksum = 0x%x", htons(hdr->Checksum));
+ Log_Log("TCP", "UrgentPointer = 0x%x", htons(hdr->UrgentPointer));
if( Length > (hdr->DataOffset >> 4)*4 )
{
// Check the destination port
if(srv->Port != htons(hdr->DestPort)) continue;
- Log("[TCP ] Matches server %p", srv);
+ Log_Log("TCP", "Matches server %p", srv);
// Is this in an established connection?
for( conn = srv->Connections; conn; conn = conn->Next )
{
- Log("[TCP ] conn->Interface(%p) == Interface(%p)",
+ Log_Log("TCP", "conn->Interface(%p) == Interface(%p)",
conn->Interface, Interface);
// Check that it is coming in on the same interface
if(conn->Interface != Interface) continue;
// Check Source Port
- Log("[TCP ] conn->RemotePort(%i) == hdr->SourcePort(%i)",
+ Log_Log("TCP", "conn->RemotePort(%i) == hdr->SourcePort(%i)",
conn->RemotePort, ntohs(hdr->SourcePort));
if(conn->RemotePort != ntohs(hdr->SourcePort)) continue;
if(conn->Interface->Type == 4 && !IP4_EQU(conn->RemoteIP.v4, *(tIPv4*)Address))
continue;
- Log("[TCP ] Matches connection %p", conn);
+ Log_Log("TCP", "Matches connection %p", conn);
// We have a response!
TCP_INT_HandleConnectionPacket(conn, hdr, Length);
return;
}
- Log("[TCP ] Opening Connection");
+ Log_Log("TCP", "Opening Connection");
// Open a new connection (well, check that it's a SYN)
if(hdr->Flags != TCP_FLAG_SYN) {
- Log("[TCP ] Packet is not a SYN");
+ Log_Log("TCP", "Packet is not a SYN");
return ;
}
}
}
- Log("[TCP ] No Match");
+ Log_Log("TCP", "No Match");
}
/**
// Get length of data
dataLen = Length - (Header->DataOffset>>4)*4;
- Log("[TCP ] HandleConnectionPacket - dataLen = %i", dataLen);
+ Log_Log("TCP", "HandleConnectionPacket - dataLen = %i", dataLen);
if(Header->Flags & TCP_FLAG_ACK) {
// TODO: Process an ACKed Packet
- Log("[TCP ] Conn %p, Packet 0x%x ACKed", Connection, Header->AcknowlegementNumber);
+ Log_Log("TCP", "Conn %p, Packet 0x%x ACKed", Connection, Header->AcknowlegementNumber);
}
if(dataLen == 0) return ;
{
tTCPStoredPacket *tmp, *prev = NULL;
- Log("[TCP ] Out of sequence packet (0x%08x != 0x%08x)",
+ Log_Log("TCP", "Out of sequence packet (0x%08x != 0x%08x)",
pkt->Sequence, Connection->NextSequenceRcv);
// No? Well, let's cache it and look at it later
// --- Server
tVFS_Node *TCP_Server_Init(tInterface *Interface)
{
- tTCPListener *srv = malloc( sizeof(tTCPListener) );
+ tTCPListener *srv;
+
+ srv = malloc( sizeof(tTCPListener) );
Log_Debug("TCP", "srv = %p", srv);
tTCPConnection *conn;
char *ret;
- Log("[TCP ] Thread %i waiting for a connection", Threads_GetTID());
+ Log_Log("TCP", "Thread %i waiting for a connection", Threads_GetTID());
for(;;)
{
LOCK( &srv->lConnections );
else // Else, mark this as used
TCP_AllocatePort(srv->Port);
- Log("[TCP ] Server %p listening on port %i", srv, srv->Port);
+ Log_Log("TCP", "Server %p listening on port %i", srv, srv->Port);
return srv->Port;
}