bootvid.c
来自「一个类似windows」· C语言 代码 · 共 673 行 · 第 1/2 页
C
673 行
/*
* 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.c 21842 2006-05-07 19:16:11Z ion $
*/
/* INCLUDES ******************************************************************/
#include <ntddk.h>
#include <windef.h>
#include <ndk/ldrfuncs.h>
#include "bootvid.h"
#include "ntbootvid.h"
#include "resource.h"
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
/*
* 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 const 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];
static CLIENT_ID BitmapThreadId;
static PUCHAR BootimageBitmap;
static LONG ShutdownNotify;
static KEVENT ShutdownCompleteEvent;
/* DATA **********************************************************************/
static PDRIVER_OBJECT BootVidDriverObject = NULL;
/* FUNCTIONS *****************************************************************/
static BOOLEAN FASTCALL
InbvFindBootimage()
{
PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
LDR_RESOURCE_INFO ResourceInfo;
NTSTATUS Status;
PVOID BaseAddress = BootVidDriverObject->DriverStart;
ULONG Size;
ResourceInfo.Type = RT_BITMAP;
ResourceInfo.Name = IDB_BOOTIMAGE;
ResourceInfo.Language = 0x09;
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,
ResourceDataEntry,
(PVOID*)&BootimageBitmap,
&Size);
if (!NT_SUCCESS(Status))
{
DPRINT("LdrAccessResource() failed with status 0x%.08x\n", Status);
return FALSE;
}
return TRUE;
}
static BOOLEAN FASTCALL
InbvMapVideoMemory(VOID)
{
PHYSICAL_ADDRESS PhysicalAddress;
PhysicalAddress.QuadPart = 0xA0000;
VideoMemory = MmMapIoSpace(PhysicalAddress, 0x10000, MmNonCached);
return VideoMemory != NULL;
}
static BOOLEAN FASTCALL
InbvUnmapVideoMemory(VOID)
{
MmUnmapIoSpace(VideoMemory, 0x10000);
return TRUE;
}
static VOID FASTCALL
vgaPreCalc()
{
ULONG j;
for (j = 0; j < 80; j++)
{
maskbit[j * 8 + 0] = 128;
maskbit[j * 8 + 1] = 64;
maskbit[j * 8 + 2] = 32;
maskbit[j * 8 + 3] = 16;
maskbit[j * 8 + 4] = 8;
maskbit[j * 8 + 5] = 4;
maskbit[j * 8 + 6] = 2;
maskbit[j * 8 + 7] = 1;
}
}
static VOID FASTCALL
vgaSetRegisters(const VGA_REGISTERS *Registers)
{
UINT 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++)
{
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]);
}
}
static VOID
InbvInitVGAMode(VOID)
{
/* Zero out video memory (clear a possibly trashed screen) */
RtlZeroMemory(VideoMemory, 0x10000);
vgaSetRegisters(&Mode12Regs);
/* Set the PEL mask. */
WRITE_PORT_UCHAR(PELMASK, 0xff);
vgaPreCalc();
}
static 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.
*/
return FALSE;
}
static VOID STDCALL
VidCleanUp(VOID)
{
InbvUnmapVideoMemory();
InterlockedIncrement(&ShutdownNotify);
KeWaitForSingleObject(&ShutdownCompleteEvent, Executive, KernelMode,
FALSE, NULL);
}
static VOID FASTCALL
InbvSetColor(INT Index, UCHAR Red, UCHAR Green, UCHAR Blue)
{
WRITE_PORT_UCHAR(PELINDEX, Index);
WRITE_PORT_UCHAR(PELDATA, Red >> 2);
WRITE_PORT_UCHAR(PELDATA, Green >> 2);
WRITE_PORT_UCHAR(PELDATA, Blue >> 2);
}
static VOID FASTCALL
InbvSetBlackPalette()
{
register ULONG r = 0;
/* Disable screen and enable palette access. */
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. */
READ_PORT_UCHAR(STATUS);
WRITE_PORT_UCHAR(ATTRIB, 0x20);
}
static VOID FASTCALL
InbvDisplayBitmap(ULONG Width, ULONG Height, PCHAR ImageData)
{
ULONG j, k, y;
register ULONG i;
register ULONG x;
register ULONG c;
k = 0;
for (y = 0; y < Height; y++)
{
for (j = 0; j < 8; j++)
{
x = j;
/*
* Loop through the line and process every 8th pixel.
* This way we can get a way with using the same bit mask
* for several pixels and thus not need to do as much I/O
* communication.
*/
while (x < 640)
{
c = 0;
if (x < Width)
{
c = ImageData[k + x];
for (i = 1; i < 4; i++)
{
if (x + i * 8 < Width)
{
c |= (ImageData[k + x + i * 8] << i * 8);
}
}
}
InbvPutPixels(x, 479 - y, c);
x += 8 * 4;
}
}
k += Width;
}
}
static VOID FASTCALL
InbvDisplayCompressedBitmap()
{
PBITMAPV5HEADER bminfo;
ULONG i,j,k;
ULONG x,y;
ULONG curx,cury;
ULONG bfOffBits;
ULONG clen;
PCHAR ImageData;
UCHAR ClrUsed;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?