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);
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)
#include <semaphore.h>
// === CONSTANTS ===
+#define TRACE_EMU 0
+
#define VM8086_MAGIC_CS 0xFFFF
#define VM8086_MAGIC_IP 0x0010
#define VM8086_STACK_SEG 0x9F00
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)
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
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)
{
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;
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;
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
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;
/*
* 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);
giVT_CurrentTerminal = ID;
gpVT_CurTerm = &gVT_Terminals[ID];
+ LOG("Attempting VT_SetMode");
+
if( gpVT_CurTerm->Mode == TERM_MODE_TEXT )
{
VT_SetMode( VIDEO_BUFFMT_TEXT );
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
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");
}
*/
#include "vterm.h"
#include <api_drv_video.h>
-#define DEBUG 1
+#define DEBUG 0
// === CODE ===
/**
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;
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 )
{
{
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
}
// Restore cursor position
+ LOG("Drawing");
DrvUtil_Video_DrawCursor(Buf, csrX, csrY);
+ LEAVE('i', 0);
return 0;
}
{
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;
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)
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(
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;
}
break;
case 32:
+ LOG("32-bit render");
for( y = 0; y < render_h; y ++ )
{
Uint32 *px;
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;
}
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;
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
\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
\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
\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
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
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
\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
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
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
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
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
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