X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FDisplay%2FVESA%2Fmain.c;h=479be3028d905fb3da2a511145d18986b4116dbb;hb=8c50e4a0672bdf9e9f6266fa5f485ad7f8b74f5b;hp=703e708f8c043c45ee7e36df126e122c61dd48e1;hpb=9eec1cc1efa9d3fabc1b040c194dbb1394f13533;p=tpg%2Facess2.git diff --git a/Modules/Display/VESA/main.c b/Modules/Display/VESA/main.c index 703e708f..479be302 100644 --- a/Modules/Display/VESA/main.c +++ b/Modules/Display/VESA/main.c @@ -2,7 +2,7 @@ * AcessOS 1 * Video BIOS Extensions (Vesa) Driver */ -#define DEBUG 0 +#define DEBUG 1 #define VERSION 0x100 #include @@ -16,7 +16,10 @@ // === CONSTANTS === #define FLAG_LFB 0x1 #define VESA_DEFAULT_FRAMEBUFFER (KERNEL_BASE|0xA0000) -#define VESA_CURSOR_PERIOD 1000 +#define BLINKING_CURSOR 1 +#if BLINKING_CURSOR +# define VESA_CURSOR_PERIOD 1000 +#endif // === PROTOTYPES === int Vesa_Install(char **Arguments); @@ -41,13 +44,14 @@ tDevFS_Driver gVesa_DriverStruct = { .IOCtl = Vesa_Ioctl } }; -tSpinlock glVesa_Lock; +tMutex glVesa_Lock; tVM8086 *gpVesa_BiosState; int giVesaDriverId = -1; // --- Video Modes --- int giVesaCurrentMode = 0; int giVesaCurrentFormat = VIDEO_BUFFMT_TEXT; tVesa_Mode *gVesa_Modes; +tVesa_Mode *gpVesaCurMode; int giVesaModeCount = 0; // --- Framebuffer --- char *gpVesa_Framebuffer = (void*)VESA_DEFAULT_FRAMEBUFFER; @@ -89,13 +93,15 @@ int Vesa_Install(char **Arguments) return MODULE_ERR_NOTNEEDED; } - Log_Debug("VESA", "info->VideoModes = %04x:%04x", info->VideoModes.seg, info->VideoModes.ofs); + //Log_Debug("VESA", "info->VideoModes = %04x:%04x", info->VideoModes.seg, info->VideoModes.ofs); modes = (Uint16 *) VM8086_GetPointer(gpVesa_BiosState, info->VideoModes.seg, info->VideoModes.ofs); // Read Modes for( giVesaModeCount = 0; modes[giVesaModeCount] != 0xFFFF; giVesaModeCount++ ); gVesa_Modes = (tVesa_Mode *)malloc( giVesaModeCount * sizeof(tVesa_Mode) ); + Log_Debug("VESA", "%i Modes", giVesaModeCount); + // Insert Text Mode gVesa_Modes[0].width = 80; gVesa_Modes[0].height = 25; @@ -249,12 +255,17 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) ); // Sanity Check + if( Offset > (Uint64)(heightInChars*widthInChars) ) { + LEAVE('i', 0); + return 0; + } if(y >= heightInChars) { LEAVE('i', 0); return 0; } - if( Offset + Length > heightInChars*widthInChars ) { + + if( (int)Offset + (int)Length > heightInChars*widthInChars ) { Log_Debug("VESA", "%i + %i > %i*%i (%i)", (int)Offset, (int)Length, heightInChars, widthInChars, heightInChars*widthInChars); Length = heightInChars*widthInChars - Offset; @@ -266,7 +277,7 @@ Uint64 Vesa_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) LOG("dest = %p", dest); - for( i = 0; i < Length; i++ ) + for( i = 0; i < (int)Length; i++ ) { VT_Font_Render( chars->Ch, @@ -357,22 +368,37 @@ int Vesa_Ioctl(tVFS_Node *Node, int ID, void *Data) return ret; case VIDEO_IOCTL_SETCURSOR: // Set cursor position + #if !BLINKING_CURSOR + if(giVesaCursorX > 0) + Vesa_FlipCursor(Node); + #endif giVesaCursorX = ((tVideo_IOCtl_Pos*)Data)->x; giVesaCursorY = ((tVideo_IOCtl_Pos*)Data)->y; + //Log_Debug("VESA", "Cursor position (%i,%i)", giVesaCursorX, giVesaCursorY); if( giVesaCursorX < 0 || giVesaCursorY < 0 - || giVesaCursorX >= gVesa_Modes[giVesaCurrentMode].width - || giVesaCursorY >= gVesa_Modes[giVesaCurrentMode].height) + || giVesaCursorX >= gpVesaCurMode->width/giVT_CharWidth + || giVesaCursorY >= gpVesaCurMode->height/giVT_CharHeight) { - if(giVesaCursorTimer != -1) + #if BLINKING_CURSOR + if(giVesaCursorTimer != -1) { Time_RemoveTimer(giVesaCursorTimer); + giVesaCursorTimer = -1; + } + #endif giVesaCursorX = -1; giVesaCursorY = -1; } else { + #if BLINKING_CURSOR + // Log_Debug("VESA", "Updating timer %i?", giVesaCursorTimer); if(giVesaCursorTimer == -1) giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Node); + #else + Vesa_FlipCursor(Node); + #endif } + //Log_Debug("VESA", "Cursor position (%i,%i) Timer %i", giVesaCursorX, giVesaCursorY, giVesaCursorTimer); return 0; case VIDEO_IOCTL_REQLFB: // Request Linear Framebuffer @@ -395,8 +421,9 @@ int Vesa_Int_SetMode(int mode) if(mode == giVesaCurrentMode) return 1; Time_RemoveTimer(giVesaCursorTimer); + giVesaCursorTimer = -1; - LOCK( &glVesa_Lock ); + Mutex_Acquire( &glVesa_Lock ); gpVesa_BiosState->AX = 0x4F02; gpVesa_BiosState->BX = gVesa_Modes[mode].code; @@ -419,8 +446,9 @@ int Vesa_Int_SetMode(int mode) // Record Mode Set giVesaCurrentMode = mode; + gpVesaCurMode = &gVesa_Modes[giVesaCurrentMode]; - RELEASE( &glVesa_Lock ); + Mutex_Release( &glVesa_Lock ); return 1; } @@ -482,18 +510,30 @@ int Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data) */ void Vesa_FlipCursor(void *Arg) { - int pitch = gVesa_Modes[giVesaCurrentMode].pitch/4; + int pitch = gpVesaCurMode->pitch/4; int x = giVesaCursorX*giVT_CharWidth; int y = giVesaCursorY*giVT_CharHeight; int i; Uint32 *fb = (void*)gpVesa_Framebuffer; - if(giVesaCursorX < 0 || giVesaCursorY < 0) return; + //Debug("Cursor flip"); - for( i = 1; i < giVT_CharHeight-1; i++ ) - fb[(y+i)*pitch+x] = ~fb[(y+i)*pitch+x]; + // Sanity check + if(giVesaCursorX < 0 || giVesaCursorY < 0 + || y*pitch + x + (giVT_CharHeight-1)*pitch > (int)gpVesaCurMode->fbSize/4) { + Log_Notice("VESA", "Cursor OOB (%i,%i)", x, y); + giVesaCursorTimer = -1; + return; + } + // Draw cursor + fb += (y+1)*pitch + x; + for( i = 1; i < giVT_CharHeight-1; i++, fb += pitch ) + *fb = ~*fb; + + #if BLINKING_CURSOR giVesaCursorTimer = Time_CreateTimer(VESA_CURSOR_PERIOD, Vesa_FlipCursor, Arg); + #endif } // ------------------------ @@ -501,11 +541,11 @@ void Vesa_FlipCursor(void *Arg) // ------------------------ void Vesa_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colour) { - int scrnwidth = gVesa_Modes[giVesaCurrentMode].width; - Uint32 *buf = (Uint32*)gpVesa_Framebuffer + Y*scrnwidth + X; + int pitch = gpVesaCurMode->pitch/4; + Uint32 *buf = (Uint32*)gpVesa_Framebuffer + Y*pitch + X; while( H -- ) { memsetd(buf, Colour, W); - buf += scrnwidth; + buf += pitch; } }