- Cleaned up the Boot Video driver.

- Replaced most of the magic numbers by defines.
- Changed the video mode setting to directly program the VGA registers instead of using Ke386CallBios.
- Properly map the video memory.

svn path=/trunk/; revision=8534
This commit is contained in:
Filip Navara 2004-03-04 18:55:09 +00:00
parent 5c30d2cc66
commit a2f24f38dc
3 changed files with 599 additions and 639 deletions

View file

@ -1,12 +1,24 @@
/* $Id: bootvid.c,v 1.6 2004/02/10 16:22:55 navaraf Exp $
/*
* ReactOS Boot video driver
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/inbv/bootvid.c
* PURPOSE: Boot video support
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* 12-07-2003 CSH Created
* Copyright (C) 2003 Casper S. Hornstroup
* Copyright (C) 2004 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Id: bootvid.c,v 1.7 2004/03/04 18:55:08 navaraf Exp $
*/
/* INCLUDES ******************************************************************/
@ -15,106 +27,56 @@
#include <ddk/ntbootvid.h>
#include <reactos/resource.h>
#include <rosrtl/string.h>
#include "bootvid.h"
#include "../../../ntoskrnl/include/internal/v86m.h"
/*#define NDEBUG*/
#define NDEBUG
#include <debug.h>
#define RT_BITMAP 2
typedef struct tagRGBQUAD {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD, *PRGBQUAD;
typedef long FXPT2DOT30;
typedef struct tagCIEXYZ {
FXPT2DOT30 ciexyzX;
FXPT2DOT30 ciexyzY;
FXPT2DOT30 ciexyzZ;
} CIEXYZ;
typedef CIEXYZ * LPCIEXYZ;
typedef struct tagCIEXYZTRIPLE {
CIEXYZ ciexyzRed;
CIEXYZ ciexyzGreen;
CIEXYZ ciexyzBlue;
} CIEXYZTRIPLE;
typedef CIEXYZTRIPLE *LPCIEXYZTRIPLE;
typedef struct {
DWORD bV5Size;
LONG bV5Width;
LONG bV5Height;
WORD bV5Planes;
WORD bV5BitCount;
DWORD bV5Compression;
DWORD bV5SizeImage;
LONG bV5XPelsPerMeter;
LONG bV5YPelsPerMeter;
DWORD bV5ClrUsed;
DWORD bV5ClrImportant;
DWORD bV5RedMask;
DWORD bV5GreenMask;
DWORD bV5BlueMask;
DWORD bV5AlphaMask;
DWORD bV5CSType;
CIEXYZTRIPLE bV5Endpoints;
DWORD bV5GammaRed;
DWORD bV5GammaGreen;
DWORD bV5GammaBlue;
DWORD bV5Intent;
DWORD bV5ProfileData;
DWORD bV5ProfileSize;
DWORD bV5Reserved;
} BITMAPV5HEADER, *PBITMAPV5HEADER;
#define MISC 0x3c2
#define SEQ 0x3c4
#define CRTC 0x3d4
#define GRAPHICS 0x3ce
#define FEATURE 0x3da
#define ATTRIB 0x3c0
#define STATUS 0x3da
typedef struct {
ULONG r;
ULONG g;
ULONG b;
} FADER_PALETTE_ENTRY;
/* In pixelsups.S */
extern VOID
InbvPutPixels(int x, int y, unsigned long c);
/* GLOBALS *******************************************************************/
char *vidmem;
/*
* NOTE:
* This is based on SvgaLib 640x480x16 mode definition with the
* following changes:
* - Graphics: Data Rotate (Index 3)
* Set to zero to indicate that the data written to video memory by
* CPU should be processed unmodified.
* - Graphics: Mode Register (index 5)
* Set to Write Mode 2 and Read Mode 0.
*/
static VGA_REGISTERS Mode12Regs =
{
/* CRT Controller Registers */
{0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3},
/* Attribute Controller Registers */
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F, 0x81, 0x00, 0x0F, 0x00, 0x00},
/* Graphics Controller Registers */
{0x00, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x05, 0x0F, 0xFF},
/* Sequencer Registers */
{0x03, 0x01, 0x0F, 0x00, 0x06},
/* Misc Output Register */
0xE3
};
PUCHAR VideoMemory;
/* Must be 4 bytes per entry */
long maskbit[640];
long y80[480];
static HANDLE BitmapThreadHandle;
static CLIENT_ID BitmapThreadId;
static BOOLEAN BitmapIsDrawn;
static PUCHAR BootimageBitmap;
static BOOLEAN InGraphicsMode = FALSE;
/* DATA **********************************************************************/
static BOOLEAN VideoAddressSpaceInitialized = FALSE;
static PVOID NonBiosBaseAddress;
static PDRIVER_OBJECT BootVidDriverObject = NULL;
/* FUNCTIONS *****************************************************************/
static BOOLEAN
STATIC BOOLEAN FASTCALL
InbvFindBootimage()
{
PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
@ -127,20 +89,24 @@ InbvFindBootimage()
ResourceInfo.Name = IDB_BOOTIMAGE;
ResourceInfo.Language = 0x09;
Status = LdrFindResource_U(BaseAddress,
Status = LdrFindResource_U(
BaseAddress,
&ResourceInfo,
RESOURCE_DATA_LEVEL,
&ResourceDataEntry);
if (!NT_SUCCESS(Status))
{
DPRINT("LdrFindResource_U() failed with status 0x%.08x\n", Status);
return FALSE;
}
Status = LdrAccessResource(BaseAddress,
Status = LdrAccessResource(
BaseAddress,
ResourceDataEntry,
(PVOID*)&BootimageBitmap,
&Size);
if (!NT_SUCCESS(Status))
{
DPRINT("LdrAccessResource() failed with status 0x%.08x\n", Status);
@ -151,150 +117,32 @@ InbvFindBootimage()
}
static BOOLEAN
InbvInitializeVideoAddressSpace(VOID)
STATIC BOOLEAN FASTCALL
InbvMapVideoMemory(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING PhysMemName;
NTSTATUS Status;
HANDLE PhysMemHandle;
PVOID BaseAddress;
LARGE_INTEGER Offset;
ULONG ViewSize;
CHAR IVT[1024];
CHAR BDA[256];
PVOID start = (PVOID)0x0;
PHYSICAL_ADDRESS PhysicalAddress;
/*
* Open the physical memory section
*/
RtlRosInitUnicodeStringFromLiteral(&PhysMemName, L"\\Device\\PhysicalMemory");
InitializeObjectAttributes(&ObjectAttributes,
&PhysMemName,
0,
NULL,
NULL);
Status = ZwOpenSection(&PhysMemHandle, SECTION_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT("Couldn't open \\Device\\PhysicalMemory\n");
return FALSE;
}
PhysicalAddress.QuadPart = 0xA0000;
VideoMemory = MmMapIoSpace(PhysicalAddress, 0x10000, FALSE);
/*
* Map the BIOS and device registers into the address space
*/
Offset.QuadPart = 0xa0000;
ViewSize = 0x100000 - 0xa0000;
BaseAddress = (PVOID)0xa0000;
Status = NtMapViewOfSection(PhysMemHandle,
NtCurrentProcess(),
&BaseAddress,
0,
8192,
&Offset,
&ViewSize,
ViewUnmap,
0,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("Couldn't map physical memory (%x)\n", Status);
NtClose(PhysMemHandle);
return FALSE;
}
NtClose(PhysMemHandle);
if (BaseAddress != (PVOID)0xa0000)
{
DPRINT("Couldn't map physical memory at the right address "
"(was %x)\n", BaseAddress);
return FALSE;
}
return VideoMemory != NULL;
}
/*
* Map some memory to use for the non-BIOS parts of the v86 mode address
* space
*/
NonBiosBaseAddress = (PVOID)0x1;
ViewSize = 0xa0000 - 0x1000;
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
&NonBiosBaseAddress,
0,
&ViewSize,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to allocate virtual memory (Status %x)\n", Status);
return FALSE;
}
if (NonBiosBaseAddress != (PVOID)0x0)
{
DPRINT("Failed to allocate virtual memory at right address "
"(was %x)\n", NonBiosBaseAddress);
return FALSE;
}
/*
* Get the real mode IVT from the kernel
*/
Status = NtVdmControl(0, IVT);
if (!NT_SUCCESS(Status))
{
DPRINT("NtVdmControl failed (status %x)\n", Status);
return FALSE;
}
/*
* Copy the real mode IVT into the right place
*/
memcpy(start, IVT, 1024);
/*
* Get the BDA from the kernel
*/
Status = NtVdmControl(1, BDA);
if (!NT_SUCCESS(Status))
{
DPRINT("NtVdmControl failed (status %x)\n", Status);
return FALSE;
}
/*
* Copy the BDA into the right place
*/
memcpy((PVOID)0x400, BDA, 256);
STATIC BOOLEAN FASTCALL
InbvUnmapVideoMemory(VOID)
{
MmUnmapIoSpace(VideoMemory, 0x10000);
return TRUE;
}
static BOOLEAN
InbvDeinitializeVideoAddressSpace(VOID)
{
ULONG RegionSize;
PUCHAR ViewBase;
RegionSize = 0xa0000 - 0x1000;
NtFreeVirtualMemory(NtCurrentProcess(),
&NonBiosBaseAddress,
&RegionSize,
MEM_RELEASE);
ViewBase = (PUCHAR) 0xa0000;
ZwUnmapViewOfSection(NtCurrentProcess(), ViewBase);
return TRUE;
}
static VOID
STATIC VOID FASTCALL
vgaPreCalc()
{
ULONG j;
for(j = 0; j < 80; j++)
for (j = 0; j < 80; j++)
{
maskbit[j * 8 + 0] = 128;
maskbit[j * 8 + 1] = 64;
@ -305,9 +153,56 @@ vgaPreCalc()
maskbit[j * 8 + 6] = 2;
maskbit[j * 8 + 7] = 1;
}
for(j = 0; j < 480; j++)
}
STATIC VOID FASTCALL
vgaSetRegisters(PVGA_REGISTERS Registers)
{
int i;
/* Update misc output register */
WRITE_PORT_UCHAR(MISC, Registers->Misc);
/* Synchronous reset on */
WRITE_PORT_UCHAR(SEQ, 0x00);
WRITE_PORT_UCHAR(SEQDATA, 0x01);
/* Write sequencer registers */
for (i = 1; i < sizeof(Registers->Sequencer); i++)
{
y80[j] = j * 80; /* 80 = 640 / 8 = Number of bytes per scanline */
WRITE_PORT_UCHAR(SEQ, i);
WRITE_PORT_UCHAR(SEQDATA, Registers->Sequencer[i]);
}
/* Synchronous reset off */
WRITE_PORT_UCHAR(SEQ, 0x00);
WRITE_PORT_UCHAR(SEQDATA, 0x03);
/* Deprotect CRT registers 0-7 */
WRITE_PORT_UCHAR(CRTC, 0x11);
WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[0x11] & 0x7f);
/* Write CRT registers */
for (i = 0; i < sizeof(Registers->CRT); i++)
{
WRITE_PORT_UCHAR(CRTC, i);
WRITE_PORT_UCHAR(CRTCDATA, Registers->CRT[i]);
}
/* Write graphics controller registers */
for (i = 0; i < sizeof(Registers->Graphics); i++)
{
WRITE_PORT_UCHAR(GRAPHICS, i);
WRITE_PORT_UCHAR(GRAPHICSDATA, Registers->Graphics[i]);
}
/* Write attribute controller registers */
for (i = 0; i < sizeof(Registers->Attribute); i++)
{
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, i);
WRITE_PORT_UCHAR(ATTRIB, Registers->Attribute[i]);
}
}
@ -315,121 +210,71 @@ vgaPreCalc()
static VOID
InbvInitVGAMode(VOID)
{
KV86M_REGISTERS Regs;
NTSTATUS Status;
ULONG i;
/* Zero out video memory (clear a possibly trashed screen) */
RtlZeroMemory(VideoMemory, 0x10000);
vidmem = (char *)(0xd0000000 + 0xa0000);
memset(&Regs, 0, sizeof(Regs));
Regs.Eax = 0x0012;
Status = Ke386CallBios(0x10, &Regs);
assert(NT_SUCCESS(Status));
/* Get VGA registers into the correct state */
/* Reset the internal flip-flop. */
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
/* Write the 16 palette registers. */
for (i = 0; i < 16; i++)
{
WRITE_PORT_UCHAR((PUCHAR)ATTRIB, i);
WRITE_PORT_UCHAR((PUCHAR)ATTRIB, i);
}
/* Write the mode control register - graphics mode; 16 color DAC. */
WRITE_PORT_UCHAR((PUCHAR)ATTRIB, 0x10);
WRITE_PORT_UCHAR((PUCHAR)ATTRIB, 0x81);
/* Write the color select register - select first 16 DAC registers. */
WRITE_PORT_UCHAR((PUCHAR)ATTRIB, 0x14);
WRITE_PORT_UCHAR((PUCHAR)ATTRIB, 0x00);
/* Get the VGA into the mode we want to work with */
WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08); /* Set */
WRITE_PORT_UCHAR((PUCHAR)0x3cf,0); /* the MASK */
WRITE_PORT_USHORT((PUSHORT)0x3ce,0x0205); /* write mode = 2 (bits 0,1) read mode = 0 (bit 3) */
(UCHAR) READ_REGISTER_UCHAR(vidmem); /* Update bit buffer */
WRITE_REGISTER_UCHAR(vidmem, 0); /* Write the pixel */
WRITE_PORT_UCHAR((PUCHAR)0x3ce,0x08);
WRITE_PORT_UCHAR((PUCHAR)0x3cf,0xff);
vgaSetRegisters(&Mode12Regs);
/* Set the PEL mask. */
WRITE_PORT_UCHAR((PUCHAR)0x3c6, 0xff);
/* Zero out video memory (clear a possibly trashed screen) */
RtlZeroMemory(vidmem, 64000);
WRITE_PORT_UCHAR(PELMASK, 0xff);
vgaPreCalc();
}
BOOL
STDCALL
BOOL STDCALL
VidResetDisplay(VOID)
{
/*
We are only using standard VGA facilities so we can rely on the HAL 'int10mode3'
reset to cleanup the hardware state.
* We are only using standard VGA facilities so we can rely on the
* HAL 'int10mode3' reset to cleanup the hardware state.
*/
InGraphicsMode = FALSE;
return FALSE;
}
VOID
STDCALL
VOID STDCALL
VidCleanUp(VOID)
{
/*
We are only using standard VGA facilities so we can rely on the HAL 'int10mode3'
reset to cleanup the hardware state.
*/
InGraphicsMode = FALSE;
InbvUnmapVideoMemory();
}
static __inline__ VOID
InbvSetColor(int cindex, unsigned char red, unsigned char green, unsigned char blue)
STATIC VOID FASTCALL
InbvSetColor(INT Index, UCHAR Red, UCHAR Green, UCHAR Blue)
{
red = (red * 63) / 255;
green = (green * 63) / 255;
blue = (blue * 63) / 255;
WRITE_PORT_UCHAR((PUCHAR)0x03c8, cindex);
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
WRITE_PORT_UCHAR((PUCHAR)0x03c9, red);
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
WRITE_PORT_UCHAR((PUCHAR)0x03c9, green);
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
WRITE_PORT_UCHAR((PUCHAR)0x03c9, blue);
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
WRITE_PORT_UCHAR(PELINDEX, Index);
WRITE_PORT_UCHAR(PELDATA, Red >> 2);
WRITE_PORT_UCHAR(PELDATA, Green >> 2);
WRITE_PORT_UCHAR(PELDATA, Blue >> 2);
}
static __inline__ VOID
STATIC VOID FASTCALL
InbvSetBlackPalette()
{
register ULONG r = 0;
/* Disable screen and enable palette access. */
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
WRITE_PORT_UCHAR((PUCHAR)0x3c0, 0x00);
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x00);
for (r = 0; r < 16; r++)
{
InbvSetColor(r, 0, 0, 0);
}
/* Enable screen and enable palette access. */
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
WRITE_PORT_UCHAR((PUCHAR)0x3c0, 0x20);
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
}
static VOID
STATIC VOID FASTCALL
InbvDisplayBitmap(ULONG Width, ULONG Height, PCHAR ImageData)
{
ULONG j,k,y;
ULONG j, k, y;
register ULONG i;
register ULONG x;
register ULONG c;
@ -456,7 +301,7 @@ InbvDisplayBitmap(ULONG Width, ULONG Height, PCHAR ImageData)
c = ImageData[k + x];
for (i = 1; i < 4; i++)
{
if (x + i*8 < Width)
if (x + i * 8 < Width)
{
c |= (ImageData[k + x + i * 8] << i * 8);
}
@ -464,7 +309,7 @@ InbvDisplayBitmap(ULONG Width, ULONG Height, PCHAR ImageData)
}
InbvPutPixels(x, 479 - y, c);
x += 8*4;
x += 8 * 4;
}
}
k += Width;
@ -472,7 +317,7 @@ InbvDisplayBitmap(ULONG Width, ULONG Height, PCHAR ImageData)
}
static VOID
STATIC VOID FASTCALL
InbvDisplayCompressedBitmap()
{
PBITMAPV5HEADER bminfo;
@ -609,16 +454,13 @@ InbvDisplayCompressedBitmap()
}
#define PALETTE_FADE_STEPS 20
#define PALETTE_FADE_TIME 20 * 10000 /* 20ms */
static VOID
STATIC VOID FASTCALL
InbvFadeUpPalette()
{
PBITMAPV5HEADER bminfo;
PRGBQUAD Palette;
ULONG i;
unsigned char r,g,b;
unsigned char r, g, b;
register ULONG c;
LARGE_INTEGER Interval;
FADER_PALETTE_ENTRY FaderPalette[16];
@ -627,8 +469,8 @@ InbvFadeUpPalette()
RtlZeroMemory(&FaderPalette, sizeof(FaderPalette));
RtlZeroMemory(&FaderPaletteDelta, sizeof(FaderPaletteDelta));
bminfo = (PBITMAPV5HEADER) &BootimageBitmap[0]; //sizeof(BITMAPFILEHEADER)];
Palette = (PRGBQUAD) &BootimageBitmap[/* sizeof(BITMAPFILEHEADER) + */ bminfo->bV5Size];
bminfo = (PBITMAPV5HEADER)&BootimageBitmap[0];
Palette = (PRGBQUAD)&BootimageBitmap[bminfo->bV5Size];
for (i = 0; i < 16; i++)
{
@ -643,8 +485,9 @@ InbvFadeUpPalette()
for (i = 0; i < PALETTE_FADE_STEPS; i++)
{
/* Disable screen and enable palette access. */
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
WRITE_PORT_UCHAR((PUCHAR)0x3c0, 0x00);
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x00);
for (c = 0; c < bminfo->bV5ClrUsed; c++)
{
/* Add the delta */
@ -668,16 +511,19 @@ InbvFadeUpPalette()
/* Update the hardware */
InbvSetColor(c, r, g, b);
}
/* Enable screen and disable palette access. */
(VOID)READ_PORT_UCHAR((PUCHAR)FEATURE);
WRITE_PORT_UCHAR((PUCHAR)0x3c0, 0x20);
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
/* Wait for a bit. */
Interval.QuadPart = -PALETTE_FADE_TIME;
KeDelayExecutionThread(KernelMode, FALSE, &Interval);
}
}
static VOID STDCALL
STATIC VOID STDCALL
InbvBitmapThreadMain(PVOID Ignored)
{
if (InbvFindBootimage())
@ -689,98 +535,83 @@ InbvBitmapThreadMain(PVOID Ignored)
{
DbgPrint("Warning: Cannot find boot image\n");
}
BitmapIsDrawn = TRUE;
}
BOOLEAN
STDCALL
VidIsBootDriverInstalled(VOID)
{
return InGraphicsMode;
}
BOOLEAN
STDCALL
STATIC BOOLEAN STDCALL
VidInitialize(VOID)
{
NTSTATUS Status;
if (!VideoAddressSpaceInitialized)
{
InbvInitializeVideoAddressSpace();
}
InbvMapVideoMemory();
InbvInitVGAMode();
InGraphicsMode = TRUE;
BitmapIsDrawn = FALSE;
Status = PsCreateSystemThread(&BitmapThreadHandle,
Status = PsCreateSystemThread(
&BitmapThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&BitmapThreadId,
InbvBitmapThreadMain,
NULL);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
NtClose(BitmapThreadHandle);
InbvDeinitializeVideoAddressSpace();
VideoAddressSpaceInitialized = FALSE;
NtClose(BitmapThreadHandle);
return TRUE;
}
NTSTATUS STDCALL
VidDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS nErrCode;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
NTBOOTVID_FUNCTION_TABLE* FunctionTable;
nErrCode = STATUS_SUCCESS;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Status = STATUS_SUCCESS;
switch(piosStack->MajorFunction)
switch(IrpSp->MajorFunction)
{
/* opening and closing handles to the device */
/* Opening and closing handles to the device */
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
break;
case IRP_MJ_DEVICE_CONTROL:
switch (piosStack->Parameters.DeviceIoControl.IoControlCode)
switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_BOOTVID_INITIALIZE:
VidInitialize();
FunctionTable = (NTBOOTVID_FUNCTION_TABLE*)
FunctionTable = (NTBOOTVID_FUNCTION_TABLE *)
Irp->AssociatedIrp.SystemBuffer;
FunctionTable->ResetDisplay = VidResetDisplay;
break;
case IOCTL_BOOTVID_CLEANUP:
VidCleanUp();
break;
default:
nErrCode = STATUS_NOT_IMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
break;
}
break;
/* unsupported operations */
/* Unsupported operations */
default:
nErrCode = STATUS_NOT_IMPLEMENTED;
Status = STATUS_NOT_IMPLEMENTED;
}
Irp->IoStatus.Status = nErrCode;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return nErrCode;
return Status;
}
@ -793,23 +624,25 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
BootVidDriverObject = DriverObject;
/* register driver routines */
/* Register driver routines */
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VidDispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VidDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VidDispatch;
DriverObject->DriverUnload = NULL;
/* create device */
DriverObject->Flags |= DO_BUFFERED_IO;
/* Create device */
RtlRosInitUnicodeStringFromLiteral(&DeviceName, L"\\Device\\BootVid");
Status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_BOOTVID,
0, FALSE, &BootVidDevice);
if (! NT_SUCCESS(Status))
{
return Status;
}
BootVidDevice->Flags |= DO_BUFFERED_IO;
Status = IoCreateDevice(
DriverObject,
0,
&DeviceName,
FILE_DEVICE_BOOTVID,
0,
FALSE,
&BootVidDevice);
return Status;
}

View file

@ -0,0 +1,124 @@
/*
* ReactOS Boot video driver
*
* Copyright (C) 2003 Casper S. Hornstroup
* Copyright (C) 2004 Filip Navara
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Id: bootvid.h,v 1.1 2004/03/04 18:55:09 navaraf Exp $
*/
#ifndef _BOOTVID_H
#define _BOOTVID_H
#define PALETTE_FADE_STEPS 20
#define PALETTE_FADE_TIME 20 * 10000 /* 20ms */
/*
* Windows Bitmap structures
*/
#define RT_BITMAP 2
typedef struct tagRGBQUAD
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD, *PRGBQUAD;
typedef long FXPT2DOT30;
typedef struct tagCIEXYZ
{
FXPT2DOT30 ciexyzX;
FXPT2DOT30 ciexyzY;
FXPT2DOT30 ciexyzZ;
} CIEXYZ, *LPCIEXYZ;
typedef struct tagCIEXYZTRIPLE
{
CIEXYZ ciexyzRed;
CIEXYZ ciexyzGreen;
CIEXYZ ciexyzBlue;
} CIEXYZTRIPLE, *LPCIEXYZTRIPLE;
typedef struct {
DWORD bV5Size;
LONG bV5Width;
LONG bV5Height;
WORD bV5Planes;
WORD bV5BitCount;
DWORD bV5Compression;
DWORD bV5SizeImage;
LONG bV5XPelsPerMeter;
LONG bV5YPelsPerMeter;
DWORD bV5ClrUsed;
DWORD bV5ClrImportant;
DWORD bV5RedMask;
DWORD bV5GreenMask;
DWORD bV5BlueMask;
DWORD bV5AlphaMask;
DWORD bV5CSType;
CIEXYZTRIPLE bV5Endpoints;
DWORD bV5GammaRed;
DWORD bV5GammaGreen;
DWORD bV5GammaBlue;
DWORD bV5Intent;
DWORD bV5ProfileData;
DWORD bV5ProfileSize;
DWORD bV5Reserved;
} BITMAPV5HEADER, *PBITMAPV5HEADER;
/*
* Private driver structures
*/
typedef struct {
ULONG r;
ULONG g;
ULONG b;
} FADER_PALETTE_ENTRY;
typedef struct _VGA_REGISTERS
{
UCHAR CRT[24];
UCHAR Attribute[21];
UCHAR Graphics[9];
UCHAR Sequencer[5];
UCHAR Misc;
} VGA_REGISTERS, *PVGA_REGISTERS;
/* VGA registers */
#define MISC (PUCHAR)0x3c2
#define SEQ (PUCHAR)0x3c4
#define SEQDATA (PUCHAR)0x3c5
#define CRTC (PUCHAR)0x3d4
#define CRTCDATA (PUCHAR)0x3d5
#define GRAPHICS (PUCHAR)0x3ce
#define GRAPHICSDATA (PUCHAR)0x3cf
#define ATTRIB (PUCHAR)0x3c0
#define STATUS (PUCHAR)0x3da
#define PELMASK (PUCHAR)0x3c6
#define PELINDEX (PUCHAR)0x3c8
#define PELDATA (PUCHAR)0x3c9
/* In pixelsups.S */
extern VOID
InbvPutPixels(int x, int y, unsigned long c);
#endif /* _BOOTVID_H */

View file

@ -1,4 +1,4 @@
/* $Id: pixelsup_i386.S,v 1.1 2003/08/24 12:11:13 dwelch Exp $
/* $Id: pixelsup_i386.S,v 1.2 2004/03/04 18:55:09 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -52,44 +52,47 @@ _InbvPutPixels:
.nomask:
/* Compute offset in video memory and put it in EBX
offset = (x >> 3) + y80[y]; */
offset = (x >> 3) + (y << 4) + (y << 6); */
movl 0xC(%ebp), %esi /* y */
movl _y80(,%esi, 4), %ebx
movl %esi, %ebx
shll $0x6, %ebx
shll $0x4, %esi
addl %esi, %ebx
movl 0x8(%ebp), %eax /* x */
shrl $0x3, %eax
addl %eax, %ebx
/* Latch first byte
(UCHAR) READ_REGISTER_UCHAR(vidmem + offset+0); */
movl (_vidmem), %esi
(UCHAR) READ_REGISTER_UCHAR(VideoMemory + offset+0); */
movl (_VideoMemory), %esi
addl %ebx, %esi
movb 0x0(%esi), %bl
/* Write color index for first pixel
*((PUCHAR)(vidmem + offset+0)) = (c >> 0*8) & 0xff; */
*((PUCHAR)(VideoMemory + offset+0)) = (c >> 0*8) & 0xff; */
movl 0x10(%ebp), %eax
movb %al, 0x0(%esi)
/* Latch second byte
(UCHAR) READ_REGISTER_UCHAR(vidmem + offset+1); */
(UCHAR) READ_REGISTER_UCHAR(VideoMemory + offset+1); */
movb 0x1(%esi), %bl
/* Write color index for second pixel
*((PUCHAR)(vidmem + offset+1)) = (c >> 1*8) & 0xff; */
*((PUCHAR)(VideoMemory + offset+1)) = (c >> 1*8) & 0xff; */
shrl $0x8, %eax
movb %al, 0x1(%esi)
/* Latch third byte
(UCHAR) READ_REGISTER_UCHAR(vidmem + offset+2); */
(UCHAR) READ_REGISTER_UCHAR(VideoMemory + offset+2); */
movb 0x2(%esi), %bl
/* Write color index for third pixel
*((PUCHAR)(vidmem + offset+2)) = (c >> 2*8) & 0xff; */
*((PUCHAR)(VideoMemory + offset+2)) = (c >> 2*8) & 0xff; */
shrl $0x8, %eax
movb %al, 0x2(%esi)
/* Latch fourth byte
(UCHAR) READ_REGISTER_UCHAR(vidmem + offset+3); */
(UCHAR) READ_REGISTER_UCHAR(VideoMemory + offset+3); */
movb 0x3(%esi), %bl
/* Write color index for fourth pixel
*((PUCHAR)(vidmem + offset+3)) = (c >> 3*8) & 0xff; */
*((PUCHAR)(VideoMemory + offset+3)) = (c >> 3*8) & 0xff; */
shrl $0x8, %eax
movb %al, 0x3(%esi)