VESA - Debugging issue on VIA S3 BIOS
authorJohn Hodge <[email protected]>
Sun, 22 Apr 2012 09:36:15 +0000 (17:36 +0800)
committerJohn Hodge <[email protected]>
Sun, 22 Apr 2012 09:36:15 +0000 (17:36 +0800)
KernelLand/Kernel/arch/x86/irq.c
KernelLand/Kernel/arch/x86/vm8086.c
KernelLand/Kernel/debug.c
KernelLand/Kernel/drv/vterm.c
KernelLand/Kernel/drv/vterm_output.c
KernelLand/Kernel/drvutil.c
KernelLand/Modules/Display/VESA/common.h
KernelLand/Modules/Display/VESA/main.c

index e2dcf0e..3d23636 100644 (file)
@@ -26,6 +26,7 @@ void  *gaIRQ_DataPointers[16][MAX_CALLBACKS_PER_IRQ];
 void IRQ_Handler(tRegs *Regs)
 {
         int    i, irq = Regs->int_num - 0xF0;
+        int    bHandled = 0;
 
        //Log("IRQ_Handler: (Regs={int_num:%i})", Regs->int_num);
 
@@ -37,8 +38,13 @@ void IRQ_Handler(tRegs *Regs)
                        if( irq != 8 )
                                Log("IRQ %i: Call %p", Regs->int_num, gIRQ_Handlers[Regs->int_num][i]);
                        #endif
+                       bHandled = 1;
                }
        }
+       
+       if( !bHandled ) {
+               Log_Debug("IRQ", "Unhandled IRQ %i", irq);
+       }
 
        //Log(" IRQ_Handler: Resetting");
        if(irq >= 8)
index 6134862..f4e98c4 100644 (file)
@@ -10,6 +10,8 @@
 #include <semaphore.h>
 
 // === CONSTANTS ===
+#define TRACE_EMU      0
+
 #define VM8086_MAGIC_CS        0xFFFF
 #define VM8086_MAGIC_IP        0x0010
 #define VM8086_STACK_SEG       0x9F00
@@ -54,6 +56,7 @@ tPID  gVM8086_WorkerPID;
 tTID   gVM8086_CallingThread;
 tVM8086        volatile * volatile gpVM8086_State = (void*)-1; // Set to -1 to avoid race conditions
 Uint32 gaVM8086_MemBitmap[VM8086_BLOCKCOUNT/32];
+ int   gbVM8086_ShadowIF = 0;
 
 // === FUNCTIONS ===
 int VM8086_Install(char **Arguments)
@@ -91,11 +94,11 @@ int VM8086_Install(char **Arguments)
                MM_Map( 0, 0 ); // IVT / BDA
                // Map (but allow allocation) of 0x1000 - 0x9F000
                // - So much hack, it isn't funny
+               // TODO: Remove this and replce with something less hacky
                for(i=1;i<0x9F;i++) {
                        MM_Map( i * 0x1000, i * 0x1000 );
-                       MM_DerefPhys( i * 0x1000 );     // Above
                        while(MM_GetRefCount(i*0x1000))
-                               MM_DerefPhys( i * 0x1000 );     // Phys setup
+                               MM_DerefPhys( i * 0x1000 );
                }
                MM_Map( 0x9F000, 0x9F000 );     // Stack / EBDA
                // System Stack / Stub
@@ -165,9 +168,12 @@ int VM8086_Install(char **Arguments)
 void VM8086_GPF(tRegs *Regs)
 {
        Uint8   opcode;
+       Uint16  newcs, newip;
        
 //     Log_Log("VM8086", "GPF - %04x:%04x", Regs->cs, Regs->eip);
-       
+
+       LOG("VM8086 GPF at %04x:%04x", Regs->cs, Regs->eip);
+
        if(Regs->eip == VM8086_MAGIC_IP && Regs->cs == VM8086_MAGIC_CS
        && Threads_GetPID() == gVM8086_WorkerPID)
        {
@@ -219,17 +225,24 @@ void VM8086_GPF(tRegs *Regs)
        case VM8086_OP_PUSHF:   //PUSHF
                Regs->esp -= 2;
                *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->eflags & 0xFFFF;
+               if( gbVM8086_ShadowIF )
+                       *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) |= 0x200;
+               else
+                       *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) &= ~0x200;
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated PUSHF");
+               Log_Debug("VM8086", "%04x:%04x Emulated PUSHF (value 0x%x)",
+                       Regs->cs, Regs->eip-1, Regs->eflags & 0xFFFF);
                #endif
                break;
        case VM8086_OP_POPF:    //POPF
                // Changing IF is not allowed
                Regs->eflags &= 0xFFFF0202;
                Regs->eflags |= *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) );
+               gbVM8086_ShadowIF = !!(*(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) & 0x200);
                Regs->esp += 2;
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated POPF");
+               Log_Debug("VM8086", "%04x:%04x Emulated POPF (new value 0x%x)",
+                       Regs->cs, Regs->eip-1, Regs->eflags & 0xFFFF);
                #endif
                break;
        
@@ -242,20 +255,26 @@ void VM8086_GPF(tRegs *Regs)
                Regs->esp -= 2; *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->cs;
                Regs->esp -= 2; *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->eip;
                
-               Regs->cs = *(Uint16*)(4*id + 2);
-               Regs->eip = *(Uint16*)(4*id);
+               newcs = *(Uint16*)(4*id + 2);
+               newip = *(Uint16*)(4*id);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated INT 0x%x", id);
+               Log_Debug("VM8086", "%04x:%04x Emulated INT 0x%x (%04x:%04x) - AX=%04x,BX=%04x",
+                       Regs->cs, Regs->eip-2, id, newcs, newip, Regs->eax, Regs->ebx);
                #endif
+               Regs->cs = newcs;
+               Regs->eip = newip;
                }
                break;
        
        case VM8086_OP_IRET:    //IRET
-               Regs->eip = *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) );     Regs->esp += 2;
-               Regs->cs  = *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) );     Regs->esp += 2;
+               newip = *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ); Regs->esp += 2;
+               newcs = *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ); Regs->esp += 2;
                #if TRACE_EMU
-               Log_Debug("VM8086", "IRET to %04x:%04x", Regs->cs, Regs->eip);
+               Log_Debug("VM8086", "%04x:%04x IRET to %04x:%04x",
+                       Regs->cs, Regs->eip-1, newcs, newip);
                #endif
+               Regs->cs = newcs;
+               Regs->eip = newip;
                break;
        
        
@@ -263,55 +282,72 @@ void VM8086_GPF(tRegs *Regs)
                Regs->eax &= 0xFFFFFF00;
                Regs->eax |= inb(Regs->edx&0xFFFF);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated IN AL, DX (Port 0x%x)\n", Regs->edx&0xFFFF);
+               Log_Debug("VM8086", "%04x:%04x Emulated IN AL, DX (Port 0x%x [Val 0x%02x])",
+                       Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax&0xFF);
                #endif
                break;
        case VM8086_OP_IN_ADX:  //IN AX, DX
                Regs->eax &= 0xFFFF0000;
                Regs->eax |= inw(Regs->edx&0xFFFF);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated IN AX, DX (Port 0x%x)\n", Regs->edx&0xFFFF);
+               Log_Debug("VM8086", "%04x:%04x Emulated IN AX, DX (Port 0x%x [Val 0x%04x])",
+                       Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax&0xFFFF);
                #endif
                break;
                
        case VM8086_OP_OUT_AD:  //OUT DX, AL
                outb(Regs->edx&0xFFFF, Regs->eax&0xFF);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated OUT DX, AL (*0x%04x = 0x%02x)\n", Regs->edx&0xFFFF, Regs->eax&0xFF);
+               Log_Debug("VM8086", "%04x:%04x Emulated OUT DX, AL (*0x%04x = 0x%02x)",
+                       Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax&0xFF);
                #endif
                break;
        case VM8086_OP_OUT_ADX: //OUT DX, AX
                outw(Regs->edx&0xFFFF, Regs->eax&0xFFFF);
                #if TRACE_EMU
-               Log_Debug("VM8086", "Emulated OUT DX, AX (*0x%04x = 0x%04x)\n", Regs->edx&0xFFFF, Regs->eax&0xFFFF);
+               Log_Debug("VM8086", "%04x:%04x Emulated OUT DX, AX (*0x%04x = 0x%04x)",
+                       Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax&0xFFFF);
                #endif
                break;
                
        // TODO: Decide on allowing VM8086 Apps to enable/disable interrupts
        case 0xFA:      //CLI
+               #if TRACE_EMU
+               Log_Debug("VM8086", "%04x:%04x Ignored CLI",
+                       Regs->cs, Regs->eip);
+               #endif
+               gbVM8086_ShadowIF = 0;
                break;
        case 0xFB:      //STI
+               #if TRACE_EMU
+               Log_Debug("VM8086", "%04x:%04x Ignored STI",
+                       Regs->cs, Regs->eip);
+               #endif
+               gbVM8086_ShadowIF = 1;
                break;
        
        case 0x66:
                opcode = *(Uint8*)( (Regs->cs*16) + (Regs->eip&0xFFFF));
+               Regs->eip ++;
                switch( opcode )
                {
                case VM8086_OP_IN_ADX:  //IN AX, DX
                        Regs->eax = ind(Regs->edx&0xFFFF);
                        #if TRACE_EMU
-                       Log_Debug("VM8086", "Emulated IN EAX, DX (Port 0x%x)\n", Regs->edx&0xFFFF);
+                       Log_Debug("VM8086", "%04x:%04x Emulated IN EAX, DX (Port 0x%x [Val 0x%08x])",
+                               Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax);
                        #endif
                        break;
                case VM8086_OP_OUT_ADX: //OUT DX, AX
                        outd(Regs->edx&0xFFFF, Regs->eax);
                        #if TRACE_EMU
-                       Log_Debug("VM8086", "Emulated OUT DX, EAX (*0x%04x = 0x%08x)\n", Regs->edx&0xFFFF, Regs->eax);
+                       Log_Debug("VM8086", "%04x:%04x Emulated OUT DX, EAX (*0x%04x = 0x%08x)",
+                               Regs->cs, Regs->eip-1, Regs->edx&0xFFFF, Regs->eax);
                        #endif
                        break;
                default:
                        Log_Error("VM8086", "Error - Unknown opcode 66 %02x caused a GPF at %04x:%04x",
-                               Regs->cs, Regs->eip,
+                               Regs->cs, Regs->eip-2,
                                opcode
                                );
                        // Force an end to the call
@@ -323,7 +359,7 @@ void VM8086_GPF(tRegs *Regs)
        
        default:
                Log_Error("VM8086", "Error - Unknown opcode %02x caused a GPF at %04x:%04x",
-                       opcode, Regs->cs, Regs->eip);
+                       opcode, Regs->cs, Regs->eip-1);
                // Force an end to the call
                Regs->cs = VM8086_MAGIC_CS;
                Regs->eip = VM8086_MAGIC_IP;
index 9edf126..6a50ca2 100644 (file)
@@ -1,17 +1,13 @@
 /*
  * AcessOS Microkernel Version
  * debug.c
- * 
- * TODO: Move the Debug_putchar methods out to the arch/ tree
  */
 #include <acess.h>
 #include <stdarg.h>
 
 #define        DEBUG_MAX_LINE_LEN      256
-
-#define        LOCK_DEBUG_OUTPUT       1
-
-#define TRACE_TO_KTERM 1
+#define        LOCK_DEBUG_OUTPUT       1       // Avoid interleaving of output lines?
+#define TRACE_TO_KTERM 0       // Send ENTER/DEBUG/LEAVE to debug?
 
 // === IMPORTS ===
 extern void    Threads_Dump(void);
index 5f4a25c..1cc60be 100644 (file)
@@ -758,6 +758,8 @@ void VT_SetTerminal(int ID)
        giVT_CurrentTerminal = ID;
        gpVT_CurTerm = &gVT_Terminals[ID];
        
+       LOG("Attempting VT_SetMode");
+       
        if( gpVT_CurTerm->Mode == TERM_MODE_TEXT )
        {
                VT_SetMode( VIDEO_BUFFMT_TEXT );
@@ -769,7 +771,9 @@ void VT_SetTerminal(int ID)
                        VFS_IOCtl(giVT_OutputDevHandle, VIDEO_IOCTL_SETCURSORBITMAP, gpVT_CurTerm->VideoCursor);
                VT_SetMode( VIDEO_BUFFMT_FRAMEBUFFER );
        }
-       
+
+       LOG("Mode set");        
+
        if(gpVT_CurTerm->Buffer)
        {
                // TODO: Handle non equal sized
@@ -779,9 +783,11 @@ void VT_SetTerminal(int ID)
                        gpVT_CurTerm->Width*gpVT_CurTerm->Height*sizeof(Uint32),
                        gpVT_CurTerm->Buffer
                        );
+               LOG("Updated screen contents");
        }
        
        VT_int_UpdateCursor(gpVT_CurTerm, 1);
        // Update the screen
        VT_int_UpdateScreen(gpVT_CurTerm, 1);
+       LOG("done");
 }
index 4d1c352..357132c 100644 (file)
@@ -7,7 +7,7 @@
  */
 #include "vterm.h"
 #include <api_drv_video.h>
-#define DEBUG  1
+#define DEBUG  0
 
 // === CODE ===
 /**
index d9bd92d..d2c86bf 100644 (file)
@@ -136,7 +136,7 @@ int DrvUtil_Video_WriteLFB(tDrvUtil_Video_BufInfo *FBInfo, size_t Offset, size_t
         int    x, y;
         int    bytes_per_px = (FBInfo->Depth + 7) / 8;
        ENTER("pFBInfo xOffset xLength pBuffer",
-               Mode, FBInfo, Offset, Length, Buffer);
+               FBInfo, Offset, Length, Buffer);
 
        csr_x = FBInfo->CursorX;
        csr_y = FBInfo->CursorY;
@@ -287,9 +287,12 @@ int DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bi
         int    csrX = Buf->CursorX, csrY = Buf->CursorY;
        size_t  size;
 
+       ENTER("pBuf pBitmap", Buf, Bitmap);
+
        // Clear old bitmap
        if( Buf->CursorBitmap )
        {
+               LOG("Clearing old cursor");
                DrvUtil_Video_RemoveCursor(Buf);
                if( !Bitmap || Bitmap->W != Buf->CursorBitmap->W || Bitmap->H != Buf->CursorBitmap->H )
                {
@@ -306,24 +309,29 @@ int DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bi
        {
                Buf->CursorX = -1;
                Buf->CursorY = -1;
+               LEAVE('i', 0);
                return 0;
        }
 
        // Sanity check the bitmap
+       LOG("Sanity checking plox");
        if( !CheckMem(Bitmap, sizeof(*Bitmap)) || !CheckMem(Bitmap->Data, Bitmap->W*Bitmap->H*sizeof(Uint32)) )
        {
                Log_Warning("DrvUtil", "DrvUtil_Video_SetCursor: Bitmap (%p) is in invalid memory", Bitmap);
                errno = -EINVAL;
+               LEAVE('i', -1);
                return -1;
        }
 
        // Don't take a copy of the DrvUtil provided cursor
        if( Bitmap == &gDrvUtil_TextModeCursor )
        {
+               LOG("No copy (provided cursor)");
                Buf->CursorBitmap = Bitmap;
        }
        else
        {
+               LOG("Make copy");
                size = sizeof(tVideo_IOCtl_Bitmap) + Bitmap->W*Bitmap->H*4;
                
                // Take a copy
@@ -332,7 +340,9 @@ int DrvUtil_Video_SetCursor(tDrvUtil_Video_BufInfo *Buf, tVideo_IOCtl_Bitmap *Bi
        }
        
        // Restore cursor position
+       LOG("Drawing");
        DrvUtil_Video_DrawCursor(Buf, csrX, csrY);
+       LEAVE('i', 0);
        return 0;
 }
 
@@ -340,24 +350,30 @@ void DrvUtil_Video_DrawCursor(tDrvUtil_Video_BufInfo *Buf, int X, int Y)
 {
         int    render_ox=0, render_oy=0, render_w, render_h;
 
+       ENTER("pBuf iX iY", Buf, X, Y);
        DrvUtil_Video_RemoveCursor(Buf);
 
        // X < 0 disables the cursor
        if( X < 0 ) {
                Buf->CursorX = -1;
+               LEAVE('-');
                return ;
        }
 
        // Sanity checking
-       if( X < 0 || Y < 0 )    return;
-       if( X >= Buf->Width || Y >= Buf->Height )       return;
+       if( X < 0 || Y < 0 || X >= Buf->Width || Y >= Buf->Height ) {
+               LEAVE('-');
+               return ;
+       }
 
        // Ensure the cursor is enabled
-       if( !Buf->CursorBitmap )        return ;
+       if( !Buf->CursorBitmap ) {
+               LEAVE('-');
+               return ;
+       }
        
        // Save cursor position (for changing the bitmap)
        Buf->CursorX = X;       Buf->CursorY = Y;
-
        // Apply cursor's center offset
        X -= Buf->CursorBitmap->XOfs;
        Y -= Buf->CursorBitmap->YOfs;
@@ -375,8 +391,12 @@ void DrvUtil_Video_DrawCursor(tDrvUtil_Video_BufInfo *Buf, int X, int Y)
        Buf->CursorDestX   = X;         Buf->CursorDestY = Y;
        Buf->CursorReadX   = render_ox; Buf->CursorReadY = render_oy;
 
+       LOG("%ix%i at %i,%i offset %i,%i",
+               render_w, render_h, X, Y, render_ox, render_oy);
+
        // Call render routine
        DrvUtil_Video_RenderCursor(Buf);
+       LEAVE('-');
 }
 
 void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
@@ -393,10 +413,13 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
        dest = (Uint8*)Buf->Framebuffer + dest_y*Buf->Pitch + dest_x*bytes_per_px;
        src = Buf->CursorBitmap->Data + src_y * Buf->CursorBitmap->W + src_x;
        
+       LOG("dest = %p, src = %p", dest, src);
+
        // Allocate save buffer if not already
        if( !Buf->CursorSaveBuf )
                Buf->CursorSaveBuf = malloc( Buf->CursorBitmap->W*Buf->CursorBitmap->H*bytes_per_px );
 
+       LOG("Saving back");
        // Save behind the cursor
        for( y = 0; y < render_h; y ++ )
                memcpy(
@@ -413,6 +436,7 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
                Log_Warning("DrvUtil", "TODO: Support 15/16 bpp modes in cursor draw");
                break;
        case 24:
+               LOG("24-bit render");
                for( y = 0; y < render_h; y ++ )
                {
                        Uint8   *px;
@@ -435,6 +459,7 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
                }
                break;
        case 32:
+               LOG("32-bit render");
                for( y = 0; y < render_h; y ++ )
                {
                        Uint32  *px;
@@ -448,6 +473,7 @@ void DrvUtil_Video_RenderCursor(tDrvUtil_Video_BufInfo *Buf)
                                else
                                        ;       // NOP, completely transparent
                        }
+                       LOG("row %i/%i (%p-%P) done", y+1, render_h, dest, MM_GetPhysAddr(dest));
                        src += Buf->CursorBitmap->W;
                        dest = (Uint8*)dest + Buf->Pitch;
                }
index eeaddd5..c81fe1a 100644 (file)
@@ -22,7 +22,24 @@ typedef struct sVesa_Mode
 
 typedef struct sVesa_CallModeInfo
 {
+       /**
+        * 0 : Mode is supported
+        * 1 : Optional information avaliable (Xres onwards)
+        * 2 : BIOS Output Supported
+        * 3 : Colour Mode?
+        * 4 : Graphics mode?
+        * -- VBE v2.0+
+        * 5 : Mode is not VGA compatible
+        * 6 : Bank switched mode supported
+        * 7 : Linear framebuffer mode supported
+        * 8 : Double-scan mode avaliable
+        */
        Uint16  attributes;
+       /**
+        * 0 : Window exists
+        * 1 : Window is readable
+        * 2 : Window is writable
+        */
        Uint8   winA,winB;
        Uint16  granularity;
        Uint16  winsize;
@@ -35,25 +52,32 @@ typedef struct sVesa_CallModeInfo
        Uint8   memory_model, bank_size, image_pages;
        Uint8   reserved0;
 
+       // -- VBE v1.2+
        Uint8   red_mask, red_position;
        Uint8   green_mask, green_position;
        Uint8   blue_mask, blue_position;
        Uint8   rsv_mask, rsv_position;
        Uint8   directcolor_attributes;
 
-       Uint32  physbase;  // Your LFB address ;)
-       Uint32  reserved1;
-       Sint16  reserved2;
+       // -- VBE v2.0+
+       Uint32  physbase;
+       Uint32  offscreen_ptr;  // Start of offscreen memory
+       Uint16  offscreen_size_kb;      // Size of offscreen memory
+       
+       // -- VBE v3.0
+       Uint16  lfb_pitch;
+       Uint8   image_count_banked;
+       Uint8   image_count_lfb;
 }      tVesa_CallModeInfo;
 
 typedef struct sVesa_CallInfo
 {
-   char                signature[4];           // == "VESA"
-   Uint16      Version;        // == 0x0300 for Vesa 3.0
-   tFarPtr     OEMString;      // isa vbeFarPtr
-   Uint8       Capabilities[4];        
-   tFarPtr     VideoModes;     // isa vbeParPtr
-   Uint16      TotalMemory;    // as # of 64KB blocks
+       char            signature[4];           // == "VESA"
+       Uint16  Version;        // == 0x0300 for Vesa 3.0
+       tFarPtr OEMString;      // isa vbeFarPtr
+       Uint8   Capabilities[4];        
+       tFarPtr VideoModes;     // isa vbeParPtr
+       Uint16  TotalMemory;    // as # of 64KB blocks
 }      tVesa_CallInfo;
 
 #endif
index 2dbc98c..c9e3c84 100644 (file)
@@ -16,6 +16,8 @@
 \r
 // === CONSTANTS ===\r
 #define        FLAG_LFB        0x1\r
+#define FLAG_POPULATED 0x2\r
+#define FLAG_VALID     0x4\r
 #define VESA_DEFAULT_FRAMEBUFFER       (KERNEL_BASE|0xA0000)\r
 #define BLINKING_CURSOR        1\r
 #if BLINKING_CURSOR\r
@@ -24,6 +26,7 @@
 \r
 // === PROTOTYPES ===\r
  int   Vesa_Install(char **Arguments);\r
+ int   VBE_int_GetModeList(void);\r
 size_t Vesa_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);\r
  int   Vesa_IOCtl(tVFS_Node *Node, int ID, void *Data);\r
  int   Vesa_Int_SetMode(int Mode);\r
@@ -67,6 +70,27 @@ tDrvUtil_Video_BufInfo       gVesa_BufInfo;
 \r
 // === CODE ===\r
 int Vesa_Install(char **Arguments)\r
+{\r
+        int    rv;\r
+       \r
+       gpVesa_BiosState = VM8086_Init();\r
+       \r
+       if( (rv = VBE_int_GetModeList()) )\r
+               return rv;\r
+               \r
+       #if BLINKING_CURSOR\r
+       // Create blink timer\r
+       gpVesaCursorTimer = Time_AllocateTimer( Vesa_FlipCursor, NULL );\r
+       #endif\r
+\r
+       // Install Device\r
+       giVesaDriverId = DevFS_AddDevice( &gVesa_DriverStruct );\r
+       if(giVesaDriverId == -1)        return MODULE_ERR_MISC;\r
+\r
+       return MODULE_ERR_OK;\r
+}\r
+\r
+int VBE_int_GetModeList(void)\r
 {\r
        tVesa_CallInfo  *info;\r
        tFarPtr infoPtr;\r
@@ -74,7 +98,6 @@ int Vesa_Install(char **Arguments)
        int     i;\r
        \r
        // Allocate Info Block\r
-       gpVesa_BiosState = VM8086_Init();\r
        info = VM8086_Allocate(gpVesa_BiosState, 512, &infoPtr.seg, &infoPtr.ofs);\r
        // Set Requested Version\r
        memcpy(info->signature, "VBE2", 4);\r
@@ -88,15 +111,16 @@ int Vesa_Install(char **Arguments)
                return MODULE_ERR_NOTNEEDED;\r
        }\r
        \r
-       //Log_Debug("VESA", "info->VideoModes = %04x:%04x", info->VideoModes.seg, info->VideoModes.ofs);\r
        modes = (Uint16 *) VM8086_GetPointer(gpVesa_BiosState, info->VideoModes.seg, info->VideoModes.ofs);\r
+//     VM8086_Deallocate( gpVesa_BiosState, info );\r
        \r
-       // Read Modes\r
+       // Count Modes\r
        for( giVesaModeCount = 0; modes[giVesaModeCount] != 0xFFFF; giVesaModeCount++ );\r
+       giVesaModeCount ++;     // First text mode\r
        gVesa_Modes = (tVesa_Mode *)malloc( giVesaModeCount * sizeof(tVesa_Mode) );\r
        \r
-       Log_Debug("VESA", "%i Modes", giVesaModeCount);\r
-       \r
+       Log_Debug("VBE", "%i Modes", giVesaModeCount);\r
+\r
        // Insert Text Mode\r
        gVesa_Modes[0].width = 80;\r
        gVesa_Modes[0].height = 25;\r
@@ -108,22 +132,103 @@ int Vesa_Install(char **Arguments)
        \r
        for( i = 1; i < giVesaModeCount; i++ )\r
        {\r
-               gVesa_Modes[i].code = modes[i];\r
+               gVesa_Modes[i].code = modes[i-1];\r
        }\r
-\r
-//     VM8086_Deallocate( info );\r
        \r
-       #if BLINKING_CURSOR\r
-       // Create blink timer\r
-       gpVesaCursorTimer = Time_AllocateTimer( Vesa_FlipCursor, NULL );\r
+       return 0;\r
+}\r
+\r
+void VBE_int_FillMode_Int(int Index, tVesa_CallModeInfo *vbeinfo, tFarPtr *BufPtr)\r
+{\r
+       tVesa_Mode      *mode = &gVesa_Modes[Index];\r
+\r
+       // Get Mode info\r
+       gpVesa_BiosState->AX = 0x4F01;\r
+       gpVesa_BiosState->CX = mode->code;\r
+       gpVesa_BiosState->ES = BufPtr->seg;\r
+       gpVesa_BiosState->DI = BufPtr->ofs;\r
+       VM8086_Int(gpVesa_BiosState, 0x10);\r
+\r
+       if( gpVesa_BiosState->AX != 0x004F ) {\r
+               Log_Error("VESA", "Getting info on mode 0x%x failed (AX=0x%x)",\r
+                       mode->code, gpVesa_BiosState->AX);\r
+               return ;\r
+       }\r
+\r
+       #define S_LOG(s, fld, fmt)      LOG(" ."#fld" = "fmt, (s).fld)\r
+       LOG("vbeinfo[0x%x] = {", mode->code);\r
+       S_LOG(*vbeinfo, attributes, "0x%02x");\r
+       S_LOG(*vbeinfo, winA, "0x%02x");\r
+       S_LOG(*vbeinfo, winB, "0x%02x");\r
+       S_LOG(*vbeinfo, granularity, "0x%04x");\r
+       S_LOG(*vbeinfo, winsize, "0x%04x");\r
+       S_LOG(*vbeinfo, segmentA, "0x%04x");\r
+       S_LOG(*vbeinfo, segmentB, "0x%04x");\r
+       LOG(" .realFctPtr = %04x:%04x", vbeinfo->realFctPtr.seg, vbeinfo->realFctPtr.ofs);\r
+       S_LOG(*vbeinfo, pitch, "0x%04x");\r
+       // -- Extended\r
+       S_LOG(*vbeinfo, Xres, "%i");\r
+       S_LOG(*vbeinfo, Yres, "%i");\r
+       S_LOG(*vbeinfo, Wchar, "%i");\r
+       S_LOG(*vbeinfo, Ychar, "%i");\r
+       S_LOG(*vbeinfo, planes, "%i");\r
+       S_LOG(*vbeinfo, bpp, "%i");\r
+       S_LOG(*vbeinfo, banks, "%i");\r
+       S_LOG(*vbeinfo, memory_model, "%i");\r
+       S_LOG(*vbeinfo, bank_size, "%i");\r
+       S_LOG(*vbeinfo, image_pages, "%i");\r
+       // -- VBE 1.2+\r
+       LOG(" Red   = %i bits at %i", vbeinfo->red_mask,   vbeinfo->red_position  );\r
+       LOG(" Green = %i bits at %i", vbeinfo->green_mask, vbeinfo->green_position);\r
+       LOG(" Blue  = %i bits at %i", vbeinfo->blue_mask,  vbeinfo->blue_position );\r
+       #if 0\r
+       Uint8   rsv_mask, rsv_position;\r
+       Uint8   directcolor_attributes;\r
        #endif\r
+       // --- VBE 2.0+\r
+       S_LOG(*vbeinfo, physbase, "0x%08x");\r
+       S_LOG(*vbeinfo, offscreen_ptr, "0x%08x");\r
+       S_LOG(*vbeinfo, offscreen_size_kb, "0x%04x");\r
+       // --- VBE 3.0+\r
+       S_LOG(*vbeinfo, lfb_pitch, "0x%04x");\r
+       S_LOG(*vbeinfo, image_count_banked, "%i");\r
+       S_LOG(*vbeinfo, image_count_lfb, "%i");\r
+       LOG("}");\r
 \r
-       // Install Device\r
-       giVesaDriverId = DevFS_AddDevice( &gVesa_DriverStruct );\r
-       if(giVesaDriverId == -1)        return MODULE_ERR_MISC;\r
+       mode->flags = FLAG_POPULATED;\r
+       if( !(vbeinfo->attributes & 1) ) {\r
+               #if DEBUG\r
+               Log_Log("VESA", "0x%x - not supported", mode->code);\r
+               #endif\r
+               mode->width = 0;\r
+               mode->height = 0;\r
+               mode->bpp = 0;\r
+               return ;\r
+       }\r
 \r
-       return MODULE_ERR_OK;\r
-}\r
+       // Parse Info\r
+       mode->flags |= FLAG_VALID;\r
+       if ( (vbeinfo->attributes & 0x90) == 0x90 )\r
+       {\r
+               mode->flags |= FLAG_LFB;\r
+               mode->framebuffer = vbeinfo->physbase;\r
+               mode->fbSize = vbeinfo->Yres*vbeinfo->pitch;\r
+       } else {\r
+               mode->framebuffer = 0;\r
+               mode->fbSize = 0;\r
+       }\r
+       \r
+       mode->pitch = vbeinfo->pitch;\r
+       mode->width = vbeinfo->Xres;\r
+       mode->height = vbeinfo->Yres;\r
+       mode->bpp = vbeinfo->bpp;\r
+       \r
+       #if DEBUG\r
+       Log_Log("VESA", "#%i 0x%x - %ix%ix%i (%x)",\r
+               Index, mode->code, mode->width, mode->height, mode->bpp, mode->flags);\r
+       #endif\r
+\r
+} \r
 \r
 void Vesa_int_FillModeList(void)\r
 {\r
@@ -133,40 +238,12 @@ void Vesa_int_FillModeList(void)
                tVesa_CallModeInfo      *modeinfo;\r
                tFarPtr modeinfoPtr;\r
                \r
-               modeinfo = VM8086_Allocate(gpVesa_BiosState, 512, &modeinfoPtr.seg, &modeinfoPtr.ofs);\r
+               modeinfo = VM8086_Allocate(gpVesa_BiosState, 256, &modeinfoPtr.seg, &modeinfoPtr.ofs);\r
                for( i = 1; i < giVesaModeCount; i ++ )\r
                {\r
-                       // Get Mode info\r
-                       gpVesa_BiosState->AX = 0x4F01;\r
-                       gpVesa_BiosState->CX = gVesa_Modes[i].code;\r
-                       gpVesa_BiosState->ES = modeinfoPtr.seg;\r
-                       gpVesa_BiosState->DI = modeinfoPtr.ofs;\r
-                       VM8086_Int(gpVesa_BiosState, 0x10);\r
-                       \r
-                       // Parse Info\r
-                       gVesa_Modes[i].flags = 0;\r
-                       if ( (modeinfo->attributes & 0x90) == 0x90 )\r
-                       {\r
-                               gVesa_Modes[i].flags |= FLAG_LFB;\r
-                               gVesa_Modes[i].framebuffer = modeinfo->physbase;\r
-                               gVesa_Modes[i].fbSize = modeinfo->Yres*modeinfo->pitch;\r
-                       } else {\r
-                               gVesa_Modes[i].framebuffer = 0;\r
-                               gVesa_Modes[i].fbSize = 0;\r
-                       }\r
-                       \r
-                       gVesa_Modes[i].pitch = modeinfo->pitch;\r
-                       gVesa_Modes[i].width = modeinfo->Xres;\r
-                       gVesa_Modes[i].height = modeinfo->Yres;\r
-                       gVesa_Modes[i].bpp = modeinfo->bpp;\r
-                       \r
-                       #if DEBUG\r
-                       Log_Log("VESA", "0x%x - %ix%ix%i",\r
-                               gVesa_Modes[i].code, gVesa_Modes[i].width, gVesa_Modes[i].height, gVesa_Modes[i].bpp);\r
-                       #endif\r
-               }\r
-       \r
-//             VM8086_Deallocate( modeinfo );\r
+                       VBE_int_FillMode_Int(i, modeinfo, &modeinfoPtr);\r
+               }       \r
+//             VM8086_Deallocate( gpVesa_BiosState, modeinfo );\r
                \r
                gbVesaModesChecked = 1;\r
        }\r
@@ -192,7 +269,6 @@ const char *csaVESA_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
 int Vesa_IOCtl(tVFS_Node *Node, int ID, void *Data)\r
 {\r
         int    ret;\r
-       //Log_Debug("VESA", "Vesa_Ioctl: (Node=%p, ID=%i, Data=%p)", Node, ID, Data);\r
        switch(ID)\r
        {\r
        BASE_IOCTLS(DRV_TYPE_VIDEO, "VESA", VERSION, csaVESA_IOCtls);\r
@@ -207,11 +283,15 @@ int Vesa_IOCtl(tVFS_Node *Node, int ID, void *Data)
                return Vesa_Int_ModeInfo((tVideo_IOCtl_Mode*)Data);\r
        \r
        case VIDEO_IOCTL_SETBUFFORMAT:\r
+               LOG("Hide cursor");\r
                Vesa_int_HideCursor();\r
+               LOG("Update internals");\r
                ret = gVesa_BufInfo.BufferFormat;\r
                if(Data)        gVesa_BufInfo.BufferFormat = *(int*)Data;\r
+               LOG("Swap back to text mode cursor");\r
                if(gVesa_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)\r
                        DrvUtil_Video_SetCursor( &gVesa_BufInfo, &gDrvUtil_TextModeCursor );\r
+               LOG("Show again");\r
                Vesa_int_ShowCursor();\r
                return ret;\r
        \r
@@ -249,11 +329,15 @@ int Vesa_Int_SetMode(int mode)
        gpVesa_BiosState->AX = 0x4F02;\r
        gpVesa_BiosState->BX = gVesa_Modes[mode].code;\r
        if(gVesa_Modes[mode].flags & FLAG_LFB) {\r
-               gpVesa_BiosState->BX |= 0x4000; // Bit 14 - Use LFB\r
+               gpVesa_BiosState->BX |= 1 << 14;        // Use LFB\r
        }\r
+       LOG("In : AX=%04x/BX=%04x",\r
+               gpVesa_BiosState->AX, gpVesa_BiosState->BX);\r
        \r
        // Set Mode\r
        VM8086_Int(gpVesa_BiosState, 0x10);\r
+\r
+       LOG("Out: AX = %04x", gpVesa_BiosState->AX);\r
        \r
        // Map Framebuffer\r
        if( (tVAddr)gpVesa_Framebuffer != VESA_DEFAULT_FRAMEBUFFER )\r
@@ -261,8 +345,8 @@ int Vesa_Int_SetMode(int mode)
        giVesaPageCount = (gVesa_Modes[mode].fbSize + 0xFFF) >> 12;\r
        gpVesa_Framebuffer = (void*)MM_MapHWPages(gVesa_Modes[mode].framebuffer, giVesaPageCount);\r
        \r
-       Log_Log("VESA", "Setting mode to %i (%ix%i %ibpp) %p[0x%x] maps %P",\r
-               mode,\r
+       Log_Log("VESA", "Setting mode to %i 0x%x (%ix%i %ibpp) %p[0x%x] maps %P",\r
+               mode, gVesa_Modes[mode].code,\r
                gVesa_Modes[mode].width, gVesa_Modes[mode].height,\r
                gVesa_Modes[mode].bpp,\r
                gpVesa_Framebuffer, giVesaPageCount << 12, gVesa_Modes[mode].framebuffer\r

UCC git Repository :: git.ucc.asn.au