From ffe900f573ee2bb2e38652235e54e9cc333916b4 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sat, 3 Feb 2007 20:30:32 +0000 Subject: [PATCH] - Replace broken bootvid by a new bootvid based on TinyKRNL's version. It is a .DLL instead of a .SYS and takes advantage of my patch to FreeLDR which allows us to load DLLs that drivers/the kernel load. - This new version is also binary compatible, so Windows's bootvid can be dropped instead and our kernel can talk to it. It has been tested under Windows/TinyKRNL. - Write 90% of the Inbv component in the kernel. Displaying the boot bitmap hasn't yet been coded. - The HAL is missing required routines for bootvid.dll, so it doesn't work yet. - .BMP resources haven't yet been added to the kernel. I will add them soon. svn path=/trunk/; revision=25706 --- reactos/boot/bootdata/packages/reactos.dff | 3 +- .../boot/freeldr/freeldr/arch/i386/loader.c | 3 +- reactos/drivers/base/bootvid/bar.bmp | Bin 262 -> 0 bytes reactos/drivers/base/bootvid/bootdata.c | 309 ++++ reactos/drivers/base/bootvid/bootimage.bmp | Bin 21632 -> 0 bytes reactos/drivers/base/bootvid/bootvid.c | 725 ++++++---- reactos/drivers/base/bootvid/bootvid.def | 25 +- reactos/drivers/base/bootvid/bootvid.h | 65 - reactos/drivers/base/bootvid/bootvid.rbuild | 12 +- reactos/drivers/base/bootvid/bootvid.rc | 12 +- reactos/drivers/base/bootvid/precomp.h | 46 + reactos/drivers/base/bootvid/resource.h | 6 - reactos/drivers/base/bootvid/vga.c | 1274 +++++++++++++++++ reactos/drivers/base/bootvid/vid.c | 119 -- reactos/drivers/base/bootvid/vid_vga.c | 512 ------- reactos/drivers/base/bootvid/vid_vgatext.c | 250 ---- reactos/drivers/base/bootvid/vid_xbox.c | 101 -- reactos/include/ndk/inbvfuncs.h | 28 +- reactos/include/ndk/inbvtypes.h | 55 + .../include/reactos/drivers/bootvid/bootvid.h | 72 + reactos/ntoskrnl/ex/init.c | 11 +- reactos/ntoskrnl/inbv/inbv.c | 699 +++++---- reactos/ntoskrnl/include/internal/inbv.h | 39 +- reactos/ntoskrnl/ke/freeldr.c | 3 +- reactos/ntoskrnl/ntoskrnl.rbuild | 1 + 25 files changed, 2729 insertions(+), 1641 deletions(-) delete mode 100644 reactos/drivers/base/bootvid/bar.bmp create mode 100644 reactos/drivers/base/bootvid/bootdata.c delete mode 100755 reactos/drivers/base/bootvid/bootimage.bmp delete mode 100644 reactos/drivers/base/bootvid/bootvid.h create mode 100644 reactos/drivers/base/bootvid/precomp.h delete mode 100644 reactos/drivers/base/bootvid/resource.h create mode 100644 reactos/drivers/base/bootvid/vga.c delete mode 100644 reactos/drivers/base/bootvid/vid.c delete mode 100644 reactos/drivers/base/bootvid/vid_vga.c delete mode 100644 reactos/drivers/base/bootvid/vid_vgatext.c delete mode 100644 reactos/drivers/base/bootvid/vid_xbox.c create mode 100644 reactos/include/ndk/inbvtypes.h create mode 100644 reactos/include/reactos/drivers/bootvid/bootvid.h diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index 77daa3b971f..034642bec0d 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -240,7 +240,8 @@ dll\win32\wsock32\wsock32.dll 1 ; Drivers -drivers\base\kdcom\kdcom.dll 2 +drivers\base\kdcom\kdcom.dll 2 +drivers\base\bootvid\bootvid.dll 2 drivers\base\beep\beep.sys 2 drivers\base\bootvid\bootvid.sys 2 drivers\base\null\null.sys 2 diff --git a/reactos/boot/freeldr/freeldr/arch/i386/loader.c b/reactos/boot/freeldr/freeldr/arch/i386/loader.c index e32412a54ca..1cc819d36ec 100644 --- a/reactos/boot/freeldr/freeldr/arch/i386/loader.c +++ b/reactos/boot/freeldr/freeldr/arch/i386/loader.c @@ -744,7 +744,8 @@ LdrPEGetOrLoadModule(IN PCHAR ModuleName, * code, and we'll just call it instead. */ if (!_stricmp(ImportedName, "hal.dll") || - !_stricmp(ImportedName, "kdcom.dll")) + !_stricmp(ImportedName, "kdcom.dll") || + !_stricmp(ImportedName, "bootvid.dll")) { /* Load the HAL */ FrLdrLoadImage(ImportedName, 10); diff --git a/reactos/drivers/base/bootvid/bar.bmp b/reactos/drivers/base/bootvid/bar.bmp deleted file mode 100644 index 239307b7d958d8eb4fc4a02dd93580eb85ecfb30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 262 zcmZ?rWn*LjgEAng0mNcJ%n8Jd3@i*xKzafY!+-#g0m2jmF(K3R&egkj%_s|21Q|B4 Gd`1A6vo3Q0 diff --git a/reactos/drivers/base/bootvid/bootdata.c b/reactos/drivers/base/bootvid/bootdata.c new file mode 100644 index 00000000000..af66e8a9ab3 --- /dev/null +++ b/reactos/drivers/base/bootvid/bootdata.c @@ -0,0 +1,309 @@ +#include "precomp.h" + +USHORT AT_Initialization[] = +{ + 0x10 | CMD_STREAM_READ, // Major Command = 0x10. Minor Command = 0x08. + 0x3DA, // Index Status 1 Register Port Address + + // + // This Stream performs a USHORT Array Indexed Write at port 0x3C0 + // + 0x20 | 0x01, // Major Command = 0x20. Minor Command = 0x01. + 0x3C0, // Attribute Controller Data Register + 0x10, // Loop Count = 16 (Number of Pallette Entries) + 0x0, // Index to select (Index = 0, palettes) + 0x00, // Palette 0 + 0x01, // Palette 1 + 0x02, // Palette 2 + 0x03, // Palette 3 + 0x04, // Palette 4 + 0x05, // Palette 5 + 0x06, // Palette 6 + 0x07, // Palette 7 + 0x08, // Palette 8 + 0x09, // Palette 9 + 0x0A, // Palette 10 + 0x0B, // Palette 11 + 0x0C, // Palette 12 + 0x0D, // Palette 13 + 0x0E, // Palette 14 + 0x0F, // Palette 15 + + // + // This Stream performs a UCHAR READ of port 0x3DA + // + 0x10 | CMD_STREAM_READ, // Major Command = 0x10. Minor Command = 0x08. + 0x3DA, // Index Status 1 Register Port Address + + // + // This Stream performs a UCHAR WRITE of value 0x20 at port 0x3C0 + // + 0x10 | CMD_STREAM_WRITE, // Major Command = 0x10. Minor Command = 0x00. + 0x3C0, // Attribute Controller Data Register + 0x20, // Set Palette Address Source + + // + // End of Stream Marker + // + 0x0 // End of command stream +}; + +CHAR FontData[256 * 13] = +{ + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 13 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 26 + 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 39 + 0x14, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 52 + 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 65 + 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 78 + 0x10, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 91 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, // 104 + 0x14, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 117 + 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 130 + 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 143 + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 156 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, // 169 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 182 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 195 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 208 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 221 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 234 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 247 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 260 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 273 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 286 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 299 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 312 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 325 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 338 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 351 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 364 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 377 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 390 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 403 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 416 + 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, // 429 + 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 442 + 0x00, 0x14, 0x14, 0x14, 0x7F, 0x28, 0xFE, 0x50, 0x50, 0x50, 0x00, 0x00, 0x00, // 455 + 0x10, 0x3C, 0x50, 0x50, 0x70, 0x38, 0x1C, 0x14, 0x14, 0x78, 0x10, 0x00, 0x00, // 468 + 0x00, 0x61, 0x92, 0x94, 0x68, 0x18, 0x16, 0x29, 0x49, 0x86, 0x00, 0x00, 0x00, // 481 + 0x00, 0x18, 0x24, 0x24, 0x38, 0x71, 0x89, 0x8E, 0xC6, 0x7E, 0x00, 0x00, 0x00, // 494 + 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 507 + 0x06, 0x08, 0x10, 0x30, 0x20, 0x20, 0x20, 0x20, 0x30, 0x10, 0x08, 0x06, 0x00, // 520 + 0x60, 0x10, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, // 533 + 0x00, 0x10, 0x52, 0x24, 0x3C, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 546 + 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xFE, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, // 559 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x10, 0x20, 0x00, // 572 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 585 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, // 598 + 0x01, 0x02, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x40, 0x80, 0x00, // 611 + 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x42, 0x24, 0x3C, 0x00, 0x00, 0x00, // 624 + 0x00, 0x30, 0xD0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFE, 0x00, 0x00, 0x00, // 637 + 0x00, 0x78, 0x04, 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x7C, 0x00, 0x00, 0x00, // 650 + 0x00, 0x78, 0x04, 0x04, 0x08, 0x30, 0x0C, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00, // 663 + 0x00, 0x08, 0x18, 0x28, 0x28, 0x48, 0x88, 0xFC, 0x08, 0x08, 0x00, 0x00, 0x00, // 676 + 0x00, 0x3C, 0x20, 0x20, 0x38, 0x04, 0x04, 0x04, 0x04, 0x38, 0x00, 0x00, 0x00, // 689 + 0x00, 0x1C, 0x20, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x22, 0x1C, 0x00, 0x00, 0x00, // 702 + 0x00, 0x7E, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, 0x00, // 715 + 0x00, 0x3C, 0x42, 0x42, 0x24, 0x3C, 0x46, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 728 + 0x00, 0x38, 0x44, 0x42, 0x42, 0x46, 0x3A, 0x02, 0x04, 0x38, 0x00, 0x00, 0x00, // 741 + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, // 754 + 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x10, 0x20, 0x00, // 767 + 0x00, 0x00, 0x00, 0x02, 0x0C, 0x10, 0x60, 0x10, 0x0C, 0x02, 0x00, 0x00, 0x00, // 780 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, // 793 + 0x00, 0x00, 0x00, 0x40, 0x30, 0x08, 0x06, 0x08, 0x30, 0x40, 0x00, 0x00, 0x00, // 806 + 0x00, 0x7C, 0x42, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, // 819 + 0x00, 0x3C, 0x62, 0xDE, 0xB2, 0xA2, 0xA6, 0x9B, 0x44, 0x3C, 0x00, 0x00, 0x00, // 832 + 0x00, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x81, 0x00, 0x00, 0x00, // 845 + 0x00, 0x00, 0x7C, 0x42, 0x42, 0x7C, 0x42, 0x42, 0x42, 0x7C, 0x00, 0x00, 0x00, // 858 + 0x00, 0x00, 0x3E, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x3E, 0x00, 0x00, 0x00, // 871 + 0x00, 0x00, 0x78, 0x44, 0x42, 0x42, 0x42, 0x42, 0x44, 0x78, 0x00, 0x00, 0x00, // 884 + 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, // 897 + 0x00, 0x00, 0x7E, 0x40, 0x40, 0x40, 0x7C, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, // 910 + 0x00, 0x00, 0x3E, 0x40, 0x80, 0x80, 0x8E, 0x82, 0x42, 0x3E, 0x00, 0x00, 0x00, // 923 + 0x00, 0x00, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, // 936 + 0x00, 0x00, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x00, 0x00, 0x00, // 949 + 0x00, 0x00, 0x3C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00, // 962 + 0x00, 0x00, 0x42, 0x44, 0x48, 0x70, 0x50, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, // 975 + 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, // 988 + 0x00, 0x00, 0xC6, 0xC6, 0xAA, 0xAA, 0xAA, 0x92, 0x82, 0x82, 0x00, 0x00, 0x00, // 1001 + 0x00, 0x00, 0x42, 0x62, 0x52, 0x52, 0x4A, 0x4A, 0x46, 0x42, 0x00, 0x00, 0x00, // 1014 + 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, // 1027 + 0x00, 0x00, 0x7C, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, // 1040 + 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x06, 0x03, 0x00, // 1053 + 0x00, 0x00, 0x78, 0x44, 0x44, 0x44, 0x78, 0x48, 0x44, 0x42, 0x00, 0x00, 0x00, // 1066 + 0x00, 0x00, 0x3E, 0x40, 0x40, 0x38, 0x04, 0x02, 0x02, 0x7C, 0x00, 0x00, 0x00, // 1079 + 0x00, 0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, // 1092 + 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 1105 + 0x00, 0x00, 0x81, 0x42, 0x42, 0x44, 0x24, 0x28, 0x38, 0x10, 0x00, 0x00, 0x00, // 1118 + 0x00, 0x00, 0x81, 0x81, 0x92, 0x5A, 0x5A, 0x6A, 0x66, 0x24, 0x00, 0x00, 0x00, // 1131 + 0x00, 0x00, 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81, 0x00, 0x00, 0x00, // 1144 + 0x00, 0x00, 0x82, 0x44, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, // 1157 + 0x00, 0x00, 0xFE, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0xFE, 0x00, 0x00, 0x00, // 1170 + 0x1E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x00, // 1183 + 0x80, 0x40, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x02, 0x02, 0x01, 0x00, // 1196 + 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00, // 1209 + 0x00, 0x08, 0x08, 0x18, 0x14, 0x24, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, // 1222 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, // 1235 + 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1248 + 0x00, 0x00, 0x00, 0x38, 0x04, 0x04, 0x3C, 0x44, 0x44, 0x3E, 0x00, 0x00, 0x00, // 1261 + 0x40, 0x40, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x62, 0x5C, 0x00, 0x00, 0x00, // 1274 + 0x00, 0x00, 0x00, 0x1E, 0x20, 0x40, 0x40, 0x40, 0x20, 0x1E, 0x00, 0x00, 0x00, // 1287 + 0x02, 0x02, 0x02, 0x3A, 0x46, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, // 1300 + 0x00, 0x00, 0x00, 0x3C, 0x22, 0x42, 0x7E, 0x40, 0x40, 0x3E, 0x00, 0x00, 0x00, // 1313 + 0x1E, 0x20, 0x20, 0xFE, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, // 1326 + 0x00, 0x00, 0x00, 0x3A, 0x46, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x02, 0x02, 0x3C, // 1339 + 0x40, 0x40, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, // 1352 + 0x18, 0x18, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, // 1365 + 0x18, 0x18, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, // 1378 + 0x40, 0x40, 0x40, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x00, 0x00, 0x00, // 1391 + 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, // 1404 + 0x00, 0x00, 0x00, 0xB6, 0xDA, 0x92, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, // 1417 + 0x00, 0x00, 0x00, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, // 1430 + 0x00, 0x00, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 1443 + 0x00, 0x00, 0x00, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x62, 0x5C, 0x40, 0x40, 0x40, // 1456 + 0x00, 0x00, 0x00, 0x3A, 0x46, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x02, 0x02, 0x02, // 1469 + 0x00, 0x00, 0x00, 0x5C, 0x64, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, // 1482 + 0x00, 0x00, 0x00, 0x3C, 0x40, 0x60, 0x18, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00, // 1495 + 0x00, 0x00, 0x20, 0xFC, 0x20, 0x20, 0x20, 0x20, 0x20, 0x1C, 0x00, 0x00, 0x00, // 1508 + 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, // 1521 + 0x00, 0x00, 0x00, 0x82, 0x44, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, // 1534 + 0x00, 0x00, 0x00, 0x81, 0x91, 0x5A, 0x5A, 0x6A, 0x24, 0x24, 0x00, 0x00, 0x00, // 1547 + 0x00, 0x00, 0x00, 0x42, 0x24, 0x18, 0x18, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, // 1560 + 0x00, 0x00, 0x00, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x10, 0x30, 0xE0, // 1573 + 0x00, 0x00, 0x00, 0x7E, 0x02, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x00, 0x00, 0x00, // 1586 + 0x1C, 0x10, 0x10, 0x10, 0x10, 0x60, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x00, // 1599 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, // 1612 + 0x30, 0x08, 0x08, 0x08, 0x08, 0x06, 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, // 1625 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, // 1638 + 0x00, 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x3C, 0x00, 0x00, 0x00, // 1651 + 0x00, 0x00, 0x3E, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x3E, 0x04, 0x02, 0x06, // 1664 + 0x00, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, // 1677 + 0x08, 0x10, 0x00, 0x3C, 0x22, 0x42, 0x7E, 0x40, 0x40, 0x3E, 0x00, 0x00, 0x00, // 1690 + 0x18, 0x24, 0x00, 0x38, 0x04, 0x04, 0x3C, 0x44, 0x44, 0x3E, 0x00, 0x00, 0x00, // 1703 + 0x00, 0x24, 0x00, 0x38, 0x04, 0x04, 0x3C, 0x44, 0x44, 0x3E, 0x00, 0x00, 0x00, // 1716 + 0x10, 0x08, 0x00, 0x38, 0x04, 0x04, 0x3C, 0x44, 0x44, 0x3E, 0x00, 0x00, 0x00, // 1729 + 0x10, 0x28, 0x10, 0x38, 0x04, 0x04, 0x3C, 0x44, 0x44, 0x3E, 0x00, 0x00, 0x00, // 1742 + 0x00, 0x00, 0x00, 0x1E, 0x20, 0x40, 0x40, 0x40, 0x20, 0x1E, 0x08, 0x04, 0x0C, // 1755 + 0x18, 0x24, 0x00, 0x3C, 0x22, 0x42, 0x7E, 0x40, 0x40, 0x3E, 0x00, 0x00, 0x00, // 1768 + 0x00, 0x12, 0x00, 0x3C, 0x22, 0x42, 0x7E, 0x40, 0x40, 0x3E, 0x00, 0x00, 0x00, // 1781 + 0x10, 0x08, 0x00, 0x3C, 0x22, 0x42, 0x7E, 0x40, 0x40, 0x3E, 0x00, 0x00, 0x00, // 1794 + 0x00, 0x24, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, // 1807 + 0x18, 0x24, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, // 1820 + 0x10, 0x08, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, // 1833 + 0x24, 0x00, 0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x81, 0x00, 0x00, 0x00, // 1846 + 0x10, 0x28, 0x10, 0x28, 0x28, 0x24, 0x44, 0x7E, 0x42, 0x81, 0x00, 0x00, 0x00, // 1859 + 0x08, 0x10, 0x7E, 0x40, 0x40, 0x40, 0x7C, 0x40, 0x40, 0x7E, 0x00, 0x00, 0x00, // 1872 + 0x00, 0x00, 0x00, 0xFC, 0x12, 0x12, 0x7E, 0x90, 0x90, 0x6E, 0x00, 0x00, 0x00, // 1885 + 0x00, 0x00, 0x0F, 0x18, 0x18, 0x28, 0x2E, 0x78, 0x48, 0x8F, 0x00, 0x00, 0x00, // 1898 + 0x18, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 1911 + 0x00, 0x24, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 1924 + 0x20, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 1937 + 0x18, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, // 1950 + 0x20, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, // 1963 + 0x00, 0x24, 0x00, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x10, 0x30, 0xE0, // 1976 + 0x24, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, // 1989 + 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 2002 + 0x00, 0x08, 0x1C, 0x28, 0x48, 0x48, 0x48, 0x68, 0x1C, 0x08, 0x00, 0x00, 0x00, // 2015 + 0x00, 0x0E, 0x10, 0x10, 0x10, 0x38, 0x10, 0x10, 0x20, 0x3E, 0x00, 0x00, 0x00, // 2028 + 0x00, 0x81, 0x42, 0x24, 0x18, 0x7C, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00, 0x00, // 2041 + 0x00, 0xE0, 0x90, 0x90, 0xE0, 0x96, 0xBC, 0x94, 0x92, 0x9E, 0x00, 0x00, 0x00, // 2054 + 0x0E, 0x10, 0x10, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xE0, // 2067 + 0x08, 0x10, 0x00, 0x38, 0x04, 0x04, 0x3C, 0x44, 0x44, 0x3E, 0x00, 0x00, 0x00, // 2080 + 0x08, 0x10, 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, // 2093 + 0x08, 0x10, 0x00, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 2106 + 0x08, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x00, 0x00, 0x00, // 2119 + 0x14, 0x28, 0x00, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, // 2132 + 0x14, 0x28, 0x42, 0x62, 0x52, 0x52, 0x4A, 0x4A, 0x46, 0x42, 0x00, 0x00, 0x00, // 2145 + 0x00, 0x78, 0x08, 0x38, 0x48, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2158 + 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2171 + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x42, 0x3E, 0x00, // 2184 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, // 2197 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, // 2210 + 0x00, 0xC4, 0x48, 0x48, 0x50, 0x37, 0x21, 0x43, 0x44, 0x87, 0x00, 0x00, 0x00, // 2223 + 0x00, 0xC4, 0x48, 0x48, 0x50, 0x22, 0x26, 0x4A, 0x4F, 0x82, 0x00, 0x00, 0x00, // 2236 + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, // 2249 + 0x00, 0x00, 0x00, 0x00, 0x12, 0x24, 0x48, 0x24, 0x12, 0x00, 0x00, 0x00, 0x00, // 2262 + 0x00, 0x00, 0x00, 0x00, 0x48, 0x24, 0x12, 0x24, 0x48, 0x00, 0x00, 0x00, 0x00, // 2275 + 0x94, 0x00, 0x00, 0x94, 0x00, 0x94, 0x00, 0x00, 0x94, 0x00, 0x94, 0x00, 0x00, // 2288 + 0x49, 0x94, 0x00, 0x49, 0x94, 0x49, 0x00, 0x94, 0x49, 0x94, 0x49, 0x00, 0x94, // 2301 + 0xFF, 0x94, 0x94, 0xFF, 0x94, 0xFF, 0x94, 0x94, 0xFF, 0x94, 0xFF, 0x94, 0x94, // 2314 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 2327 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 2340 + 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, // 2353 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // 2366 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // 2379 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, // 2392 + 0x14, 0x14, 0x14, 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x14, 0x14, 0x14, 0x14, 0x14, // 2405 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // 2418 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14, 0x14, 0x14, 0x14, // 2431 + 0x14, 0x14, 0x14, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, // 2444 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2457 + 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, // 2470 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 2483 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2496 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2509 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 2522 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 2535 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2548 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 2561 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, // 2574 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // 2587 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, // 2600 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x17, 0x14, 0x14, 0x14, 0x14, 0x14, // 2613 + 0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, // 2626 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x14, 0x14, // 2639 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14, 0x14, 0x14, 0x14, // 2652 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, // 2665 + 0x14, 0x14, 0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14, 0x14, 0x14, 0x14, // 2678 + 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, // 2691 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2704 + 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, // 2717 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // 2730 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2743 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x10, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, // 2756 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, // 2769 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // 2782 + 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, // 2795 + 0x10, 0x10, 0x10, 0x10, 0x10, 0xFF, 0x10, 0xFF, 0x10, 0x10, 0x10, 0x10, 0x10, // 2808 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2821 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 2834 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 2847 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 2860 + 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, // 2873 + 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, // 2886 + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2899 + 0x00, 0x00, 0x00, 0x31, 0x49, 0x86, 0x84, 0x84, 0x8A, 0x71, 0x00, 0x00, 0x00, // 2912 + 0x38, 0x48, 0x48, 0x50, 0x50, 0x58, 0x44, 0x42, 0x42, 0x5C, 0x00, 0x00, 0x00, // 2925 + 0x00, 0x00, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, // 2938 + 0x00, 0x00, 0x00, 0x7F, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, // 2951 + 0x00, 0x00, 0xFF, 0x40, 0x20, 0x10, 0x10, 0x20, 0x40, 0xFF, 0x00, 0x00, 0x00, // 2964 + 0x00, 0x00, 0x00, 0x7F, 0x84, 0x84, 0x84, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, // 2977 + 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x5A, 0x40, 0x40, 0x40, // 2990 + 0x00, 0x00, 0x00, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, // 3003 + 0x00, 0x00, 0x10, 0x7C, 0x92, 0x92, 0x92, 0x92, 0x7C, 0x10, 0x00, 0x00, 0x00, // 3016 + 0x00, 0x00, 0x38, 0x44, 0x82, 0xBA, 0x82, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, // 3029 + 0x00, 0x00, 0x7C, 0xC6, 0x82, 0x82, 0x82, 0x84, 0x44, 0xEE, 0x00, 0x00, 0x00, // 3042 + 0x38, 0x40, 0x60, 0x18, 0x24, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00, 0x00, // 3055 + 0x00, 0x00, 0x00, 0x00, 0x66, 0x99, 0x99, 0x99, 0x66, 0x00, 0x00, 0x00, 0x00, // 3068 + 0x10, 0x10, 0x10, 0x7C, 0x92, 0x91, 0x91, 0x91, 0x92, 0x7C, 0x10, 0x10, 0x10, // 3081 + 0x00, 0x00, 0x00, 0x1E, 0x20, 0x40, 0x7C, 0x40, 0x60, 0x1E, 0x00, 0x00, 0x00, // 3094 + 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x82, 0x82, 0x82, 0x82, 0x00, 0x00, 0x00, // 3107 + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, // 3120 + 0x00, 0x00, 0x00, 0x10, 0x10, 0xFE, 0x10, 0x10, 0x00, 0xFE, 0x00, 0x00, 0x00, // 3133 + 0x00, 0x00, 0x40, 0x30, 0x08, 0x06, 0x08, 0x30, 0x40, 0x00, 0x7E, 0x00, 0x00, // 3146 + 0x00, 0x00, 0x02, 0x0C, 0x10, 0x60, 0x10, 0x0C, 0x02, 0x00, 0x7E, 0x00, 0x00, // 3159 + 0x0C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 3172 + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x60, // 3185 + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, // 3198 + 0x00, 0x00, 0x00, 0x00, 0x72, 0x4E, 0x00, 0x72, 0x4E, 0x00, 0x00, 0x00, 0x00, // 3211 + 0x00, 0x10, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3224 + 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // 3237 + 0x00, 0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // 3250 + 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0xC4, 0x28, 0x28, 0x18, 0x10, 0x00, // 3263 + 0x00, 0x3C, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3276 + 0x00, 0x3C, 0x04, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3289 + 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, // 3302 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 3315 +}; diff --git a/reactos/drivers/base/bootvid/bootimage.bmp b/reactos/drivers/base/bootvid/bootimage.bmp deleted file mode 100755 index b074e82903258e57f9b9851bfed5ada07398a97d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21632 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 SMlP8mU@Dd0h6EjkYv?dK5FG7PS5crIzchWrN zVDUtg_TGN+D%+zo=0Snn!5e6uSA=NhEyu9qAY1)Wnqs6=lgt~BZ_ z22HTf-iS|!$CN}mD>nq5VA{rE&6QQiSzaiPMqoV2Y(c!eoB&flaS>qZXT*YMS9s=( z7{ZM}vq?;XCI4p?{q&svEKlGNXL1xqytElPQX`|1D~J!C#afmgJ(K22RvelWyG(`w zNnV`W7K`)zP=WPU!3?5AKO5HPc7tTZ#PgEG0d|&i-|}>uQ_d&!vx{{QqW2Vd&dHqT z2|#!d9Z`XJdPD9TNOc8QALL4&gXCGWmI1iH-)$ZZk|*bgj!$Tgx!#5u`3?>= 1) + { + /* Set bitmask */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, i); + + /* Read it back...it should be the same */ + if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != i) + { + /* Reset the registers and fail */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF); + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); + return FALSE; + } + } + + /* Select Read Map Select Register */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 4); + + /* Read it back...it should be 3 */ + if (READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) != 3) + { + /* Reset the registers and fail */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0); + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 0xFF); + return FALSE; + } + + /* Write the registers we read earlier */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg); + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, VgaReg2); + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, VgaReg3); + + /* Read sequencer address */ + SeqReg = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4); + + /* Select memory mode register */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, 4); + + /* Read it back...it should still be 4 */ + if (((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4)) & 7) != 4) + { + /* Fail */ + return FALSE; + } + + /* Read sequencer Data */ + SeqReg2 = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5); + + /* Write null plane */ + WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x100); + + /* Write sequencer flag */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2 ^ 8); + + /* Read it back */ + if ((READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5)) != (SeqReg2 ^ 8)) + { + /* Not the same value...restore registers and fail */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, 2); + WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300); + return FALSE; + } + + /* Now write the registers we read */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C5, SeqReg2); + WRITE_PORT_USHORT((PUSHORT)VgaRegisterBase + 0x3C4, 0x300); + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3C4, SeqReg); + + /* VGA is present! */ + return TRUE; +} + +/* PUBLIC FUNCTIONS **********************************************************/ + /* - * ReactOS Boot video driver - * - * Copyright (C) 2003 Casper S. Hornstroup - * Copyright (C) 2004, 2005 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$ + * @implemented */ - -/* INCLUDES ******************************************************************/ - -#include "bootvid.h" -#include "resource.h" - -#define NDEBUG -#include - -//#define USE_PROGRESS_BAR - -/* GLOBALS *******************************************************************/ - -static volatile LONG ShutdownNotify; -static KEVENT ShutdownCompleteEvent; - -/* DATA **********************************************************************/ - -static RGBQUAD _MainPalette[16]; -static UCHAR _Square1[9 * 4]; -static UCHAR _Square2[9 * 4]; -static UCHAR _Square3[9 * 4]; - -/* FUNCTIONS *****************************************************************/ - -static VOID NTAPI -BootVidAnimationThread(PVOID Ignored) +BOOLEAN +NTAPI +VidInitialize(IN BOOLEAN SetMode) { - UCHAR PaletteBitmapBuffer[sizeof(BITMAPINFOHEADER) + sizeof(_MainPalette)]; - PBITMAPINFOHEADER PaletteBitmap = (PBITMAPINFOHEADER)PaletteBitmapBuffer; - LPRGBQUAD Palette = (LPRGBQUAD)(PaletteBitmapBuffer + sizeof(BITMAPINFOHEADER)); - ULONG Iteration, Index, ClrUsed; - UINT AnimBarPos; - LARGE_INTEGER Interval; - - /* - * Build a bitmap containing the fade in palette. The palette entries - * are then processed in a loop and set using VidBitBlt function. - */ - - ClrUsed = sizeof(_MainPalette) / sizeof(_MainPalette[0]); - RtlZeroMemory(PaletteBitmap, sizeof(BITMAPINFOHEADER)); - PaletteBitmap->biSize = sizeof(BITMAPINFOHEADER); - PaletteBitmap->biBitCount = 4; - PaletteBitmap->biClrUsed = ClrUsed; + ULONG Context = 0; + PHYSICAL_ADDRESS TranslatedAddress; + PHYSICAL_ADDRESS NullAddress = {{0}}; + ULONG AddressSpace = 1; + BOOLEAN Result; + ULONG_PTR Base; - /* - * Main animation loop. - */ + /* Make sure that we have a bus translation function */ + if (!HalFindBusAddressTranslation) return FALSE; - for (Iteration = 0, AnimBarPos = 0; !ShutdownNotify; Iteration++) - { - if (Iteration <= PALETTE_FADE_STEPS) - { - for (Index = 0; Index < ClrUsed; Index++) - { - Palette[Index].rgbRed = - _MainPalette[Index].rgbRed * Iteration / PALETTE_FADE_STEPS; - Palette[Index].rgbGreen = - _MainPalette[Index].rgbGreen * Iteration / PALETTE_FADE_STEPS; - Palette[Index].rgbBlue = - _MainPalette[Index].rgbBlue * Iteration / PALETTE_FADE_STEPS; - } + /* Get the VGA Register address */ + Result = HalFindBusAddressTranslation(NullAddress, + &AddressSpace, + &TranslatedAddress, + &Context, + TRUE); + if (!Result) return FALSE; - VidBitBlt(PaletteBitmapBuffer, 0, 0); - } -#ifdef USE_PROGRESS_BAR - else - { - break; - } + /* See if this is I/O Space, which we need to map */ +TryAgain: + if (!AddressSpace) + { + /* Map it */ + Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress, 0x400, MmNonCached); + } + else + { + /* The base is the translated address, no need to map I/O space */ + Base = TranslatedAddress.LowPart; + } - Interval.QuadPart = -PALETTE_FADE_TIME; -#else + /* Set the VGA Register base and now check if we have a VGA device */ + VgaRegisterBase = Base; + if (VgaIsPresent()) + { + /* Translate the VGA Memory Address */ + NullAddress.LowPart = 0xA0000; + AddressSpace = 0; + Result = HalFindBusAddressTranslation(NullAddress, + &AddressSpace, + &TranslatedAddress, + &Context, + FALSE); + if (Result) + { + /* Success! See if this is I/O Space, which we need to map */ + if (!AddressSpace) + { + /* Map it */ + Base = (ULONG_PTR)MmMapIoSpace(TranslatedAddress, + 0x20000, + MmNonCached); + } + else + { + /* The base is the translated address, no need to map I/O space */ + Base = TranslatedAddress.LowPart; + } -#if 0 - if (AnimBarPos == 0) - { - VidSolidColorFill(0x173, 354, 0x178, 354 + 9, 0); - } - else if (AnimBarPos > 3) - { - VidSolidColorFill(0xe3 + AnimBarPos * 8, 354, - 0xe8 + AnimBarPos * 8, 354 + 9, - 0); - } + /* Set the VGA Memory Base */ + VgaBase = Base; - if (AnimBarPos >= 3) - { - VidBufferToScreenBlt(_Square1, 0xeb + AnimBarPos * 8, 354, 6, 9, 4); - } - if (AnimBarPos >= 2 && AnimBarPos <= 16) - { - VidBufferToScreenBlt(_Square2, 0xf3 + AnimBarPos * 8, 354, 6, 9, 4); - } - if (AnimBarPos >= 1 && AnimBarPos <= 15) - { - VidBufferToScreenBlt(_Square3, 0xfb + AnimBarPos * 8, 354, 6, 9, 4); - } -#endif + /* Now check if we have to set the mode */ + if (SetMode) + { + // + // Reset the display + // + HalResetDisplay(); + curr_x = 0; + curr_y = 0; - if (Iteration <= PALETTE_FADE_STEPS) - { - Interval.QuadPart = -PALETTE_FADE_TIME; - if ((Iteration % 5) == 0) - AnimBarPos++; - } - else - { - Interval.QuadPart = -PALETTE_FADE_TIME * 5; - AnimBarPos++; - } - AnimBarPos = Iteration % 18; -#endif + /* Initialize it */ + VgaInterpretCmdStream(AT_Initialization); + return TRUE; + } + } + } + else + { + /* It's not, so unmap the I/O space if we mapped it */ + if (!AddressSpace) MmUnmapIoSpace((PVOID)VgaRegisterBase, 0x400); + } - /* Wait for a bit. */ - KeDelayExecutionThread(KernelMode, FALSE, &Interval); - } + /* If we got here, then we failed...let's try again */ + Result = HalFindBusAddressTranslation(NullAddress, + &AddressSpace, + &TranslatedAddress, + &Context, + TRUE); + if (Result) goto TryAgain; - DPRINT("Finishing bootvid thread.\n"); - KeSetEvent(&ShutdownCompleteEvent, 0, FALSE); - - PsTerminateSystemThread(0); + /* If we got here, then we failed even past our re-try... */ + return FALSE; } - -NTSTATUS NTAPI -BootVidDisplayBootLogo(PVOID ImageBase) +/* + * @implemented + */ +VOID +NTAPI +VidResetDisplay(IN BOOLEAN HalReset) { - PBITMAPINFOHEADER BitmapInfoHeader; - LPRGBQUAD Palette; - static const ULONG BitmapIds[2] = {IDB_BOOTIMAGE, IDB_BAR}; - PUCHAR BitmapData[2]; - ULONG Index; - HANDLE BitmapThreadHandle; - CLIENT_ID BitmapThreadId; - NTSTATUS Status; + /* Clear the current position */ + curr_x = 0; + curr_y = 0; - KeInitializeEvent(&ShutdownCompleteEvent, NotificationEvent, FALSE); + /* Clear the screen with HAL if we were asked to */ + if (HalReset) HalResetDisplay(); - /* - * Get the bitmaps from the executable. - */ + /* Re-initialize the VGA Display */ + VgaInterpretCmdStream(AT_Initialization); - for (Index = 0; Index < sizeof(BitmapIds) / sizeof(BitmapIds[0]); Index++) - { - PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; - LDR_RESOURCE_INFO ResourceInfo; - ULONG Size; - - ResourceInfo.Type = /* RT_BITMAP */ 2; - ResourceInfo.Name = BitmapIds[Index]; - ResourceInfo.Language = 0x09; - - Status = LdrFindResource_U( - ImageBase, - &ResourceInfo, - RESOURCE_DATA_LEVEL, - &ResourceDataEntry); - - if (!NT_SUCCESS(Status)) - { - DPRINT("LdrFindResource_U() failed with status 0x%.08x\n", Status); - return Status; - } - - Status = LdrAccessResource( - ImageBase, - ResourceDataEntry, - (PVOID*)&BitmapData[Index], - &Size); - - if (!NT_SUCCESS(Status)) - { - DPRINT("LdrAccessResource() failed with status 0x%.08x\n", Status); - return Status; - } - } - - - /* - * Initialize the graphics output. - */ - - if (!VidInitialize(TRUE)) - { - return STATUS_UNSUCCESSFUL; - } - - /* - * Load the bar bitmap and get the square data from it. - */ - - VidBitBlt(BitmapData[1], 0, 0); - VidScreenToBufferBlt(_Square1, 0, 0, 6, 9, 4); - VidScreenToBufferBlt(_Square2, 8, 0, 6, 9, 4); - VidScreenToBufferBlt(_Square3, 16, 0, 6, 9, 4); - - /* - * Save the main image palette and replace it with black palette, so - * we can do fade in effect later. - */ - - BitmapInfoHeader = (PBITMAPINFOHEADER)BitmapData[0]; - Palette = (LPRGBQUAD)(BitmapData[0] + BitmapInfoHeader->biSize); - RtlCopyMemory(_MainPalette, Palette, sizeof(_MainPalette)); - RtlZeroMemory(Palette, sizeof(_MainPalette)); - - /* - * Display the main image. - */ - - VidBitBlt(BitmapData[0], 0, 0); - - /* - * Start a thread that handles the fade in and bar animation effects. - */ - - Status = PsCreateSystemThread( - &BitmapThreadHandle, - THREAD_ALL_ACCESS, - NULL, - NULL, - &BitmapThreadId, - BootVidAnimationThread, - NULL); - - if (!NT_SUCCESS(Status)) - { - VidCleanUp(); - return Status; - } - - ZwClose(BitmapThreadHandle); - - return STATUS_SUCCESS; + /* Re-initialize the palette and fill the screen black */ + InitializePalette(); + VidSolidColorFill(0, 0, 639, 479, 0); } - -VOID NTAPI -BootVidUpdateProgress(ULONG Progress) -{ -#ifdef USE_PROGRESS_BAR - if (ShutdownNotify == 0) - { - VidSolidColorFill(0x103, 354, 0x103 + (Progress * 120 / 100), 354 + 9, 1); - } -#endif -} - - -VOID NTAPI -BootVidFinalizeBootLogo(VOID) -{ - InterlockedIncrement(&ShutdownNotify); - DPRINT1("Waiting for bootvid thread to finish.\n"); - KeWaitForSingleObject(&ShutdownCompleteEvent, Executive, KernelMode, - FALSE, NULL); - DPRINT1("Bootvid thread to finish.\n"); - //VidResetDisplay(); -} - - -NTSTATUS STDCALL -DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) -{ - return STATUS_SUCCESS; -} diff --git a/reactos/drivers/base/bootvid/bootvid.def b/reactos/drivers/base/bootvid/bootvid.def index 10aa908c650..ccd481bd100 100644 --- a/reactos/drivers/base/bootvid/bootvid.def +++ b/reactos/drivers/base/bootvid/bootvid.def @@ -1,14 +1,15 @@ -LIBRARY bootvid.sys +LIBRARY BOOTVID.DLL EXPORTS -VidInitialize -VidCleanUp -VidResetDisplay -VidBufferToScreenBlt -VidScreenToBufferBlt -VidBitBlt -VidSolidColorFill -VidDisplayString -BootVidDisplayBootLogo -BootVidUpdateProgress -BootVidFinalizeBootLogo +VidBitBlt@12 +VidBufferToScreenBlt@24 +VidCleanUp@0 +VidDisplayString@4 +VidDisplayStringXY +VidInitialize@4 +VidResetDisplay@4 +VidScreenToBufferBlt@24 +VidSetScrollRegion@16 +VidSetTextColor@4 +VidSolidColorFill@20 + diff --git a/reactos/drivers/base/bootvid/bootvid.h b/reactos/drivers/base/bootvid/bootvid.h deleted file mode 100644 index 4e82c800aa3..00000000000 --- a/reactos/drivers/base/bootvid/bootvid.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * ReactOS Boot video driver - * - * Copyright (C) 2003 Casper S. Hornstroup - * Copyright (C) 2004, 2005 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$ - */ - -#ifndef _BOOTVID_H -#define _BOOTVID_H - -#include -#include -#include -#include - -#define PALETTE_FADE_STEPS 15 -#define PALETTE_FADE_TIME 20 * 10000 /* 20ms */ - -BOOLEAN NTAPI VidInitialize(BOOLEAN); -VOID NTAPI VidCleanUp(VOID); -VOID NTAPI VidResetDisplay(VOID); -VOID NTAPI VidBufferToScreenBlt(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG); -VOID NTAPI VidScreenToBufferBlt(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG); -VOID NTAPI VidBitBlt(PUCHAR, ULONG, ULONG); -VOID NTAPI VidSolidColorFill(ULONG, ULONG, ULONG, ULONG, ULONG); -VOID NTAPI VidDisplayString(PCSTR); - -typedef BOOLEAN (NTAPI *PVID_INITIALIZE)(BOOLEAN); -typedef VOID (NTAPI *PVID_CLEAN_UP)(VOID); -typedef VOID (NTAPI *PVID_RESET_DISPLAY)(VOID); -typedef VOID (NTAPI *PVID_BUFFER_TO_SCREEN_BLT)(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG); -typedef VOID (NTAPI *PVID_SCREEN_TO_BUFFER_BLT)(PUCHAR, ULONG, ULONG, ULONG, ULONG, LONG); -typedef VOID (NTAPI *PVID_BITBLT)(PUCHAR, ULONG, ULONG); -typedef VOID (NTAPI *PVID_SOLID_COLOR_FILL)(ULONG, ULONG, ULONG, ULONG, ULONG); -typedef VOID (NTAPI *PVID_DISPLAY_STRING)(PCSTR); - -typedef struct _VID_FUNCTION_TABLE -{ - PVID_INITIALIZE Initialize; - PVID_CLEAN_UP CleanUp; - PVID_RESET_DISPLAY ResetDisplay; - PVID_BUFFER_TO_SCREEN_BLT BufferToScreenBlt; - PVID_SCREEN_TO_BUFFER_BLT ScreenToBufferBlt; - PVID_BITBLT BitBlt; - PVID_SOLID_COLOR_FILL SolidColorFill; - PVID_DISPLAY_STRING DisplayString; -} VID_FUNCTION_TABLE, *PVID_FUNCTION_TABLE; - -#endif /* _BOOTVID_H */ diff --git a/reactos/drivers/base/bootvid/bootvid.rbuild b/reactos/drivers/base/bootvid/bootvid.rbuild index ab5f97f598b..0cf8be0c21b 100644 --- a/reactos/drivers/base/bootvid/bootvid.rbuild +++ b/reactos/drivers/base/bootvid/bootvid.rbuild @@ -1,14 +1,12 @@ - + - + . ntoskrnl hal bootvid.c - vid.c - vid_vga.c - vid_vgatext.c - vid_xbox.c + bootdata.c + vga.c bootvid.rc - + \ No newline at end of file diff --git a/reactos/drivers/base/bootvid/bootvid.rc b/reactos/drivers/base/bootvid/bootvid.rc index 946f4b7edd4..e6a6ac115d0 100644 --- a/reactos/drivers/base/bootvid/bootvid.rc +++ b/reactos/drivers/base/bootvid/bootvid.rc @@ -3,12 +3,8 @@ #include "resource.h" #define REACTOS_VERSION_DLL -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Boot Video\0" -#define REACTOS_STR_INTERNAL_NAME "bootvid\0" -#define REACTOS_STR_ORIGINAL_FILENAME "bootvid.sys\0" +#define REACTOS_STR_FILE_DESCRIPTION "VGA Boot Driver\0" +#define REACTOS_STR_INTERNAL_NAME "bootvid.dll\0" +#define REACTOS_STR_ORIGINAL_FILENAME "bootvid.dll\0" + #include - -IDB_BOOTIMAGE BITMAP DISCARDABLE "bootimage.bmp" -IDB_BAR BITMAP DISCARDABLE "bar.bmp" - - diff --git a/reactos/drivers/base/bootvid/precomp.h b/reactos/drivers/base/bootvid/precomp.h new file mode 100644 index 00000000000..903d0d2f4c5 --- /dev/null +++ b/reactos/drivers/base/bootvid/precomp.h @@ -0,0 +1,46 @@ +#include "ntddk.h" +#include "arc\arc.h" +#include "halfuncs.h" +#include "drivers\bootvid\bootvid.h" + +// +// Command Stream Definitions +// +#define CMD_STREAM_WRITE 0x0 +#define CMD_STREAM_WRITE_ARRAY 0x2 +#define CMD_STREAM_USHORT 0x4 +#define CMD_STREAM_READ 0x8 + +// +// Bitmap Header +// +typedef struct tagBITMAPINFOHEADER +{ + ULONG biSize; + LONG biWidth; + LONG biHeight; + USHORT biPlanes; + USHORT biBitCount; + ULONG biCompression; + ULONG biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + ULONG biClrUsed; + ULONG biClrImportant; +} BITMAPINFOHEADER, *PBITMAPINFOHEADER; + +VOID +NTAPI +InitializePalette( + VOID +); + +// +// Globals +// +extern USHORT AT_Initialization[]; +extern ULONG curr_x; +extern ULONG curr_y; +extern ULONG_PTR VgaRegisterBase; +extern ULONG_PTR VgaBase; +extern CHAR FontData[256 * 13]; diff --git a/reactos/drivers/base/bootvid/resource.h b/reactos/drivers/base/bootvid/resource.h deleted file mode 100644 index 76fce3d5d23..00000000000 --- a/reactos/drivers/base/bootvid/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -/* $Id$ */ - -/* Bitmaps */ -#define IDB_BOOTIMAGE 1 -#define IDB_BAR 8 - diff --git a/reactos/drivers/base/bootvid/vga.c b/reactos/drivers/base/bootvid/vga.c new file mode 100644 index 00000000000..398df46901f --- /dev/null +++ b/reactos/drivers/base/bootvid/vga.c @@ -0,0 +1,1274 @@ +#include "precomp.h" + +/* GLOBALS *******************************************************************/ + +ULONG ScrollRegion[4] = +{ + 0, + 0, + 640 - 1, + 480 - 1 +}; +UCHAR lMaskTable[8] = +{ + (1 << 8) - (1 << 0), + (1 << 7) - (1 << 0), + (1 << 6) - (1 << 0), + (1 << 5) - (1 << 0), + (1 << 4) - (1 << 0), + (1 << 3) - (1 << 0), + (1 << 2) - (1 << 0), + (1 << 1) - (1 << 0) +}; +UCHAR rMaskTable[8] = +{ + (1 << 7), + (1 << 7)+ (1 << 6), + (1 << 7)+ (1 << 6) + (1 << 5), + (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4), + (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3), + (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2), + (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2) + (1 << 1), + (1 << 7)+ (1 << 6) + (1 << 5) + (1 << 4) + (1 << 3) + (1 << 2) + (1 << 1) + + (1 << 0), +}; +UCHAR PixelMask[8] = +{ + (1 << 7), + (1 << 6), + (1 << 5), + (1 << 4), + (1 << 3), + (1 << 2), + (1 << 1), + (1 << 0), +}; +ULONG lookup[16] = +{ + 0x0000, + 0x0100, + 0x1000, + 0x1100, + 0x0001, + 0x0101, + 0x1001, + 0x1101, + 0x0010, + 0x0110, + 0x1010, + 0x1110, + 0x0011, + 0x0111, + 0x1011, + 0x1111, +}; + +ULONG TextColor = 0xF; +ULONG curr_x = 0; +ULONG curr_y = 0; +BOOLEAN NextLine = FALSE; +ULONG_PTR VgaRegisterBase = 0; +ULONG_PTR VgaBase = 0; + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +NTAPI +ReadWriteMode(UCHAR Mode) +{ + UCHAR Value; + + /* Switch to graphics mode register */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 5); + + /* Get the current register value, minus the current mode */ + Value = READ_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF) & 0xF4; + + /* Set the new mode */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, Mode | Value); +} + +VOID +NTAPI +__outpb(IN ULONG Port, + IN ULONG Value) +{ + /* Write to the VGA Register */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + Port, (UCHAR)Value); +} + +VOID +NTAPI +__outpw(IN ULONG Port, + IN ULONG Value) +{ + /* Write to the VGA Register */ + WRITE_PORT_USHORT((PUSHORT)(VgaRegisterBase + Port), (USHORT)Value); +} + +VOID +NTAPI +SetPixel(IN ULONG Left, + IN ULONG Top, + IN UCHAR Color) +{ + PUCHAR PixelPosition; + + /* Calculate the pixel position. */ + PixelPosition = (PUCHAR)VgaBase + (Left >> 3) + (Top * 80); + + /* Switch to mode 10 */ + ReadWriteMode(10); + + /* Clear the 4 planes (we're already in unchained mode here) */ + __outpw(0x3C4, 0xF02); + + /* Select the color don't care register */ + __outpw(0x3CE, 7); + + /* Select the bitmask register and write the mask */ + __outpw(0x3CE, (PixelMask[Left & 7] << 8) | 8); + + /* Read the current pixel value and add our color */ + WRITE_REGISTER_UCHAR(PixelPosition, + READ_REGISTER_UCHAR(PixelPosition) & Color); +} + +VOID +NTAPI +DisplayCharacter(CHAR Character, + ULONG Left, + ULONG Top, + ULONG TextColor, + ULONG BackTextColor) +{ + PUCHAR FontChar; + ULONG i, j, XOffset; + + /* Get the font line for this character */ + FontChar = &FontData[Character * 13 - Top]; + + /* Loop each pixel height */ + i = 13; + do + { + /* Loop each pixel width */ + j = 128; + XOffset = Left; + do + { + /* Check if we should draw this pixel */ + if (FontChar[Top] & (UCHAR)j) + { + /* We do, use the given Text Color */ + SetPixel(XOffset, Top, (UCHAR)TextColor); + } + else if (BackTextColor < 16) + { + /* This is a background pixel. We're drawing it unless it's */ + /* transparent. */ + SetPixel(XOffset, Top, (UCHAR)BackTextColor); + } + + /* Increase X Offset */ + XOffset++; + } while (j >>= 1); + + /* Move to the next Y ordinate */ + Top++; + } while (--i); +} + +VOID +NTAPI +DisplayStringXY(PUCHAR String, + ULONG Left, + ULONG Top, + ULONG TextColor, + ULONG BackColor) +{ + /* Loop every character */ + while (*String) + { + /* Display a character */ + DisplayCharacter(*String, Left, Top, TextColor, BackColor); + + /* Move to next character and next position */ + String++; + Left += 8; + } +} + +VOID +NTAPI +SetPaletteEntryRGB(IN ULONG Id, + IN ULONG Rgb) +{ + PCHAR Colors = (PCHAR)&Rgb; + + /* Set the palette index */ + __outpb(0x3C8, (UCHAR)Id); + + /* Set RGB colors */ + __outpb(0x3C9, Colors[2] >> 2); + __outpb(0x3C9, Colors[1] >> 2); + __outpb(0x3C9, Colors[0] >> 2); +} + +VOID +NTAPI +InitPaletteWithTable(IN PULONG Table, + IN ULONG Count) +{ + ULONG i; + PULONG Entry = Table; + + /* Loop every entry */ + for (i = 0; i < Count; i++, Entry++) + { + /* Set the entry */ + SetPaletteEntryRGB(i, *Entry); + } +} + +VOID +NTAPI +SetPaletteEntry(IN ULONG Id, + IN ULONG PaletteEntry) +{ + /* Set the palette index */ + __outpb(0x3C8, (UCHAR)Id); + + /* Set RGB colors */ + __outpb(0x3C9, PaletteEntry & 0xFF); + __outpb(0x3C9, (PaletteEntry >>= 8) & 0xFF); + __outpb(0x3C9, (PaletteEntry >> 8) & 0xFF); +} + +VOID +NTAPI +InitializePalette(VOID) +{ + ULONG PaletteEntry[16] = {0, + 0x20, + 0x2000, + 0x2020, + 0x200000, + 0x200020, + 0x202000, + 0x202020, + 0x303030, + 0x3F, + 0x3F00, + 0x3F3F, + 0x3F0000, + 0x3F003F, + 0x3F3F00, + 0x3F3F3F}; + ULONG i; + + /* Loop all the entries and set their palettes */ + for (i = 0; i < 16; i++) SetPaletteEntry(i, PaletteEntry[i]); +} + +VOID +NTAPI +VgaScroll(ULONG Scroll) +{ + ULONG Top; + ULONG SourceOffset, DestOffset; + ULONG Offset; + ULONG i, j; + + /* Set memory positions of the scroll */ + SourceOffset = VgaBase + (ScrollRegion[1] * 80) + (ScrollRegion[0] >> 3); + DestOffset = SourceOffset + (Scroll * 80); + + /* Clear the 4 planes */ + __outpw(0x3C4, 0xF02); + + /* Set the bitmask to 0xFF for all 4 planes */ + __outpw(0x3CE, 0xFF08); + + /* Set Mode 1 */ + ReadWriteMode(1); + + /* Save top and check if it's above the bottom */ + Top = ScrollRegion[1]; + if (Top > ScrollRegion[3]) return; + + /* Start loop */ + do + { + /* Set number of bytes to loop and start offset */ + Offset = ScrollRegion[0] >> 3; + j = SourceOffset; + + /* Check if this is part of the scroll region */ + if (Offset <= (ScrollRegion[2] >> 3)) + { + /* Update position */ + i = DestOffset - SourceOffset; + + /* Loop the X axis */ + do + { + /* Write value in the new position so that we can do the scroll */ + WRITE_REGISTER_UCHAR((PUCHAR)j, + READ_REGISTER_UCHAR((PUCHAR)j + i)); + + /* Move to the next memory location to write to */ + j++; + + /* Move to the next byte in the region */ + Offset++; + + /* Make sure we don't go past the scroll region */ + } while (Offset <= (ScrollRegion[2] >> 3)); + } + + /* Move to the next line */ + SourceOffset += 80; + DestOffset += 80; + + /* Increase top */ + Top++; + + /* Make sure we don't go past the scroll region */ + } while (Top <= ScrollRegion[3]); +} + +VOID +NTAPI +PreserveRow(IN ULONG CurrentTop, + IN ULONG TopDelta, + IN BOOLEAN Direction) +{ + PUCHAR Position1, Position2; + ULONG Count; + + /* Clear the 4 planes */ + __outpw(0x3C4, 0xF02); + + /* Set the bitmask to 0xFF for all 4 planes */ + __outpw(0x3CE, 0xFF08); + + /* Set Mode 1 */ + ReadWriteMode(1); + + /* Check which way we're preserving */ + if (Direction) + { + /* Calculate the position in memory for the row */ + Position1 = (PUCHAR)VgaBase + CurrentTop * 80; + Position2 = (PUCHAR)VgaBase + 0x9600; + } + else + { + /* Calculate the position in memory for the row */ + Position1 = (PUCHAR)VgaBase + 0x9600; + Position2 = (PUCHAR)VgaBase + CurrentTop * 80; + } + + /* Set the count and make sure it's above 0 */ + Count = TopDelta * 80; + if (Count) + { + /* Loop every pixel */ + do + { + /* Write the data back on the other position */ + WRITE_REGISTER_UCHAR(Position1, READ_REGISTER_UCHAR(Position2)); + + /* Increase both positions */ + Position2++; + Position1++; + } while (--Count); + } +} + +VOID +NTAPI +BitBlt(IN ULONG Left, + IN ULONG Top, + IN ULONG Width, + IN ULONG Height, + IN PUCHAR Buffer, + IN ULONG BitsPerPixel, + IN ULONG Delta) +{ + ULONG LeftAnd, LeftShifted, LeftPlusOne, LeftPos; + ULONG lMask, rMask; + UCHAR NotlMask; + ULONG Distance; + ULONG DistanceMinusLeftBpp; + ULONG SomeYesNoFlag, SomeYesNoFlag2; + PUCHAR PixelPosition, m; + PUCHAR i, k; + ULONG j; + ULONG x; + ULONG Plane; + UCHAR LeftArray[84]; + PUCHAR CurrentLeft; + PUCHAR l; + ULONG LoopCount; + UCHAR pMask, PlaneShift; + BOOLEAN Odd; + UCHAR Value; + + /* Check if the buffer isn't 4bpp */ + if (BitsPerPixel != 4) + { + /* FIXME: TODO */ + DbgPrint("Unhandled BitBlt\n" + "%lxx%lx @ (%lx,%lx)\n" + "Bits Per Pixel %lx\n" + "Buffer: %p. Delta: %lx\n", + Width, + Height, + Left, + Top, + BitsPerPixel, + Buffer, + Delta); + return; + } + + /* Get the masks and other values */ + LeftAnd = Left & 0x7; + lMask = lMaskTable[LeftAnd]; + Distance = Width + Left; + rMask = rMaskTable[(Distance - 1) & 0x7]; + Left >>= 3; + + /* Set some values */ + SomeYesNoFlag = FALSE; + SomeYesNoFlag2 = FALSE; + Distance = (Distance - 1) >> 3; + DistanceMinusLeftBpp = Distance - Left; + + /* Check if the distance is equal to the left position and add the masks */ + if (Left == Distance) lMask += rMask; + + /* Check if there's no distance offset */ + if (DistanceMinusLeftBpp) + { + /* Set the first flag on */ + SomeYesNoFlag = TRUE; + + /* Decrease offset and check if we still have one */ + if (--DistanceMinusLeftBpp) + { + /* Still have a distance offset */ + SomeYesNoFlag2 = TRUE; + } + } + + /* Calculate initial pixel position */ + PixelPosition = (PUCHAR)VgaBase + (Top * 80) + Left; + + /* Set loop buffer variable */ + i = Buffer; + + /* Switch to mode 0 */ + ReadWriteMode(0); + + /* Leave now if the height is 0 */ + if (Height <= 0) return; + + /* Set more weird values */ + CurrentLeft = &LeftArray[Left]; + NotlMask = ~(UCHAR)lMask; + LeftPlusOne = Left + 1; + LeftShifted = (lMask << 8) | 8; + j = Height; + + /* Start the height loop */ + do + { + /* Start the plane loop */ + Plane = 0; + do + { + /* Clear the current value */ + *CurrentLeft = 0; + LoopCount = 0; + + /* Set the buffer loop variable for this loop */ + k = i; + + /* Calculate plane shift and pixel mask */ + PlaneShift = 1 << Plane; + pMask = PixelMask[LeftAnd]; + + /* Check if we have a width */ + if (Width > 0) + { + /* Loop it */ + l = CurrentLeft; + x = Width; + do + { + /* Check if we're odd and increase the loop count */ + Odd = LoopCount & 1 ? TRUE : FALSE; + LoopCount++; + if (Odd) + { + /* Check for the plane shift */ + if (*k & PlaneShift) + { + /* Write the pixel mask */ + *l |= pMask; + } + + /* Increase buffer position */ + k++; + } + else + { + /* Check for plane shift */ + if ((*k >> 4) & PlaneShift) + { + /* Write the pixel mask */ + *l |= pMask; + } + } + + /* Shift the pixel mask */ + pMask >>= 1; + if (!pMask) + { + /* Move to the next current left position and clear it */ + l++; + *l = 0; + + /* Set the pixel mask to 0x80 */ + pMask = 0x80; + } + } while (--x); + } + + /* Set the plane value */ + __outpw(0x3C4, (1 << (Plane + 8) | 2)); + + /* Select the bitmask register and write the mask */ + __outpw(0x3CE, (USHORT)LeftShifted); + + /* Read the current Pixel value */ + Value = READ_REGISTER_UCHAR(PixelPosition); + + /* Add our mask */ + Value = (Value & NotlMask) | *CurrentLeft; + + /* Set current left for the loop, and write new pixel value */ + LeftPos = LeftPlusOne; + WRITE_REGISTER_UCHAR(PixelPosition, Value); + + /* Set loop pixel position and check if we should loop */ + m = PixelPosition + 1; + if (SomeYesNoFlag2) + { + /* Set the bitmask to 0xFF for all 4 planes */ + __outpw(0x3CE, 0xFF08); + + /* Check if we have any distance left */ + if (DistanceMinusLeftBpp > 0) + { + /* Start looping it */ + x = DistanceMinusLeftBpp; + do + { + /* Write the value */ + WRITE_REGISTER_UCHAR(m, LeftArray[LeftPos]); + + /* Go to the next position */ + m++; + LeftPos++; + } while (--x); + } + } + + /* Check if the first flag is on */ + if (SomeYesNoFlag) + { + /* Set the mask value */ + __outpw(0x3CE, (rMask << 8) | 8); + + /* Read the current Pixel value */ + Value = READ_REGISTER_UCHAR(m); + + /* Add our mask */ + Value = (Value & ~(UCHAR)rMask) | LeftArray[LeftPos]; + + /* Set current left for the loop, and write new pixel value */ + WRITE_REGISTER_UCHAR(m, Value); + } + } while (++Plane < 4); + + /* Update pixel position, buffer and height */ + PixelPosition += 80; + i += Delta; + } while (--j); +} + +VOID +NTAPI +RleBitBlt(IN ULONG Left, + IN ULONG Top, + IN ULONG Width, + IN ULONG Height, + IN PUCHAR Buffer) +{ + ULONG YDelta; + ULONG x; + ULONG RleValue, NewRleValue; + ULONG Color, Color2; + ULONG i, j; + ULONG Code; + + /* Set Y height and current X value and start loop */ + YDelta = Top + Height - 1; + x = Left; + for (;;) + { + /* Get the current value and advance in the buffer */ + RleValue = *Buffer; + Buffer++; + if (RleValue) + { + /* Check if we've gone past the edge */ + if ((x + RleValue) > (Width + Left)) + { + /* Fixeup the pixel value */ + RleValue = Left - x + Width; + } + + /* Get the new value */ + NewRleValue = *Buffer; + + /* Get the two colors */ + Color = NewRleValue >> 4; + Color2 = NewRleValue & 0xF; + + /* Increase buffer positition */ + Buffer++; + + /* Check if we need to do a fill */ + if (Color == Color2) + { + /* Do a fill and continue the loop */ + RleValue += x; + VidSolidColorFill(x, YDelta, RleValue - 1, YDelta, (UCHAR)Color); + x = RleValue; + continue; + } + + /* Check if the pixel value is 1 or below */ + if (RleValue > 1) + { + /* Set loop variables */ + i = (RleValue - 2) / 2 + 1; + do + { + /* Set the pixels */ + SetPixel(x, YDelta, (UCHAR)Color); + x++; + SetPixel(x, YDelta, (UCHAR)Color2); + x++; + + /* Decrease pixel value */ + RleValue -= 2; + } while (--i); + } + + /* Check if there is any value at all */ + if (RleValue) + { + /* Set the pixel and increase posititon */ + SetPixel(x, YDelta, (UCHAR)Color); + x++; + } + + /* Start over */ + continue; + } + + /* Get the current pixel value */ + RleValue = *Buffer; + Code = RleValue; + switch (Code) + { + /* Case 0 */ + case 0: + + /* Set new x value, decrease distance and restart */ + x = Left; + YDelta--; + Buffer++; + continue; + + /* Case 1 */ + case 1: + + /* Done */ + return; + + /* Case 2 */ + case 2: + + /* Set new x value, decrease distance and restart */ + Buffer++; + x += *Buffer; + Buffer++; + YDelta -= *Buffer; + Buffer++; + continue; + + /* Other values */ + default: + + Buffer++; + break; + } + + /* Check if we've gone past the edge */ + if ((x + RleValue) > (Width + Left)) + { + /* Set fixed up loop count */ + i = RleValue - Left - Width + x; + + /* Fixup pixel value */ + RleValue -= i; + } + else + { + /* Clear loop count */ + i = 0; + } + + /* Check the value now */ + if (RleValue > 1) + { + /* Set loop variables */ + j = (RleValue - 2) / 2 + 1; + do + { + /* Get the new value */ + NewRleValue = *Buffer; + + /* Get the two colors */ + Color = NewRleValue >> 4; + Color2 = NewRleValue & 0xF; + + /* Increase buffer position */ + Buffer++; + + /* Set the pixels */ + SetPixel(x, YDelta, (UCHAR)Color); + x++; + SetPixel(x, YDelta, (UCHAR)Color2); + x++; + + /* Decrease pixel value */ + RleValue -= 2; + } while (--j); + } + + /* Check if there is any value at all */ + if (RleValue) + { + /* Set the pixel and increase position */ + Color = *Buffer >> 4; + Buffer++; + SetPixel(x, YDelta, (UCHAR)Color); + x++; + i--; + } + + /* Check loop count now */ + if ((LONG)i > 0) + { + /* Decrease it */ + i--; + + /* Set new position */ + Buffer = Buffer + (i / 2) + 1; + } + + /* Check if we need to increase the buffer */ + if ((ULONG_PTR)Buffer & 1) Buffer++; + } +} + +/* PUBLIC FUNCTIONS **********************************************************/ + +/* + * @implemented + */ +ULONG +NTAPI +VidSetTextColor(ULONG Color) +{ + ULONG OldColor; + + /* Save the old color and set the new one */ + OldColor = TextColor; + TextColor = Color; + return OldColor; +} + +/* + * @implemented + */ +VOID +NTAPI +VidDisplayStringXY(PUCHAR String, + ULONG Left, + ULONG Top, + BOOLEAN Transparent) +{ + ULONG BackColor; + + /* If the caller wanted transparent, then send the special value (16), else */ + /* use our default and call the helper routine. */ + BackColor = (Transparent) ? 16 : 14; + DisplayStringXY(String, Left, Top, 12, BackColor); +} + +/* + * @implemented + */ +VOID +NTAPI +VidSetScrollRegion(ULONG x1, + ULONG y1, + ULONG x2, + ULONG y2) +{ + /* Assert alignment */ + ASSERT((x1 & 0x7) == 0); + ASSERT((x2 & 0x7) == 0); + + /* Set Scroll Region */ + ScrollRegion[0] = x1; + ScrollRegion[1] = y1; + ScrollRegion[2] = x2; + ScrollRegion[3] = y2; + + /* Set current X and Y */ + curr_x = x1; + curr_y = y1; +} + +/* + * @implemented + */ +VOID +NTAPI +VidCleanUp(VOID) +{ + /* Select bit mask register */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CE, 8); + + /* Clear it */ + WRITE_PORT_UCHAR((PUCHAR)VgaRegisterBase + 0x3CF, 255); +} + +/* + * @implemented + */ +VOID +NTAPI +VidBufferToScreenBlt(IN PUCHAR Buffer, + IN ULONG Left, + IN ULONG Top, + IN ULONG Width, + IN ULONG Height, + IN ULONG Delta) +{ + /* Make sure we have a width and height */ + if (!(Width) || !(Height)) return; + + /* Call the helper function */ + BitBlt(Left, Top, Width, Height, Buffer, 4, Delta); +} + +/* + * @implemented + */ +VOID +NTAPI +VidDisplayString(PUCHAR String) +{ + ULONG TopDelta = 14; + + /* Start looping the string */ + while (*String) + { + /* Treat new-line separately */ + if (*String == '\n') + { + /* Modify Y position */ + curr_y += TopDelta; + if (curr_y >= ScrollRegion[3]) + { + /* Scroll the view */ + VgaScroll(TopDelta); + curr_y -= TopDelta; + + /* Preserve row */ + PreserveRow(curr_y, TopDelta, TRUE); + } + + /* Update current X */ + curr_x = ScrollRegion[0]; + + /* Preseve the current row */ + PreserveRow(curr_y, TopDelta, FALSE); + } + else if (*String == '\r') + { + /* Update current X */ + curr_x = ScrollRegion[0]; + + /* Check if we're being followed by a new line */ + if (String[1] != '\n') NextLine = TRUE; + } + else + { + /* Check if we had a \n\r last time */ + if (NextLine) + { + /* We did, preserve the current row */ + PreserveRow(curr_y, TopDelta, TRUE); + NextLine = FALSE; + } + + /* Display this character */ + DisplayCharacter(*String, curr_x, curr_y, TextColor, 16); + curr_x += 8; + + /* Check if we should scroll */ + if (curr_x > ScrollRegion[2]) + { + /* Update Y position and check if we should scroll it */ + curr_y += TopDelta; + if (curr_y > ScrollRegion[3]) + { + /* Do the scroll */ + VgaScroll(TopDelta); + curr_y -= TopDelta; + + /* Save the row */ + PreserveRow(curr_y, TopDelta, TRUE); + } + + /* Update X */ + curr_x = ScrollRegion[0]; + } + } + + /* Get the next character */ + String++; + } +} + +/* + * @implemented + */ +VOID +NTAPI +VidBitBlt(PUCHAR Buffer, + ULONG Left, + ULONG Top) +{ + PBITMAPINFOHEADER BitmapInfoHeader; + LONG Delta; + PUCHAR BitmapOffset; + + /* Get the Bitmap Header */ + BitmapInfoHeader = (PBITMAPINFOHEADER)Buffer; + + /* Initialize the palette */ + InitPaletteWithTable((PULONG)(Buffer + BitmapInfoHeader->biSize), + (BitmapInfoHeader->biClrUsed) ? + BitmapInfoHeader->biClrUsed : 16); + + /* Make sure we can support this bitmap */ + ASSERT((BitmapInfoHeader->biBitCount * BitmapInfoHeader->biPlanes) <= 4); + + /* Calculate the delta and align it on 32-bytes, then calculate the actual */ + /* start of the bitmap data. */ + Delta = (BitmapInfoHeader->biBitCount * BitmapInfoHeader->biWidth) + 31; + Delta >>= 3; + Delta &= ~3; + BitmapOffset = Buffer + sizeof(BITMAPINFOHEADER) + 16 * sizeof(ULONG); + + /* Check the compression of the bitmap */ + if (BitmapInfoHeader->biCompression == 2) + { + /* Make sure we have a width and a height */ + if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight)) + { + /* We can use RLE Bit Blt */ + RleBitBlt(Left, + Top, + BitmapInfoHeader->biWidth, + BitmapInfoHeader->biHeight, + BitmapOffset); + } + } + else + { + /* Check if the height is negative */ + if (BitmapInfoHeader->biHeight < 0) + { + /* Make it positive in the header */ + BitmapInfoHeader->biHeight *= -1; + } + else + { + /* Update buffer offset */ + BitmapOffset += ((BitmapInfoHeader->biHeight -1) * Delta); + Delta *= -1; + } + + /* Make sure we have a width and a height */ + if ((BitmapInfoHeader->biWidth) && (BitmapInfoHeader->biHeight)) + { + /* Do the BitBlt */ + BitBlt(Left, + Top, + BitmapInfoHeader->biWidth, + BitmapInfoHeader->biHeight, + BitmapOffset, + BitmapInfoHeader->biBitCount, + Delta); + } + } +} + +/* + * @implemented + */ +VOID +NTAPI +VidScreenToBufferBlt(PUCHAR Buffer, + ULONG Left, + ULONG Top, + ULONG Width, + ULONG Height, + ULONG Delta) +{ + ULONG Plane; + ULONG XDistance; + ULONG LeftDelta, RightDelta; + ULONG PixelOffset; + PUCHAR PixelPosition; + PUCHAR k, i; + PULONG m; + UCHAR Value, Value2; + UCHAR a; + ULONG b; + ULONG x, y; + + /* Calculate total distance to copy on X */ + XDistance = Left + Width - 1; + + /* Start at plane 0 */ + Plane = 0; + + /* Calculate the 8-byte left and right deltas */ + LeftDelta = Left & 7; + RightDelta = 8 - LeftDelta; + + /* Clear the destination buffer */ + RtlZeroMemory(Buffer, Delta * Height); + + /* Calculate the pixel offset and convert the X distance into byte form */ + PixelOffset = Top * 80 + (Left >> 3); + XDistance >>= 3; + + /* Loop the 4 planes */ + do + { + /* Set the current pixel position and reset buffer loop variable */ + PixelPosition = (PUCHAR)VgaBase + PixelOffset; + i = Buffer; + + /* Set Mode 0 */ + ReadWriteMode(0); + + /* Set the current plane */ + __outpw(0x3CE, (Plane << 8) | 4); + + /* Make sure we have a height */ + if (Height > 0) + { + /* Start the outer Y loop */ + y = Height; + do + { + /* Read the current value */ + m = (PULONG)i; + Value = READ_REGISTER_UCHAR(PixelPosition); + + /* Set Pixel Position loop variable */ + k = PixelPosition + 1; + + /* Check if we're still within bounds */ + if (Left <= XDistance) + { + /* Start X Inner loop */ + x = (XDistance - Left) + 1; + do + { + /* Read the current value */ + Value2 = READ_REGISTER_UCHAR(k); + + /* Increase pixel position */ + k++; + + /* Do the blt */ + a = Value2 >> (UCHAR)RightDelta; + a |= Value << (UCHAR)LeftDelta; + b = lookup[a & 0xF]; + a >>= 4; + b <<= 16; + b |= lookup[a]; + + /* Save new value to buffer */ + *m |= (b << Plane); + + /* Move to next destination location */ + m++; + + /* Write new value */ + Value = Value2; + } while (--x); + } + + /* Update pixel position */ + PixelPosition += 80; + i += Delta; + } while (--y); + } + } while (++Plane < 4); +} + +/* + * @implemented + */ +VOID +NTAPI +VidSolidColorFill(IN ULONG Left, + IN ULONG Top, + IN ULONG Right, + IN ULONG Bottom, + IN UCHAR Color) +{ + ULONG rMask, lMask; + ULONG LeftOffset, RightOffset, Distance; + PUCHAR Offset; + ULONG i, j; + + /* Get the left and right masks, shifts, and delta */ + LeftOffset = Left >> 3; + lMask = (lMaskTable[Left & 0x7] << 8) | 8; + RightOffset = Right >> 3; + rMask = (rMaskTable[Right & 0x7] << 8) | 8; + Distance = RightOffset - LeftOffset; + + /* If there is no distance, then combine the right and left masks */ + if (!Distance) lMask &= rMask; + + /* Switch to mode 10 */ + ReadWriteMode(10); + + /* Clear the 4 planes (we're already in unchained mode here) */ + __outpw(0x3C4, 0xF02); + + /* Select the color don't care register */ + __outpw(0x3CE, 7); + + /* Calculate pixel position for the read */ + Offset = VgaBase + (Top * 80) + (PUCHAR)LeftOffset; + + /* Select the bitmask register and write the mask */ + __outpw(0x3CE, (USHORT)lMask); + + /* Check if the top coord is below the bottom one */ + if (Top <= Bottom) + { + /* Start looping each line */ + i = (Bottom - Top) + 1; + do + { + /* Read the previous value and add our color */ + WRITE_REGISTER_UCHAR(Offset, READ_REGISTER_UCHAR(Offset) & Color); + + /* Move to the next line */ + Offset += 80; + } while (--i); + } + + /* Check if we have a delta */ + if (Distance) + { + /* Calculate new pixel position */ + Offset = VgaBase + (Top * 80) + (PUCHAR)RightOffset; + Distance--; + + /* Select the bitmask register and write the mask */ + __outpw(0x3CE, (USHORT)rMask); + + /* Check if the top coord is below the bottom one */ + if (Top <= Bottom) + { + /* Start looping each line */ + i = (Bottom - Top) + 1; + do + { + /* Read the previous value and add our color */ + WRITE_REGISTER_UCHAR(Offset, + READ_REGISTER_UCHAR(Offset) & Color); + + /* Move to the next line */ + Offset += 80; + } while (--i); + } + + /* Check if we still have a delta */ + if (Distance) + { + /* Calculate new pixel position */ + Offset = VgaBase + (Top * 80) + (PUCHAR)(LeftOffset + 1); + + /* Set the bitmask to 0xFF for all 4 planes */ + __outpw(0x3CE, 0xFF08); + + /* Check if the top coord is below the bottom one */ + if (Top <= Bottom) + { + /* Start looping each line */ + i = (Bottom - Top) + 1; + do + { + /* Loop the shift delta */ + if (Distance > 0) + { + for (j = Distance; j; Offset++, j--) + { + /* Write the color */ + WRITE_REGISTER_UCHAR(Offset, Color); + } + } + + /* Update position in memory */ + Offset += (80 - Distance); + } while (--i); + } + } + } +} + diff --git a/reactos/drivers/base/bootvid/vid.c b/reactos/drivers/base/bootvid/vid.c deleted file mode 100644 index 22ea29309b1..00000000000 --- a/reactos/drivers/base/bootvid/vid.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * ReactOS Boot video driver - * - * Copyright (C) 2005 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. - */ - -/* INCLUDES ******************************************************************/ - -#include "bootvid.h" -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -static PVID_FUNCTION_TABLE VidTable; -extern VID_FUNCTION_TABLE VidVgaTable; -extern VID_FUNCTION_TABLE VidVgaTextTable; -extern VID_FUNCTION_TABLE VidXboxTable; - -/* FUNCTIONS *****************************************************************/ - -BOOLEAN NTAPI -VidInitialize( - IN BOOLEAN SetMode) -{ - ULONG PciId; - - /* - * Check for Xbox by identifying device at PCI 0:0:0, if it's - * 0x10de/0x02a5 then we're running on an Xbox. - */ - CHECKPOINT; - WRITE_PORT_ULONG((PULONG)0xcf8, 0x80000000); - PciId = READ_PORT_ULONG((PULONG)0xcfc); - if (0x02a510de == PciId) - VidTable = &VidXboxTable; - else if (SetMode) - VidTable = &VidVgaTable; - else - VidTable = &VidVgaTextTable; - return VidTable->Initialize(SetMode); -} - -VOID STDCALL -VidResetDisplay(VOID) -{ - VidTable->ResetDisplay(); -} - -VOID NTAPI -VidCleanUp(VOID) -{ - VidTable->CleanUp(); -} - -VOID NTAPI -VidBufferToScreenBlt( - IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN ULONG Delta) -{ - VidTable->BufferToScreenBlt(Buffer, Left, Top, Width, Height, Delta); -} - -VOID NTAPI -VidScreenToBufferBlt( - OUT PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN ULONG Delta) -{ - VidTable->ScreenToBufferBlt(Buffer, Left, Top, Width, Height, Delta); -} - -VOID NTAPI -VidBitBlt( - IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top) -{ - VidTable->BitBlt(Buffer, Left, Top); -} - -VOID NTAPI -VidSolidColorFill( - IN ULONG Left, - IN ULONG Top, - IN ULONG Right, - IN ULONG Bottom, - IN ULONG Color) -{ - VidTable->SolidColorFill(Left, Top, Right, Bottom, Color); -} - -VOID NTAPI -VidDisplayString( - IN PCSTR String) -{ - VidTable->DisplayString(String); -} diff --git a/reactos/drivers/base/bootvid/vid_vga.c b/reactos/drivers/base/bootvid/vid_vga.c deleted file mode 100644 index 1bac1c53b47..00000000000 --- a/reactos/drivers/base/bootvid/vid_vga.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * ReactOS Boot video driver - * - * Copyright (C) 2005 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. - */ - -/* INCLUDES ******************************************************************/ - -#include "bootvid.h" -#define NDEBUG -#include - -/* TYPES AND DEFINITIONS *****************************************************/ - -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 - -/* 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 VidpMode12Regs = -{ - /* 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 -}; - -static const RGBQUAD DefaultPalette[] = -{ - {0, 0, 0}, - {0, 0, 0x80}, - {0, 0x80, 0}, - {0, 0x80, 0x80}, - {0x80, 0, 0}, - {0x80, 0, 0x80}, - {0x80, 0x80, 0}, - {0x80, 0x80, 0x80}, - {0xC0, 0xC0, 0xC0}, - {0, 0, 0xFF}, - {0, 0xFF, 0}, - {0, 0xFF, 0xFF}, - {0xFF, 0, 0}, - {0xFF, 0, 0xFF}, - {0xFF, 0xFF, 0}, - {0xFF, 0xFF, 0xFF} -}; - -static BOOLEAN VidpInitialized = FALSE; -static PUCHAR VidpMemory; -static CHAR VidpMaskBit[640]; -static ULONG VidpCurrentX; -static ULONG VidpCurrentY; - -/* FUNCTIONS *****************************************************************/ - -static VOID FASTCALL -VidpSetRegisters(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]); - } - - /* Set the PEL mask. */ - WRITE_PORT_UCHAR(PELMASK, 0xff); -} - -static BOOLEAN NTAPI -VidVgaInitialize( - IN BOOLEAN SetMode) -{ - ULONG Index; - PHYSICAL_ADDRESS PhysicalAddress; - - if (!VidpInitialized) - { - PhysicalAddress.QuadPart = 0xA0000; - VidpMemory = MmMapIoSpace(PhysicalAddress, 0x10000, MmNonCached); - if (VidpMemory == NULL) - return FALSE; - - for (Index = 0; Index < 80; Index++) - { - VidpMaskBit[Index * 8 + 0] = 128; - VidpMaskBit[Index * 8 + 1] = 64; - VidpMaskBit[Index * 8 + 2] = 32; - VidpMaskBit[Index * 8 + 3] = 16; - VidpMaskBit[Index * 8 + 4] = 8; - VidpMaskBit[Index * 8 + 5] = 4; - VidpMaskBit[Index * 8 + 6] = 2; - VidpMaskBit[Index * 8 + 7] = 1; - } - - VidpInitialized = TRUE; - } - - if (SetMode) - { - VidpSetRegisters(&VidpMode12Regs); - VidpCurrentX = VidpCurrentY = 0; - - /* Disable screen and enable palette access. */ - READ_PORT_UCHAR(STATUS); - WRITE_PORT_UCHAR(ATTRIB, 0x00); - - for (Index = 0; Index < sizeof(DefaultPalette) / sizeof(RGBQUAD); Index++) - { - WRITE_PORT_UCHAR(PELINDEX, Index); - WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index].rgbRed >> 2); - WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index].rgbGreen >> 2); - WRITE_PORT_UCHAR(PELDATA, DefaultPalette[Index].rgbBlue >> 2); - } - - /* Enable screen and disable palette access. */ - READ_PORT_UCHAR(STATUS); - WRITE_PORT_UCHAR(ATTRIB, 0x20); - } - - return TRUE; -} - -static VOID STDCALL -VidVgaResetDisplay(VOID) -{ - VidVgaInitialize(TRUE); -} - -static VOID NTAPI -VidVgaCleanUp(VOID) -{ - if (VidpInitialized) - { - MmUnmapIoSpace(VidpMemory, 0x10000); - VidpInitialized = FALSE; - } -} - -static VOID NTAPI -VidVgaBufferToScreenBlt( - IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN ULONG Delta) -{ - ULONG x, y; - PUCHAR BufferPtr; - ULONG VidOffset; - - for (x = Left; x < Left + Width; x++) - { - WRITE_PORT_UCHAR(GRAPHICS, 0x08); - WRITE_PORT_UCHAR(GRAPHICSDATA, VidpMaskBit[x]); - - BufferPtr = Buffer; - VidOffset = (x >> 3) + (Top * 80); - - if (((x - Left) % 2) == 0) - { - for (y = Top; y < Top + Height; y++) - { - READ_REGISTER_UCHAR(VidpMemory + VidOffset); - WRITE_REGISTER_UCHAR(VidpMemory + VidOffset, *BufferPtr >> 4); - VidOffset += 80; - BufferPtr += Delta; - } - } - else - { - for (y = Top; y < Top + Height; y++) - { - READ_REGISTER_UCHAR(VidpMemory + VidOffset); - WRITE_REGISTER_UCHAR(VidpMemory + VidOffset, *BufferPtr & 0xf); - VidOffset += 80; - BufferPtr += Delta; - } - - Buffer++; - } - } -} - -static VOID NTAPI -VidVgaScreenToBufferBlt( - OUT PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN LONG Delta) -{ - UCHAR Plane; - UCHAR b; - ULONG x, y; - - /* Reset the destination. */ - RtlZeroMemory(Buffer, (Delta > 0 ? Delta : -Delta) * Height); - - for (Plane = 0; Plane < 4; Plane++) - { - WRITE_PORT_UCHAR(GRAPHICS, 0x04); - WRITE_PORT_UCHAR(GRAPHICSDATA, Plane); - - for (y = Top; y < Top + Height; y++) - { - for (x = Left; x < Left + Width; x++) - { - b = READ_REGISTER_UCHAR(VidpMemory + (y * 80 + (x >> 3))); - b >>= 7 - (x & 7); - b &= 1; - b <<= Plane + ((~(x - Left) & 1) << 2); - Buffer[(y - Top) * Delta + ((x - Left) >> 1)] |= b; - } - } - } -} - -static VOID NTAPI -VidVgaBitBlt( - IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top) -{ - PBITMAPINFOHEADER BitmapInfoHeader; - LPRGBQUAD Palette; - ULONG bfOffBits; - UCHAR ClrUsed; - ULONG Index; - LONG Delta; - - BitmapInfoHeader = (PBITMAPINFOHEADER)Buffer; - Palette = (LPRGBQUAD)(Buffer + BitmapInfoHeader->biSize); - - if (BitmapInfoHeader->biClrUsed) - ClrUsed = BitmapInfoHeader->biClrUsed; - else - ClrUsed = 1 << BitmapInfoHeader->biBitCount; - - bfOffBits = BitmapInfoHeader->biSize + ClrUsed * sizeof(RGBQUAD); - - /* Disable screen and enable palette access. */ - READ_PORT_UCHAR(STATUS); - WRITE_PORT_UCHAR(ATTRIB, 0x00); - - for (Index = 0; Index < ClrUsed; Index++) - { - WRITE_PORT_UCHAR(PELINDEX, Index); - WRITE_PORT_UCHAR(PELDATA, Palette[Index].rgbRed >> 2); - WRITE_PORT_UCHAR(PELDATA, Palette[Index].rgbGreen >> 2); - WRITE_PORT_UCHAR(PELDATA, Palette[Index].rgbBlue >> 2); - } - - /* Enable screen and disable palette access. */ - READ_PORT_UCHAR(STATUS); - WRITE_PORT_UCHAR(ATTRIB, 0x20); - - if (BitmapInfoHeader->biCompression == 2) - { - PUCHAR OutputBuffer; - ULONG InputPos, OutputPos; - ULONG x, y; - UCHAR b; - ULONG Length; - - Delta = (BitmapInfoHeader->biWidth + 1) >> 1; - OutputBuffer = ExAllocatePool(NonPagedPool, Delta * BitmapInfoHeader->biHeight); - RtlZeroMemory(OutputBuffer, Delta * BitmapInfoHeader->biHeight); - OutputPos = InputPos = 0; - Buffer += bfOffBits; - - while (InputPos < BitmapInfoHeader->biSizeImage && - OutputPos < (ULONG)Delta * BitmapInfoHeader->biHeight * 2) - { - Length = Buffer[InputPos++]; - if (Length > 0) - { - /* Encoded mode */ - b = Buffer[InputPos++]; - if (OutputPos % 2) - { - OutputBuffer[OutputPos >> 1] |= b & 0xf; - b = (b >> 4) | (b << 4); - Length--; - OutputPos++; - } - - memset(OutputBuffer + (OutputPos >> 1), b, Length / 2); - OutputPos += Length; - - if (Length & 1) - { - OutputBuffer[OutputPos >> 1] |= b & 0xf; - OutputPos++; - } - } - else - { - /* Absolute mode */ - b = Buffer[InputPos++]; - if (b == 0) - { - /* End of line */ - if (OutputPos % Delta) - OutputPos = ((OutputPos / Delta) + 1) * Delta; - } - else if (b == 1) - { - /* End of image */ - break; - } - else if (b == 2) - { - x = Buffer[InputPos++]; - y = Buffer[InputPos++]; - OutputPos = ((OutputPos / Delta) + y) * Delta + - ((OutputPos % Delta) + x); - } - else - { - Length = b; - if (Length) - { - if (OutputPos % 2) - { - ASSERT(FALSE); - } - - for (Index = 0; Index < (Length / 2); Index++) - { - b = Buffer[InputPos++]; - OutputBuffer[OutputPos >> 1] = b; - OutputPos += 2; - } - if (Length & 1) - { - b = Buffer[InputPos++]; - OutputBuffer[OutputPos >> 1] |= b >> 4; - OutputPos++; - } - } - - /* Word align */ - InputPos += (InputPos & 1); - } - } - } - - VidBufferToScreenBlt(OutputBuffer + - (Delta * (BitmapInfoHeader->biHeight - 1)), - 0, 0, BitmapInfoHeader->biWidth, - BitmapInfoHeader->biHeight, -Delta); - - ExFreePool(OutputBuffer); - } - else - { - Delta = ((BitmapInfoHeader->biWidth + 31) & ~31) >> 1; - if (BitmapInfoHeader->biHeight < 0) - { - VidBufferToScreenBlt(Buffer + bfOffBits, - 0, 0, BitmapInfoHeader->biWidth, - -BitmapInfoHeader->biHeight, Delta); - } - else - { - VidBufferToScreenBlt(Buffer + bfOffBits + - (Delta * (BitmapInfoHeader->biHeight - 1)), - 0, 0, BitmapInfoHeader->biWidth, - BitmapInfoHeader->biHeight, -Delta); - } - } -} - -static VOID NTAPI -VidVgaSolidColorFill( - IN ULONG Left, - IN ULONG Top, - IN ULONG Right, - IN ULONG Bottom, - IN ULONG Color) -{ - ULONG x, y; - ULONG VidOffset; - - for (x = Left; x <= Right; x++) - { - WRITE_PORT_UCHAR(GRAPHICS, 0x08); - WRITE_PORT_UCHAR(GRAPHICSDATA, VidpMaskBit[x]); - - VidOffset = (x >> 3) + (Top * 80); - - for (y = Top; y <= Bottom; y++) - { - READ_REGISTER_UCHAR(VidpMemory + VidOffset); - WRITE_REGISTER_UCHAR(VidpMemory + VidOffset, Color & 0xF); - VidOffset += 80; - } - } -} - -static VOID NTAPI -VidVgaDisplayString( - IN PCSTR String) -{ -} - -VID_FUNCTION_TABLE VidVgaTable = -{ - VidVgaInitialize, - VidVgaCleanUp, - VidVgaResetDisplay, - VidVgaBufferToScreenBlt, - VidVgaScreenToBufferBlt, - VidVgaBitBlt, - VidVgaSolidColorFill, - VidVgaDisplayString -}; diff --git a/reactos/drivers/base/bootvid/vid_vgatext.c b/reactos/drivers/base/bootvid/vid_vgatext.c deleted file mode 100644 index 61db02c72ca..00000000000 --- a/reactos/drivers/base/bootvid/vid_vgatext.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * ReactOS Boot video driver - * - * Copyright (C) 2005 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. - */ - -/* INCLUDES ******************************************************************/ - -#include "bootvid.h" -#define NDEBUG -#include - -/* TYPES AND DEFINITIONS *****************************************************/ - -/* 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 - -#define CRTC_COLUMNS 0x01 -#define CRTC_OVERFLOW 0x07 -#define CRTC_ROWS 0x12 -#define CRTC_SCANLINES 0x09 -#define CRTC_CURHI 0x0e -#define CRTC_CURLO 0x0f - -#define CHAR_ATTRIBUTE_BLACK 0x00 /* black on black */ -#define CHAR_ATTRIBUTE 0x07 /* grey on blue */ - -/* GLOBALS *******************************************************************/ - -static BOOLEAN VidpInitialized = FALSE; -static PUCHAR VidpMemory; -static ULONG SizeX, SizeY; - -/* FUNCTIONS *****************************************************************/ - -static VOID NTAPI -VidpVgaTextClearDisplay(VOID) -{ - volatile WORD *ptr = (volatile WORD*)VidpMemory; - ULONG i; - - for (i = 0; i < SizeX * SizeY; i++, ptr++) - *ptr = (0x0000 + ' '); -} - -static BOOLEAN NTAPI -VidVgaTextInitialize( - IN BOOLEAN SetMode) -{ - ULONG ScanLines; - PHYSICAL_ADDRESS PhysicalAddress; - UCHAR Data; - - if (!VidpInitialized) - { - PhysicalAddress.QuadPart = 0xB8000; - VidpMemory = MmMapIoSpace(PhysicalAddress, 0x2000, MmNonCached); - if (VidpMemory == NULL) - return FALSE; - VidpInitialized = TRUE; - - WRITE_PORT_UCHAR(CRTC, CRTC_COLUMNS); - SizeX = READ_PORT_UCHAR(CRTCDATA) + 1; - WRITE_PORT_UCHAR(CRTC, CRTC_ROWS); - SizeY = READ_PORT_UCHAR(CRTCDATA); - WRITE_PORT_UCHAR(CRTC, CRTC_OVERFLOW); - Data = READ_PORT_UCHAR(CRTCDATA); - SizeY |= (((Data & 0x02) << 7) | ((Data & 0x40) << 3)); - SizeY++; - WRITE_PORT_UCHAR(CRTC, CRTC_SCANLINES); - ScanLines = (READ_PORT_UCHAR(CRTCDATA) & 0x1F) + 1; - SizeY = SizeY / ScanLines; - - VidpVgaTextClearDisplay(); - - WRITE_PORT_UCHAR(CRTC, CRTC_CURLO); - WRITE_PORT_UCHAR(CRTCDATA, 0); - WRITE_PORT_UCHAR(CRTC, CRTC_CURHI); - WRITE_PORT_UCHAR(CRTCDATA, 0); - } - - return TRUE; -} - -static VOID NTAPI -VidVgaTextResetDisplay(VOID) -{ - VidVgaTextInitialize(TRUE); -} - -static VOID NTAPI -VidVgaTextCleanUp(VOID) -{ - if (VidpInitialized) - { - MmUnmapIoSpace(VidpMemory, 0x10000); - VidpInitialized = FALSE; - } -} - -static VOID NTAPI -VidVgaTextBufferToScreenBlt( - IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN ULONG Delta) -{ -} - -static VOID NTAPI -VidVgaTextScreenToBufferBlt( - OUT PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN LONG Delta) -{ -} - -static VOID NTAPI -VidVgaTextBitBlt( - IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top) -{ -} - -static VOID NTAPI -VidVgaTextSolidColorFill( - IN ULONG Left, - IN ULONG Top, - IN ULONG Right, - IN ULONG Bottom, - IN ULONG Color) -{ -} - -static VOID NTAPI -VidpVgaTextScrollDisplay(VOID) -{ - volatile USHORT *ptr; - int i; - - RtlMoveMemory(VidpMemory, (PUSHORT)VidpMemory + SizeX, SizeX * (SizeY - 1) * 2); - - ptr = (volatile USHORT *)VidpMemory + (SizeX * (SizeY - 1)); - for (i = 0; i < (int)SizeX; i++, ptr++) - *ptr = (CHAR_ATTRIBUTE << 8) + ' '; -} - -static VOID NTAPI -VidVgaTextDisplayString( - IN PCSTR String) -{ - PCSTR pch; - int offset; - ULONG CursorX; - ULONG CursorY; - - pch = String; - - WRITE_PORT_UCHAR(CRTC, CRTC_CURHI); - offset = READ_PORT_UCHAR(CRTCDATA) << 8; - WRITE_PORT_UCHAR(CRTC, CRTC_CURLO); - offset += READ_PORT_UCHAR(CRTCDATA); - - CursorY = offset / SizeX; - CursorX = offset % SizeX; - - while (*pch != 0) - { - if (*pch == '\n') - { - CursorY++; - CursorX = 0; - } - else if (*pch == '\b') - { - if (CursorX > 0) - CursorX--; - } - else if (*pch != '\r') - { - volatile USHORT *ptr; - - ptr = (volatile USHORT *)VidpMemory + ((CursorY * SizeX) + CursorX); - *ptr = (CHAR_ATTRIBUTE << 8) + *pch; - CursorX++; - - if (CursorX >= SizeX) - { - CursorY++; - CursorX = 0; - } - } - - if (CursorY >= SizeY) - { - VidpVgaTextScrollDisplay(); - CursorY = SizeY - 1; - } - - pch++; - } - - offset = (CursorY * SizeX) + CursorX; - WRITE_PORT_UCHAR(CRTC, CRTC_CURLO); - WRITE_PORT_UCHAR(CRTCDATA, (UCHAR)(offset & 0xff)); - WRITE_PORT_UCHAR(CRTC, CRTC_CURHI); - WRITE_PORT_UCHAR(CRTCDATA, (UCHAR)((offset >> 8) & 0xff)); -} - -VID_FUNCTION_TABLE VidVgaTextTable = { - VidVgaTextInitialize, - VidVgaTextCleanUp, - VidVgaTextResetDisplay, - VidVgaTextBufferToScreenBlt, - VidVgaTextScreenToBufferBlt, - VidVgaTextBitBlt, - VidVgaTextSolidColorFill, - VidVgaTextDisplayString -}; diff --git a/reactos/drivers/base/bootvid/vid_xbox.c b/reactos/drivers/base/bootvid/vid_xbox.c deleted file mode 100644 index f8736a96374..00000000000 --- a/reactos/drivers/base/bootvid/vid_xbox.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * ReactOS Boot video driver - * - * Copyright (C) 2005 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. - */ - -/* INCLUDES ******************************************************************/ - -#include "bootvid.h" -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -static BOOLEAN NTAPI -VidXboxInitialize( - IN BOOLEAN SetMode) -{ - return TRUE; -} - -static VOID NTAPI -VidXboxResetDisplay(VOID) -{ -} - -static VOID NTAPI -VidXboxCleanUp(VOID) -{ -} - -static VOID NTAPI -VidXboxBufferToScreenBlt( - IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN ULONG Delta) -{ -} - -static VOID NTAPI -VidXboxScreenToBufferBlt( - OUT PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN LONG Delta) -{ -} - -static VOID NTAPI -VidXboxBitBlt( - IN PUCHAR Buffer, - IN ULONG Left, - IN ULONG Top) -{ -} - -static VOID NTAPI -VidXboxSolidColorFill( - IN ULONG Left, - IN ULONG Top, - IN ULONG Right, - IN ULONG Bottom, - IN ULONG Color) -{ -} - -static VOID NTAPI -VidXboxDisplayString( - IN PCSTR String) -{ -} - -VID_FUNCTION_TABLE VidXboxTable = { - VidXboxInitialize, - VidXboxCleanUp, - VidXboxResetDisplay, - VidXboxBufferToScreenBlt, - VidXboxScreenToBufferBlt, - VidXboxBitBlt, - VidXboxSolidColorFill, - VidXboxDisplayString -}; diff --git a/reactos/include/ndk/inbvfuncs.h b/reactos/include/ndk/inbvfuncs.h index 142abef54d9..d21f16e969a 100644 --- a/reactos/include/ndk/inbvfuncs.h +++ b/reactos/include/ndk/inbvfuncs.h @@ -23,6 +23,7 @@ Author: // Dependencies // #include +#include #ifndef NTOS_MODE_USER // @@ -30,16 +31,20 @@ Author: // VOID NTAPI -InbvAcquireDisplayOwnership(VOID); +InbvAcquireDisplayOwnership( + VOID +); BOOLEAN NTAPI -InbvCheckDisplayOwnership(VOID); +InbvCheckDisplayOwnership( + VOID +); VOID NTAPI InbvNotifyDisplayOwnershipLost( - IN PVOID Callback + IN INBV_RESET_DISPLAY_PARAMETERS Callback ); // @@ -54,12 +59,14 @@ InbvEnableBootDriver( VOID NTAPI InbvInstallDisplayStringFilter( - IN PVOID DisplayFilter + IN INBV_DISPLAY_STRING_FILTER DisplayFilter ); BOOLEAN NTAPI -InbvIsBootDriverInstalled(VOID); +InbvIsBootDriverInstalled( + VOID +); // // Display Functions @@ -78,7 +85,9 @@ InbvEnableDisplayString( BOOLEAN NTAPI -InbvResetDisplay(VOID); +InbvResetDisplay( + VOID +); VOID NTAPI @@ -105,5 +114,12 @@ InbvSolidColorFill( IN ULONG Color ); +VOID +NTAPI +InbvSetProgressBarSubset( + IN ULONG Floor, + IN ULONG Ceiling +); + #endif #endif diff --git a/reactos/include/ndk/inbvtypes.h b/reactos/include/ndk/inbvtypes.h new file mode 100644 index 00000000000..9500882416a --- /dev/null +++ b/reactos/include/ndk/inbvtypes.h @@ -0,0 +1,55 @@ +/*++ NDK Version: 0098 + +Copyright (c) Alex Ionescu. All rights reserved. + +Header Name: + + inbvtypes.h + +Abstract: + + Type definitions for the Boot Video Driver. + +Author: + + Alex Ionescu (alexi@tinykrnl.org) - Created - 02-Feb-2007 + +--*/ + +#ifndef _INBVTYPES_H +#define _INBVTYPES_H + +// +// Dependencies +// +#include +#ifndef NTOS_MODE_USER + +// +// Boot Video Display Ownership Status +// +typedef enum _INBV_DISPLAY_STATE +{ + INBV_DISPLAY_STATE_OWNED, + INBV_DISPLAY_STATE_DISABLED, + INBV_DISPLAY_STATE_LOST +} INBV_DISPLAY_STATE; + +// +// Function Callbacks +// +typedef +BOOLEAN +(NTAPI *INBV_RESET_DISPLAY_PARAMETERS)( + ULONG Cols, + ULONG Rows +); + +typedef +VOID +(NTAPI *INBV_DISPLAY_STRING_FILTER)( + PCHAR *Str +); + +#endif +#endif diff --git a/reactos/include/reactos/drivers/bootvid/bootvid.h b/reactos/include/reactos/drivers/bootvid/bootvid.h new file mode 100644 index 00000000000..0e0667982f6 --- /dev/null +++ b/reactos/include/reactos/drivers/bootvid/bootvid.h @@ -0,0 +1,72 @@ +#ifndef _BOOTVID_ +#define _BOOTVID_ + +BOOLEAN +NTAPI +VidInitialize(IN BOOLEAN SetMode); + +VOID +NTAPI +VidResetDisplay(IN BOOLEAN HalReset); + +ULONG +NTAPI +VidSetTextColor(ULONG Color); + +VOID +NTAPI +VidDisplayStringXY(PUCHAR String, + ULONG Left, + ULONG Top, + BOOLEAN Transparent); + +VOID +NTAPI +VidSetScrollRegion(ULONG x1, + ULONG y1, + ULONG x2, + ULONG y2); + + +VOID +NTAPI +VidCleanUp(VOID); + +VOID +NTAPI +VidBufferToScreenBlt(IN PUCHAR Buffer, + IN ULONG Left, + IN ULONG Top, + IN ULONG Width, + IN ULONG Height, + IN ULONG Delta); + +VOID +NTAPI +VidDisplayString(PUCHAR String); + +VOID +NTAPI +VidBitBlt(PUCHAR Buffer, + ULONG Left, + ULONG Top); + +VOID +NTAPI +VidScreenToBufferBlt(PUCHAR Buffer, + ULONG Left, + ULONG Top, + ULONG Width, + ULONG Height, + ULONG Delta); + +VOID +NTAPI +VidSolidColorFill(IN ULONG Left, + IN ULONG Top, + IN ULONG Right, + IN ULONG Bottom, + IN UCHAR Color); + + +#endif diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index 6f970145d25..3c317f99b8b 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -1020,20 +1020,20 @@ Phase1InitializationDiscard(PVOID Context) SosEnabled = strstr(CommandLine, "SOS") ? TRUE: FALSE; /* Setup the boot driver */ - InbvDisplayInitialize(); - if (!ExpInTextModeSetup) InbvDisplayInitialize2(NoGuiBoot); + InbvEnableBootDriver(!NoGuiBoot); + InbvDriverInitialize(LoaderBlock, 18); /* Check if GUI boot is enabled */ if (!NoGuiBoot) { /* It is, display the boot logo and enable printing strings */ InbvEnableDisplayString(SosEnabled); - InbvDisplayBootLogo(SosEnabled); + //DisplayBootBitmap(SosEnabled); } else { /* Release display ownership if not using GUI boot */ - if (!SosEnabled) InbvNotifyDisplayOwnershipLost(NULL); + InbvNotifyDisplayOwnershipLost(NULL); /* Don't allow boot-time strings */ InbvEnableDisplayString(FALSE); @@ -1207,7 +1207,8 @@ Phase1InitializationDiscard(PVOID Context) /* Wait 5 seconds for it to initialize */ Timeout.QuadPart = Int32x32To64(5, -10000000); Status = ZwWaitForSingleObject(ProcessInfo->ProcessHandle, FALSE, &Timeout); - if (!NoGuiBoot) InbvFinalizeBootLogo(); + //if (InbvBootDriverInstalled) FinalizeBootLogo(); + if (Status == STATUS_SUCCESS) { /* Bugcheck the system if SMSS couldn't initialize */ diff --git a/reactos/ntoskrnl/inbv/inbv.c b/reactos/ntoskrnl/inbv/inbv.c index 4a704d7973b..de94faa4bb8 100644 --- a/reactos/ntoskrnl/inbv/inbv.c +++ b/reactos/ntoskrnl/inbv/inbv.c @@ -1,350 +1,531 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/inbv/inbv.c - * PURPOSE: Boot video support - * - * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) - */ - /* INCLUDES ******************************************************************/ #include #define NDEBUG -#include - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, InbvDisplayInitialize) -#endif +#include +#include "bootvid\bootvid.h" /* GLOBALS *******************************************************************/ -/* DATA **********************************************************************/ - -static BOOLEAN BootVidDriverInstalled = FALSE; - -static BOOLEAN (NTAPI *VidInitialize)(BOOLEAN); -static VOID (NTAPI *VidCleanUp)(VOID); -static VOID (NTAPI *VidResetDisplay)(VOID); -static VOID (NTAPI *VidBufferToScreenBlt)(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG); -static VOID (NTAPI *VidScreenToBufferBlt)(PUCHAR, ULONG, ULONG, ULONG, ULONG, ULONG); -static VOID (NTAPI *VidBitBlt)(PUCHAR, ULONG, ULONG); -static VOID (NTAPI *VidSolidColorFill)(ULONG, ULONG, ULONG, ULONG, ULONG); -static VOID (NTAPI *VidDisplayString)(PCSTR); -static NTSTATUS (NTAPI *BootVidDisplayBootLogo)(PVOID); -static VOID (NTAPI *BootVidUpdateProgress)(ULONG Progress); -static VOID (NTAPI *BootVidFinalizeBootLogo)(VOID); - -static KSPIN_LOCK InbvLock; -static KIRQL InbvOldIrql; -static ULONG InbvDisplayState = 0; -static PHAL_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters = NULL; -static PVOID BootVidBase; +KSPIN_LOCK BootDriverLock; +KIRQL InbvOldIrql; +INBV_DISPLAY_STATE InbvDisplayState; +BOOLEAN InbvBootDriverInstalled; +BOOLEAN InbvDisplayDebugStrings; +INBV_DISPLAY_STRING_FILTER InbvDisplayFilter; +ULONG ProgressBarLeft, ProgressBarTop; +BOOLEAN ShowProgressBar; +INBV_PROGRESS_STATE InbvProgressState; +INBV_RESET_DISPLAY_PARAMETERS InbvResetDisplayParameters; +ULONG ResourceCount; +PUCHAR ResourceList[64]; /* FUNCTIONS *****************************************************************/ -VOID NTAPI INIT_FUNCTION -InbvDisplayInitialize(VOID) +PVOID +NTAPI +FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock, + IN ULONG ResourceId) { - struct { - ANSI_STRING Name; - PVOID *Ptr; - } Exports[] = { - { RTL_CONSTANT_STRING("VidInitialize"), (PVOID*)&VidInitialize }, - { RTL_CONSTANT_STRING("VidCleanUp"), (PVOID*)&VidCleanUp }, - { RTL_CONSTANT_STRING("VidResetDisplay"), (PVOID*)&VidResetDisplay }, - { RTL_CONSTANT_STRING("VidBufferToScreenBlt"), (PVOID*)&VidBufferToScreenBlt }, - { RTL_CONSTANT_STRING("VidScreenToBufferBlt"), (PVOID*)&VidScreenToBufferBlt }, - { RTL_CONSTANT_STRING("VidBitBlt"), (PVOID*)&VidBitBlt }, - { RTL_CONSTANT_STRING("VidSolidColorFill"), (PVOID*)&VidSolidColorFill }, - { RTL_CONSTANT_STRING("VidDisplayString"), (PVOID*)&VidDisplayString }, - { RTL_CONSTANT_STRING("BootVidDisplayBootLogo"), (PVOID*)&BootVidDisplayBootLogo }, - { RTL_CONSTANT_STRING("BootVidUpdateProgress"), (PVOID*)&BootVidUpdateProgress }, - { RTL_CONSTANT_STRING("BootVidFinalizeBootLogo"), (PVOID*)&BootVidFinalizeBootLogo } - }; - UNICODE_STRING BootVidPath = RTL_CONSTANT_STRING(L"bootvid.sys"); - PLDR_DATA_TABLE_ENTRY ModuleObject = NULL, LdrEntry; - ULONG Index; - NTSTATUS Status; + UNICODE_STRING UpString = RTL_CONSTANT_STRING(L"ntoskrnl.exe"); + UNICODE_STRING MpString = RTL_CONSTANT_STRING(L"ntkrnlmp.exe"); + PLIST_ENTRY NextEntry, ListHead; + PLDR_DATA_TABLE_ENTRY LdrEntry; + PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; + LDR_RESOURCE_INFO ResourceInfo; + ULONG Size; + NTSTATUS Status; + PVOID Data = NULL; - /* FIXME: Hack, try to search for boot driver. */ -#if 0 - ModuleObject = LdrGetModuleObject(&BootVidPath); -#else - { - NTSTATUS LdrProcessModule(PVOID, PUNICODE_STRING, PLDR_DATA_TABLE_ENTRY*); - PLIST_ENTRY ListHead, NextEntry; + /* Loop the driver list */ + ListHead = &LoaderBlock->LoadOrderListHead; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + /* Get the entry */ + LdrEntry = CONTAINING_RECORD(NextEntry, + LDR_DATA_TABLE_ENTRY, + InLoadOrderLinks); - ListHead = &KeLoaderBlock->LoadOrderListHead; - NextEntry = ListHead->Flink; - while (ListHead != NextEntry) - { - /* Get the entry */ - LdrEntry = CONTAINING_RECORD(NextEntry, - LDR_DATA_TABLE_ENTRY, - InLoadOrderLinks); - - /* Compare names */ - if (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &BootVidPath, TRUE)) - { - /* Tell, that the module is already loaded */ - LdrEntry->Flags |= LDRP_ENTRY_INSERTED; - Status = LdrProcessModule(LdrEntry->DllBase, - &BootVidPath, - &ModuleObject); - if (!NT_SUCCESS(Status)) - { - DPRINT1("%x\n", Status); - return; - } + /* Check for a match */ + if ((RtlEqualUnicodeString(&LdrEntry->BaseDllName, &UpString, TRUE)) || + (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &MpString, TRUE))) + { + /* Break out */ break; - } + } + } - /* Go to the next driver */ - NextEntry= NextEntry->Flink; - } - } -#endif + /* Check if we found it */ + if (NextEntry != ListHead) + { + /* Try to find the resource */ + ResourceInfo.Type = 2; + ResourceInfo.Name = ResourceId; + ResourceInfo.Language = 0; + Status = LdrFindResource_U(LdrEntry->DllBase, + &ResourceInfo, + RESOURCE_DATA_LEVEL, + &ResourceDataEntry); + if (NT_SUCCESS(Status)) + { + /* Access the resource */ + Status = LdrAccessResource(LdrEntry->DllBase, + ResourceDataEntry, + &Data, + &Size); + if (!NT_SUCCESS(Status)) Data = NULL; + } + } - if (ModuleObject != NULL) - { - for (Index = 0; Index < sizeof(Exports) / sizeof(Exports[0]); Index++) - { - Status = LdrGetProcedureAddress(ModuleObject->DllBase, - &Exports[Index].Name, 0, - Exports[Index].Ptr); - if (!NT_SUCCESS(Status)) - return; - } - - DPRINT("Done!\n"); - KeInitializeSpinLock(&InbvLock); - BootVidBase = ModuleObject->DllBase; - BootVidDriverInstalled = TRUE; - } + /* Return the pointer */ + return Data; } -static VOID NTAPI +BOOLEAN +NTAPI +InbvDriverInitialize(IN PLOADER_PARAMETER_BLOCK LoaderBlock, + IN ULONG Count) +{ + PCHAR CommandLine; + BOOLEAN CustomLogo = FALSE; + ULONG i; + + /* Quit if we're already installed */ + if (InbvBootDriverInstalled) return TRUE; + + /* Initialize the lock and check the current display state */ + KeInitializeSpinLock(&BootDriverLock); + if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED) + { + /* Check if we have a custom boot logo */ + CommandLine = _strupr(LoaderBlock->LoadOptions); + CustomLogo = strstr(CommandLine, "BOOTLOGO") ? TRUE: FALSE; + } + + /* Initialize the video */ + InbvBootDriverInstalled = VidInitialize(CustomLogo); + DPRINT1("Init: %lx\n", InbvBootDriverInstalled); + if (InbvBootDriverInstalled) + { + /* Find bitmap resources in the kernel */ + ResourceCount = Count; + for (i = 0; i < Count; i++) + { + /* Do the lookup */ + ResourceList[i] = FindBitmapResource(LoaderBlock, i); + } + + /* Set the progress bar ranges */ + InbvSetProgressBarSubset(0, 100); + } + + /* Return install state */ + return InbvBootDriverInstalled; +} + +VOID +NTAPI InbvAcquireLock(VOID) { - if ((InbvOldIrql = KeGetCurrentIrql()) < DISPATCH_LEVEL) - InbvOldIrql = KfRaiseIrql(DISPATCH_LEVEL); - KiAcquireSpinLock(&InbvLock); + /* Check if we're below dispatch level */ + InbvOldIrql = KeGetCurrentIrql(); + if (InbvOldIrql < DISPATCH_LEVEL) + { + /* Raise IRQL to dispatch level */ + InbvOldIrql = KfRaiseIrql(DISPATCH_LEVEL); + } + + /* Acquire the lock */ + KiAcquireSpinLock(&BootDriverLock); } -static VOID NTAPI +VOID +NTAPI InbvReleaseLock(VOID) { - KiReleaseSpinLock(&InbvLock); - if (InbvOldIrql < DISPATCH_LEVEL) - KfLowerIrql(InbvOldIrql); + /* Release the driver lock */ + KiReleaseSpinLock(&BootDriverLock); + + /* If we were below dispatch level, lower IRQL back */ + if (InbvOldIrql < DISPATCH_LEVEL) KfLowerIrql(InbvOldIrql); } -VOID STDCALL +VOID +NTAPI InbvEnableBootDriver(IN BOOLEAN Enable) { - if (BootVidDriverInstalled) - { - if (InbvDisplayState >= 2) - return; - InbvAcquireLock(); - if (InbvDisplayState == 0) - VidCleanUp(); - InbvDisplayState = !Enable; - InbvReleaseLock(); - } - else - { - InbvDisplayState = !Enable; - } + /* Check if we're installed */ + if (InbvBootDriverInstalled) + { + /* Check for lost state */ + if (InbvDisplayState >= INBV_DISPLAY_STATE_LOST) return; + + /* Acquire the lock */ + InbvAcquireLock(); + + /* Cleanup the screen if we own it */ + if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED) VidCleanUp(); + + /* Set the new display state */ + InbvDisplayState = Enable ? INBV_DISPLAY_STATE_OWNED: + INBV_DISPLAY_STATE_DISABLED; + + /* Release the lock */ + InbvReleaseLock(); + } + else + { + /* Set the new display state */ + InbvDisplayState = Enable ? INBV_DISPLAY_STATE_OWNED: + INBV_DISPLAY_STATE_DISABLED; + } } -VOID NTAPI +VOID +NTAPI InbvAcquireDisplayOwnership(VOID) { - if (InbvResetDisplayParameters && InbvDisplayState == 2) - { - if (InbvResetDisplayParameters != NULL) - InbvResetDisplayParameters(80, 50); - } - InbvDisplayState = 0; + /* Check if we have a callback and we're just acquiring it now */ + if ((InbvResetDisplayParameters) && + (InbvDisplayState == INBV_DISPLAY_STATE_LOST)) + { + /* Call the callback */ + InbvResetDisplayParameters(80, 50); + } + + /* Acquire the display */ + InbvDisplayState = INBV_DISPLAY_STATE_OWNED; } -BOOLEAN STDCALL +VOID +NTAPI +InbvSetDisplayOwnership(IN BOOLEAN DisplayOwned) +{ + /* Set the new display state */ + InbvDisplayState = DisplayOwned ? INBV_DISPLAY_STATE_OWNED: + INBV_DISPLAY_STATE_LOST; +} + +BOOLEAN +NTAPI InbvCheckDisplayOwnership(VOID) { - return InbvDisplayState != 2; + /* Return if we own it or not */ + return InbvDisplayState != INBV_DISPLAY_STATE_LOST; } -BOOLEAN STDCALL +INBV_DISPLAY_STATE +NTAPI +InbvGetDisplayState(VOID) +{ + /* Return the actual state */ + return InbvDisplayState; +} + +BOOLEAN +NTAPI InbvDisplayString(IN PCHAR String) { - if (BootVidDriverInstalled && InbvDisplayState == 0) - { - InbvAcquireLock(); - VidDisplayString(String); - InbvReleaseLock(); + /* Make sure we own the display */ + if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED) + { + /* If we're not allowed, return success anyway */ + if (!InbvDisplayDebugStrings) return TRUE; - /* Call Headless (We don't support headless for now) - HeadlessDispatch(DISPLAY_STRING); - */ + /* Check if a filter is installed */ + if (InbvDisplayFilter) InbvDisplayFilter(&String); - return TRUE; - } + /* Acquire the lock */ + InbvAcquireLock(); - return FALSE; + /* Make sure we're installed and display the string */ + if (InbvBootDriverInstalled) VidDisplayString(String); + + /* Call Headless (We don't support headless for now) + HeadlessDispatch(DISPLAY_STRING); */ + + /* Release the lock */ + InbvReleaseLock(); + + /* All done */ + return TRUE; + } + + /* We don't own it, fail */ + return FALSE; } - -BOOLEAN STDCALL +BOOLEAN +NTAPI InbvEnableDisplayString(IN BOOLEAN Enable) { - return FALSE; + BOOLEAN OldSetting; + + /* Get the old setting */ + OldSetting = InbvDisplayDebugStrings; + + /* Update it */ + InbvDisplayDebugStrings = Enable; + + /* Return the old setting */ + return OldSetting; } - -VOID STDCALL -InbvInstallDisplayStringFilter(IN PVOID Unknown) +VOID +NTAPI +InbvInstallDisplayStringFilter(IN INBV_DISPLAY_STRING_FILTER Filter) { + /* Save the filter */ + InbvDisplayFilter = Filter; } - -BOOLEAN STDCALL +BOOLEAN +NTAPI InbvIsBootDriverInstalled(VOID) { - return BootVidDriverInstalled; + /* Return driver state */ + return InbvBootDriverInstalled; } - -VOID STDCALL -InbvNotifyDisplayOwnershipLost( - IN PVOID Callback) +VOID +NTAPI +InbvNotifyDisplayOwnershipLost(IN INBV_RESET_DISPLAY_PARAMETERS Callback) { - if (BootVidDriverInstalled) - { - InbvAcquireLock(); - if (InbvDisplayState != 2) - VidCleanUp(); - else if (InbvResetDisplayParameters != NULL) - InbvResetDisplayParameters(80, 50); - InbvResetDisplayParameters = Callback; - InbvDisplayState = 2; - InbvReleaseLock(); - } - else - { - InbvResetDisplayParameters = Callback; - InbvDisplayState = 2; - } + /* Check if we're installed */ + if (InbvBootDriverInstalled) + { + /* Acquire the lock and cleanup if we own the screen */ + InbvAcquireLock(); + if (InbvDisplayState != INBV_DISPLAY_STATE_LOST) VidCleanUp(); + + /* Set the reset callback and display state */ + InbvResetDisplayParameters = Callback; + InbvDisplayState = INBV_DISPLAY_STATE_LOST; + + /* Release the lock */ + InbvReleaseLock(); + } + else + { + /* Set the reset callback and display state */ + InbvResetDisplayParameters = Callback; + InbvDisplayState = INBV_DISPLAY_STATE_LOST; + } } - -BOOLEAN STDCALL +BOOLEAN +NTAPI InbvResetDisplay(VOID) { - if (BootVidDriverInstalled && InbvDisplayState == 0) - { - VidResetDisplay(); - return TRUE; - } - return FALSE; + /* Check if we're installed and we own it */ + if ((InbvBootDriverInstalled) && + (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) + { + /* Do the reset */ + VidResetDisplay(TRUE); + return TRUE; + } + + /* Nothing to reset */ + return FALSE; } - -VOID STDCALL -InbvSetScrollRegion( - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height) +VOID +NTAPI +InbvSetScrollRegion(IN ULONG Left, + IN ULONG Top, + IN ULONG Width, + IN ULONG Height) { + /* Just call bootvid */ + VidSetScrollRegion(Left, Top, Width, Height); } - -VOID STDCALL -InbvSetTextColor( - IN ULONG Color) +VOID +NTAPI +InbvSetTextColor(IN ULONG Color) { + /* FIXME: Headless */ + + /* Update the text color */ + VidSetTextColor(Color); } - -VOID STDCALL -InbvSolidColorFill( - IN ULONG Left, - IN ULONG Top, - IN ULONG Width, - IN ULONG Height, - IN ULONG Color) +VOID +NTAPI +InbvSolidColorFill(IN ULONG Left, + IN ULONG Top, + IN ULONG Width, + IN ULONG Height, + IN ULONG Color) { - if (BootVidDriverInstalled && InbvDisplayState == 0) - { - VidSolidColorFill(Left, Top, Width, Height, Color); - } + /* Make sure we own it */ + if (InbvDisplayState == INBV_DISPLAY_STATE_OWNED) + { + /* Acquire the lock */ + InbvAcquireLock(); + + /* Check if we're installed */ + if (InbvBootDriverInstalled) + { + /* Call bootvid */ + VidSolidColorFill(Left, Top, Width, Height, Color); + } + + /* FIXME: Headless */ + + /* Release the lock */ + InbvReleaseLock(); + } } - -BOOLEAN NTAPI -BootVidResetDisplayParameters(ULONG SizeX, ULONG SizeY) +VOID +NTAPI +InbvUpdateProgressBar(IN ULONG Progress) { - BootVidFinalizeBootLogo(); - return TRUE; + ULONG FillCount, Left = 0; + + /* Make sure the progress bar is enabled, that we own and are installed */ + if ((ShowProgressBar) && + (InbvBootDriverInstalled) && + (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) + { + /* Calculate the fill count */ + FillCount = InbvProgressState.Bias * Progress + InbvProgressState.Floor; + FillCount *= 18; + FillCount /= 10000; + + /* Start fill loop */ + while (FillCount) + { + /* Acquire the lock */ + InbvAcquireLock(); + + /* Fill the progress bar */ + VidSolidColorFill(Left + ProgressBarLeft, + ProgressBarTop, + Left + ProgressBarLeft + 7, + ProgressBarTop + 7, + 11); + + /* Release the lock */ + InbvReleaseLock(); + + /* Update the X position */ + Left += 9; + FillCount--; + } + } } - -VOID NTAPI -InbvDisplayInitialize2(BOOLEAN NoGuiBoot) +VOID +NTAPI +InbvBufferToScreenBlt(IN PUCHAR Buffer, + IN ULONG X, + IN ULONG Y, + IN ULONG Width, + IN ULONG Height, + IN ULONG Delta) { - VidInitialize(!NoGuiBoot); + /* Check if we're installed and we own it */ + if ((InbvBootDriverInstalled) && + (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) + { + /* Do the blit */ + VidBufferToScreenBlt(Buffer, X, Y, Width, Height, Delta); + } } - -VOID NTAPI -InbvDisplayBootLogo(IN BOOLEAN SosEnabled) +VOID +NTAPI +InbvBitBlt(IN PUCHAR Buffer, + IN ULONG X, + IN ULONG Y) { - InbvEnableBootDriver(TRUE); + /* Check if we're installed and we own it */ + if ((InbvBootDriverInstalled) && + (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) + { + /* Acquire the lock */ + InbvAcquireLock(); - if (BootVidDriverInstalled) - { - InbvResetDisplayParameters = BootVidResetDisplayParameters; - if (!SosEnabled) BootVidDisplayBootLogo(BootVidBase); - } + /* Do the blit */ + VidBitBlt(Buffer, X, Y); + + /* Release the lock */ + InbvReleaseLock(); + } } - -VOID NTAPI -InbvUpdateProgressBar( - IN ULONG Progress) +VOID +NTAPI +InbvScreenToBufferBlt(IN PUCHAR Buffer, + IN ULONG X, + IN ULONG Y, + IN ULONG Width, + IN ULONG Height, + IN ULONG Delta) { - if (BootVidDriverInstalled) - { - BootVidUpdateProgress(Progress); - } + /* Check if we're installed and we own it */ + if ((InbvBootDriverInstalled) && + (InbvDisplayState == INBV_DISPLAY_STATE_OWNED)) + { + /* Do the blit */ + VidScreenToBufferBlt(Buffer, X, Y, Width, Height, Delta); + } } - -VOID NTAPI -InbvFinalizeBootLogo(VOID) +VOID +NTAPI +InbvSetProgressBarCoordinates(IN ULONG Left, + IN ULONG Top) { - if (BootVidDriverInstalled) - { - /* Notify the hal we have released the display. */ - /* InbvReleaseDisplayOwnership(); */ - BootVidFinalizeBootLogo(); - InbvEnableBootDriver(FALSE); - } + /* Update the coordinates */ + ProgressBarLeft = Left; + ProgressBarTop = Top; + + /* Enable the progress bar */ + ShowProgressBar = TRUE; } - -NTSTATUS STDCALL -NtDisplayString( - IN PUNICODE_STRING DisplayString) +VOID +NTAPI +InbvSetProgressBarSubset(IN ULONG Floor, + IN ULONG Ceiling) { - OEM_STRING OemString; + /* Sanity checks */ + ASSERT(Floor < Ceiling); + ASSERT(Ceiling <= 100); - RtlUnicodeStringToOemString(&OemString, DisplayString, TRUE); - InbvDisplayString(OemString.Buffer); - RtlFreeOemString(&OemString); - - return STATUS_SUCCESS; + /* Update the progress bar state */ + InbvProgressState.Floor = Floor * 100; + InbvProgressState.Ceiling = Ceiling * 100; + InbvProgressState.Bias = (Ceiling * 100) - Floor; +} + +PUCHAR +NTAPI +InbvGetResourceAddress(IN ULONG ResourceNumber) +{ + /* Validate the resource number */ + if (ResourceNumber > ResourceCount) return NULL; + + /* Return the address */ + return ResourceList[ResourceNumber--]; +} + +NTSTATUS +NTAPI +NtDisplayString(IN PUNICODE_STRING DisplayString) +{ + OEM_STRING OemString; + + /* Convert the string to OEM and display it */ + RtlUnicodeStringToOemString(&OemString, DisplayString, TRUE); + InbvDisplayString(OemString.Buffer); + RtlFreeOemString(&OemString); + + /* Return success */ + return STATUS_SUCCESS; } diff --git a/reactos/ntoskrnl/include/internal/inbv.h b/reactos/ntoskrnl/include/internal/inbv.h index 9e6b34e3ad2..ffdd818e236 100644 --- a/reactos/ntoskrnl/include/internal/inbv.h +++ b/reactos/ntoskrnl/include/internal/inbv.h @@ -1,26 +1,31 @@ #ifndef NTOSKRNL_INBV_H #define NTOSKRNL_INBV_H -/* INCLUDES ******************************************************************/ +typedef struct _InbvProgressState +{ + ULONG Floor; + ULONG Ceiling; + ULONG Bias; +} INBV_PROGRESS_STATE; -/* DEFINES *******************************************************************/ +VOID +NTAPI +InbvUpdateProgressBar( + IN ULONG Progress +); -/* FUNCTIONS *****************************************************************/ +BOOLEAN +NTAPI +InbvDriverInitialize( + IN PLOADER_PARAMETER_BLOCK LoaderBlock, + IN ULONG Count +); -VOID NTAPI INIT_FUNCTION -InbvDisplayInitialize(VOID); - -VOID NTAPI -InbvDisplayInitialize2(BOOLEAN NoGuiBoot); - -VOID NTAPI -InbvDisplayBootLogo(IN BOOLEAN SosEnabled); - -VOID NTAPI -InbvUpdateProgressBar(ULONG Progress); - -VOID NTAPI -InbvFinalizeBootLogo(VOID); +VOID +NTAPI +InbvEnableBootDriver( + IN BOOLEAN Enable +); #endif /* NTOSKRNL_INBV_H */ diff --git a/reactos/ntoskrnl/ke/freeldr.c b/reactos/ntoskrnl/ke/freeldr.c index 95c6255f569..471d57c5c08 100644 --- a/reactos/ntoskrnl/ke/freeldr.c +++ b/reactos/ntoskrnl/ke/freeldr.c @@ -41,7 +41,6 @@ ARC_DISK_INFORMATION BldrArcDiskInfo; // 0x9F34 CHAR BldrArcNames[32][256]; // 0x9F3C ARC_DISK_SIGNATURE BldrDiskInfo[32]; // 0xBF3C // 0xC23C -ULONG Guard = 0xCACA1234; /* FUNCTIONS *****************************************************************/ @@ -342,7 +341,7 @@ KiRosPrepareForSystemStartup(IN ULONG Dummy, MmSystemRangeStart = (PVOID)KeRosLoaderBlock->KernelBase; /* Convert every driver address to virtual memory */ - for (i = 2; i < KeRosLoaderBlock->ModsCount; i++) + for (i = 3; i < KeRosLoaderBlock->ModsCount; i++) { /* Subtract the base Address in Physical Memory */ KeRosLoaderBlock->ModsAddr[i].ModStart -= 0x200000; diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 600d0efae5a..977ab822c25 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -20,6 +20,7 @@ rossym string kdcom + bootvid wdmguid ntoskrnl.h