ReactOS 0.4.15-dev-5893-g1bb4167
bootvid.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Boot Video Driver for Original Xbox
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Main file
5 * COPYRIGHT: Copyright 2004 Gé van Geldorp (gvg@reactos.org)
6 * Copyright 2005 Filip Navara (navaraf@reactos.org)
7 * Copyright 2020 Stanislav Motylkov (x86corez@gmail.com)
8 */
9
10#include "precomp.h"
11
12#include <debug.h>
13
14#include <drivers/xbox/xgpu.h>
15
16/* GLOBALS ********************************************************************/
17
23
24/* PRIVATE FUNCTIONS *********************************************************/
25
26static UCHAR
28 ULONG Base,
30{
33}
34
35static UCHAR
37 ULONG Base,
39{
40 /* Get BPP directly from NV2A CRTC (magic constants are from Cromwell) */
41 UCHAR BytesPerPixel = 8 * (((NvGetCrtc(Base, 0x19) & 0xE0) << 3) | (NvGetCrtc(Base, 0x13) & 0xFF)) / ScreenWidth;
42
43 if (BytesPerPixel == 4)
44 {
45 ASSERT((NvGetCrtc(Base, 0x28) & 0xF) == BytesPerPixel - 1);
46 }
47 else
48 {
49 ASSERT((NvGetCrtc(Base, 0x28) & 0xF) == BytesPerPixel);
50 }
51
52 return BytesPerPixel;
53}
54
55static VOID
57{
59 ULONG x, y;
60
61 /* Top panning */
62 for (x = 0; x < PanV * FrameBufferWidth; x++)
63 {
64 *Frame++ = CachedPalette[0];
65 }
66
67 /* Left panning */
68 for (y = 0; y < SCREEN_HEIGHT; y++)
69 {
70 Frame = (PULONG)(FrameBufferStart + FB_OFFSET(-PanH, y));
71
72 for (x = 0; x < PanH; x++)
73 {
74 *Frame++ = CachedPalette[0];
75 }
76 }
77
78 /* Screen redraw */
79 PUCHAR Back = BackBuffer;
80 for (y = 0; y < SCREEN_HEIGHT; y++)
81 {
82 Frame = (PULONG)(FrameBufferStart + FB_OFFSET(0, y));
83
84 for (x = 0; x < SCREEN_WIDTH; x++)
85 {
86 *Frame++ = CachedPalette[*Back++];
87 }
88 }
89
90 /* Right panning */
91 for (y = 0; y < SCREEN_HEIGHT; y++)
92 {
94
95 for (x = 0; x < PanH; x++)
96 {
97 *Frame++ = CachedPalette[0];
98 }
99 }
100
101 /* Bottom panning */
103 for (x = 0; x < PanV * FrameBufferWidth; x++)
104 {
105 *Frame++ = CachedPalette[0];
106 }
107}
108
109/* PUBLIC FUNCTIONS **********************************************************/
110
112NTAPI
114 _In_ BOOLEAN SetMode)
115{
117
118 /* FIXME: Add platform check */
119 /* 1. Access PCI device 1:0:0 */
120 /* 2. Check if device ID is 10DE:02A0 */
121
122 /* FIXME: Get device MMIO ranges from PCI */
123 PHYSICAL_ADDRESS PhysControlStart = {.QuadPart = 0xFD000000};
124 PHYSICAL_ADDRESS PhysFrameBufferStart = {.QuadPart = 0xF0000000};
125 ULONG ControlLength = 16 * 1024 * 1024;
126
127 ULONG_PTR ControlStart = (ULONG_PTR)MmMapIoSpace(PhysControlStart, ControlLength, MmNonCached);
128 if (!ControlStart)
129 {
130 DPRINT1("Out of memory!\n");
131 return FALSE;
132 }
133
137
138 FrameBuffer &= 0x0FFFFFFF;
139 if (FrameBuffer != 0x3C00000 && FrameBuffer != 0x7C00000)
140 {
141 /* Check framebuffer address (high 4 MB of either 64 or 128 MB RAM) */
142 DPRINT1("Non-standard framebuffer address 0x%p\n", FrameBuffer);
143 }
144 /* Verify that framebuffer address is page-aligned */
146
148 {
149 DPRINT1("Unsupported screen resolution!\n");
150 goto cleanup;
151 }
152
154 ASSERT(BytesPerPixel >= 1 && BytesPerPixel <= 4);
155
156 if (BytesPerPixel != 4)
157 {
158 DPRINT1("Unsupported BytesPerPixel = %d\n", BytesPerPixel);
159 goto cleanup;
160 }
161
162 /* Calculate panning values */
165
166 /* Verify that screen fits framebuffer size */
168
169 /* FIXME: obtain fb size from firmware somehow (Cromwell reserves high 4 MB of RAM) */
171 {
172 DPRINT1("Current screen resolution exceeds video memory bounds!\n");
173 goto cleanup;
174 }
175
176 /*
177 * Reserve off-screen area for the backbuffer that contains 8-bit indexed
178 * color screen image, plus preserved row data.
179 */
180 ULONG BackBufferSize = SCREEN_WIDTH * (SCREEN_HEIGHT + BOOTCHAR_HEIGHT + 1);
181
182 /* Make sure there is enough video memory for backbuffer */
183 if (NV2A_VIDEO_MEMORY_SIZE - FrameBufferSize < BackBufferSize)
184 {
185 DPRINT1("Out of memory!\n");
186 goto cleanup;
187 }
188
189 /* Return the address back to GPU memory mapped I/O */
190 PhysFrameBufferStart.QuadPart += FrameBuffer;
192 if (!FrameBufferStart)
193 {
194 DPRINT1("Out of memory!\n");
195 goto cleanup;
196 }
197
198 Result = TRUE;
199
200 /* Place backbuffer in the hidden part of framebuffer */
202
203 /* Now check if we have to set the mode */
204 if (SetMode)
206
207cleanup:
208 if (ControlStart)
209 MmUnmapIoSpace((PVOID)ControlStart, ControlLength);
210
211 /* Video is ready */
212 return Result;
213}
214
215VOID
216NTAPI
218{
219 /* Just fill the screen black */
221}
222
223VOID
224NTAPI
226 _In_ BOOLEAN HalReset)
227{
228 /* Clear the current position */
229 VidpCurrentX = 0;
230 VidpCurrentY = 0;
231
232 /* Clear the screen with HAL if we were asked to */
233 if (HalReset)
235
236 /* Re-initialize the palette and fill the screen black */
240}
241
242VOID
243NTAPI
247{
249
250 for (ULONG i = 0; i < Count; i++, Entry++)
251 {
252 CachedPalette[i] = *Entry | 0xFF000000;
253 }
254 ApplyPalette();
255}
256
257VOID
259{
260 /* Nothing to prepare */
261 NOTHING;
262}
263
264VOID
266 _In_ ULONG Left,
267 _In_ ULONG Top,
269{
270 PUCHAR Back = BackBuffer + BB_OFFSET(Left, Top);
271 PULONG Frame = (PULONG)(FrameBufferStart + FB_OFFSET(Left, Top));
272
273 *Back = Color;
274 *Frame = CachedPalette[Color];
275}
276
277VOID
278NTAPI
280 _In_ ULONG CurrentTop,
281 _In_ ULONG TopDelta,
282 _In_ BOOLEAN Restore)
283{
284 PUCHAR NewPosition, OldPosition;
285
286 /* Calculate the position in memory for the row */
287 if (Restore)
288 {
289 /* Restore the row by copying back the contents saved off-screen */
290 NewPosition = BackBuffer + BB_OFFSET(0, CurrentTop);
291 OldPosition = BackBuffer + BB_OFFSET(0, SCREEN_HEIGHT);
292 }
293 else
294 {
295 /* Preserve the row by saving its contents off-screen */
296 NewPosition = BackBuffer + BB_OFFSET(0, SCREEN_HEIGHT);
297 OldPosition = BackBuffer + BB_OFFSET(0, CurrentTop);
298 }
299
300 /* Set the count and loop every pixel of backbuffer */
301 ULONG Count = TopDelta * SCREEN_WIDTH;
302
303 RtlCopyMemory(NewPosition, OldPosition, Count);
304
305 if (Restore)
306 {
307 NewPosition = BackBuffer + BB_OFFSET(0, CurrentTop);
308
309 /* Set the count and loop every pixel of framebuffer */
310 for (ULONG y = 0; y < TopDelta; y++)
311 {
312 PULONG Frame = (PULONG)(FrameBufferStart + FB_OFFSET(0, CurrentTop + y));
313
315 while (Count--)
316 {
317 *Frame++ = CachedPalette[*NewPosition++];
318 }
319 }
320 }
321}
322
323VOID
324NTAPI
326 _In_ ULONG Scroll)
327{
328 ULONG RowSize = VidpScrollRegion[2] - VidpScrollRegion[0] + 1;
329
330 /* Calculate the position in memory for the row */
331 PUCHAR OldPosition = BackBuffer + BB_OFFSET(VidpScrollRegion[0], VidpScrollRegion[1] + Scroll);
333
334 /* Start loop */
335 for (ULONG Top = VidpScrollRegion[1]; Top <= VidpScrollRegion[3]; ++Top)
336 {
337 ULONG i;
338
339 /* Scroll the row */
340 RtlCopyMemory(NewPosition, OldPosition, RowSize);
341
343
344 for (i = 0; i < RowSize; ++i)
345 Frame[i] = CachedPalette[NewPosition[i]];
346
347 OldPosition += SCREEN_WIDTH;
348 NewPosition += SCREEN_WIDTH;
349 }
350}
351
352VOID
353NTAPI
355 _In_ CHAR Character,
356 _In_ ULONG Left,
357 _In_ ULONG Top,
358 _In_ ULONG TextColor,
359 _In_ ULONG BackColor)
360{
361 /* Get the font and pixel pointer */
362 PUCHAR FontChar = GetFontPtr(Character);
363
364 /* Loop each pixel height */
365 for (ULONG y = Top; y < Top + BOOTCHAR_HEIGHT; y++, FontChar += FONT_PTR_DELTA)
366 {
367 /* Loop each pixel width */
368 ULONG x = Left;
369
370 for (UCHAR bit = 1 << (BOOTCHAR_WIDTH - 1); bit > 0; bit >>= 1, x++)
371 {
372 /* Check if we should draw this pixel */
373 if (*FontChar & bit)
374 {
375 /* We do, use the given Text Color */
376 SetPixel(x, y, (UCHAR)TextColor);
377 }
378 else if (BackColor < BV_COLOR_NONE)
379 {
380 /*
381 * This is a background pixel. We're drawing it
382 * unless it's transparent.
383 */
384 SetPixel(x, y, (UCHAR)BackColor);
385 }
386 }
387 }
388}
389
390VOID
391NTAPI
393 _In_ ULONG Left,
394 _In_ ULONG Top,
395 _In_ ULONG Right,
398{
399 while (Top <= Bottom)
400 {
401 PUCHAR Back = BackBuffer + BB_OFFSET(Left, Top);
402 PULONG Frame = (PULONG)(FrameBufferStart + FB_OFFSET(Left, Top));
403 ULONG L = Left;
404
405 while (L++ <= Right)
406 {
407 *Back++ = Color;
408 *Frame++ = CachedPalette[Color];
409 }
410 Top++;
411 }
412}
413
414VOID
415NTAPI
418 _In_ ULONG Left,
419 _In_ ULONG Top,
423{
424 /* Clear the destination buffer */
426
427 /* Start the outer Y height loop */
428 for (ULONG y = 0; y < Height; y++)
429 {
430 /* Set current scanline */
431 PUCHAR Back = BackBuffer + BB_OFFSET(Left, Top + y);
432 PUCHAR Buf = Buffer + y * Delta;
433
434 /* Start the X inner loop */
435 for (ULONG x = 0; x < Width; x += sizeof(USHORT))
436 {
437 /* Read the current value */
438 *Buf = (*Back++ & 0xF) << 4;
439 *Buf |= *Back++ & 0xF;
440 Buf++;
441 }
442 }
443}
unsigned char BOOLEAN
VOID NTAPI DoScroll(_In_ ULONG Scroll)
Definition: bootvid.c:59
VOID NTAPI VidScreenToBufferBlt(_Out_writes_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_ ULONG Delta)
Definition: bootvid.c:257
VOID NTAPI PreserveRow(_In_ ULONG CurrentTop, _In_ ULONG TopDelta, _In_ BOOLEAN Restore)
Definition: bootvid.c:107
VOID NTAPI VidSolidColorFill(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Right, _In_ ULONG Bottom, _In_ UCHAR Color)
Definition: bootvid.c:274
VOID NTAPI InitPaletteWithTable(_In_ PULONG Table, _In_ ULONG Count)
Definition: bootvid.c:170
VOID NTAPI VidCleanUp(VOID)
Definition: bootvid.c:246
VOID NTAPI VidResetDisplay(_In_ BOOLEAN HalReset)
Definition: bootvid.c:220
VOID NTAPI DisplayCharacter(_In_ CHAR Character, _In_ ULONG Left, _In_ ULONG Top, _In_ ULONG TextColor, _In_ ULONG BackColor)
Definition: bootvid.c:13
BOOLEAN NTAPI VidInitialize(_In_ BOOLEAN SetMode)
Definition: bootvid.c:184
FORCEINLINE VOID SetPixel(_In_ ULONG Left, _In_ ULONG Top, _In_ UCHAR Color)
Definition: arm.h:50
#define READ_REGISTER_ULONG(r)
Definition: arm.h:20
#define DPRINT1
Definition: precomp.h:8
static LPHIST_ENTRY Bottom
Definition: history.c:54
static LPHIST_ENTRY Top
Definition: history.c:53
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void cleanup(void)
Definition: main.c:1335
ULONG VidpCurrentY
Definition: common.c:8
ULONG VidpCurrentX
Definition: common.c:7
ULONG VidpScrollRegion[4]
Definition: common.c:10
#define GetFontPtr(_Char)
Definition: precomp.h:74
ULONG RGBQUAD
Definition: precomp.h:50
#define FONT_PTR_DELTA
Definition: precomp.h:75
#define BOOTCHAR_HEIGHT
Definition: precomp.h:27
#define BOOTCHAR_WIDTH
Definition: precomp.h:28
#define InitializePalette()
Definition: precomp.h:68
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ASMGENDATA Table[]
Definition: genincdata.c:61
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID PrepareForSetPixel(VOID)
Definition: bootvid.c:322
ULONG_PTR FrameBuffer
Definition: bootvid.c:15
static UCHAR NvGetCrtc(ULONG Base, UCHAR Index)
Definition: bootvid.c:27
static ULONG PanV
Definition: bootvid.c:19
static UCHAR NvGetBytesPerPixel(ULONG Base, ULONG ScreenWidth)
Definition: bootvid.c:36
static ULONG FrameBufferWidth
Definition: bootvid.c:19
static RGBQUAD CachedPalette[BV_MAX_COLORS]
Definition: bootvid.c:21
static UCHAR BytesPerPixel
Definition: bootvid.c:20
static VOID ApplyPalette(VOID)
Definition: bootvid.c:56
static ULONG FrameBufferHeight
Definition: bootvid.c:19
static ULONG_PTR FrameBufferStart
Definition: bootvid.c:18
static ULONG PanH
Definition: bootvid.c:19
static PUCHAR BackBuffer
Definition: bootvid.c:22
#define NOTHING
Definition: input_list.c:10
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
ULONG FrameBufferSize
Definition: xboxvideo.c:29
#define ASSERT(a)
Definition: mode.c:44
#define _Out_writes_bytes_(size)
Definition: ms_sal.h:350
#define _In_
Definition: ms_sal.h:308
#define HalResetDisplay
Definition: halfuncs.h:45
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2427
int Count
Definition: noreturn.cpp:7
#define L(x)
Definition: ntvdm.h:50
#define FB_OFFSET(x, y)
Definition: pc98.h:17
#define SCREEN_WIDTH
Definition: pc98video.c:27
#define SCREEN_HEIGHT
Definition: pc98video.c:28
static ULONG ScreenWidth
Definition: pcvideo.c:114
unsigned short USHORT
Definition: pedump.c:61
#define BV_COLOR_NONE
Definition: display.h:31
#define BV_COLOR_BLACK
Definition: display.h:15
#define BV_MAX_COLORS
Definition: display.h:32
base of all file and directory entries
Definition: entries.h:83
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ HFONT _Out_ PUINT _Out_ PUINT Width
Definition: font.h:126
_In_ HFONT _Out_ PUINT Height
Definition: font.h:125
_In_ WDFCOLLECTION _In_ ULONG Index
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define BB_OFFSET(x, y)
Definition: xbox.h:15
static ULONG Delta
Definition: xboxvideo.c:33
NTKERNELAPI VOID NTAPI WRITE_REGISTER_UCHAR(IN PUCHAR Register, IN UCHAR Value)
NTKERNELAPI UCHAR NTAPI READ_REGISTER_UCHAR(IN PUCHAR Register)
@ MmNonCached
Definition: mmtypes.h:129
#define NV2A_VIDEO_MEMORY_SIZE
Definition: xgpu.h:16
#define NV2A_CRTC_FRAMEBUFFER_START
Definition: xgpu.h:21
#define NV2A_RAMDAC_FP_VVALID_END
Definition: xgpu.h:26
#define NV2A_CRTC_REGISTER_INDEX
Definition: xgpu.h:22
#define NV2A_CRTC_REGISTER_VALUE
Definition: xgpu.h:23
#define NV2A_RAMDAC_FP_HVALID_END
Definition: xgpu.h:25
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175