ReactOS 0.4.16-dev-2104-gb84fa49
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#include <drivers/xbox/xgpu.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* GLOBALS ********************************************************************/
17
18#define BB_OFFSET(x, y) ((y) * SCREEN_WIDTH + (x))
19#define FB_OFFSET(x, y) (((PanV + (y)) * FrameBufferWidth + PanH + (x)) * BytesPerPixel)
20
26
27/* PRIVATE FUNCTIONS *********************************************************/
28
29static UCHAR
31 ULONG Base,
33{
36}
37
38static UCHAR
40 ULONG Base,
42{
43 /* Get BPP directly from NV2A CRTC (magic constants are from Cromwell) */
44 UCHAR BytesPerPixel = 8 * (((NvGetCrtc(Base, 0x19) & 0xE0) << 3) | (NvGetCrtc(Base, 0x13) & 0xFF)) / ScreenWidth;
45
46 if (BytesPerPixel == 4)
47 {
48 ASSERT((NvGetCrtc(Base, 0x28) & 0xF) == BytesPerPixel - 1);
49 }
50 else
51 {
52 ASSERT((NvGetCrtc(Base, 0x28) & 0xF) == BytesPerPixel);
53 }
54
55 return BytesPerPixel;
56}
57
58static VOID
60{
62 ULONG x, y;
63
64 /* Top panning */
65 for (x = 0; x < PanV * FrameBufferWidth; x++)
66 {
67 *Frame++ = CachedPalette[0];
68 }
69
70 /* Left panning */
71 for (y = 0; y < SCREEN_HEIGHT; y++)
72 {
73 Frame = (PULONG)(FrameBufferStart + FB_OFFSET(-(LONG)PanH, y));
74
75 for (x = 0; x < PanH; x++)
76 {
77 *Frame++ = CachedPalette[0];
78 }
79 }
80
81 /* Screen redraw */
82 PUCHAR Back = BackBuffer;
83 for (y = 0; y < SCREEN_HEIGHT; y++)
84 {
85 Frame = (PULONG)(FrameBufferStart + FB_OFFSET(0, y));
86
87 for (x = 0; x < SCREEN_WIDTH; x++)
88 {
89 *Frame++ = CachedPalette[*Back++];
90 }
91 }
92
93 /* Right panning */
94 for (y = 0; y < SCREEN_HEIGHT; y++)
95 {
97
98 for (x = 0; x < PanH; x++)
99 {
100 *Frame++ = CachedPalette[0];
101 }
102 }
103
104 /* Bottom panning */
106 for (x = 0; x < PanV * FrameBufferWidth; x++)
107 {
108 *Frame++ = CachedPalette[0];
109 }
110}
111
112/* PUBLIC FUNCTIONS **********************************************************/
113
115NTAPI
117 _In_ BOOLEAN SetMode)
118{
120
121 /* FIXME: Add platform check */
122 /* 1. Access PCI device 1:0:0 */
123 /* 2. Check if device ID is 10DE:02A0 */
124
125 /* FIXME: Get device MMIO ranges from PCI */
126 PHYSICAL_ADDRESS PhysControlStart = {.QuadPart = 0xFD000000};
127 PHYSICAL_ADDRESS PhysFrameBufferStart = {.QuadPart = 0xF0000000};
128 ULONG ControlLength = 16 * 1024 * 1024;
129
130 ULONG_PTR ControlStart = (ULONG_PTR)MmMapIoSpace(PhysControlStart, ControlLength, MmNonCached);
131 if (!ControlStart)
132 {
133 DPRINT1("Out of memory!\n");
134 return FALSE;
135 }
136
140
141 FrameBuffer &= 0x0FFFFFFF;
142 if (FrameBuffer != 0x3C00000 && FrameBuffer != 0x7C00000)
143 {
144 /* Check framebuffer address (high 4 MB of either 64 or 128 MB RAM) */
145 DPRINT1("Non-standard framebuffer address 0x%p\n", FrameBuffer);
146 }
147 /* Verify that framebuffer address is page-aligned */
149
151 {
152 DPRINT1("Unsupported screen resolution!\n");
153 goto cleanup;
154 }
155
157 ASSERT(BytesPerPixel >= 1 && BytesPerPixel <= 4);
158
159 if (BytesPerPixel != 4)
160 {
161 DPRINT1("Unsupported BytesPerPixel = %d\n", BytesPerPixel);
162 goto cleanup;
163 }
164
165 /* Calculate panning values */
168
169 /* Verify that screen fits framebuffer size */
171
172 /* FIXME: obtain fb size from firmware somehow (Cromwell reserves high 4 MB of RAM) */
174 {
175 DPRINT1("Current screen resolution exceeds video memory bounds!\n");
176 goto cleanup;
177 }
178
179 /*
180 * Reserve off-screen area for the backbuffer that contains 8-bit indexed
181 * color screen image, plus preserved row data.
182 */
183 ULONG BackBufferSize = SCREEN_WIDTH * (SCREEN_HEIGHT + BOOTCHAR_HEIGHT + 1);
184
185 /* Make sure there is enough video memory for backbuffer */
186 if (NV2A_VIDEO_MEMORY_SIZE - FrameBufferSize < BackBufferSize)
187 {
188 DPRINT1("Out of memory!\n");
189 goto cleanup;
190 }
191
192 /* Return the address back to GPU memory mapped I/O */
193 PhysFrameBufferStart.QuadPart += FrameBuffer;
195 if (!FrameBufferStart)
196 {
197 DPRINT1("Out of memory!\n");
198 goto cleanup;
199 }
200
201 Result = TRUE;
202
203 /* Place backbuffer in the hidden part of framebuffer */
205
206 /* Check whether we have to set the video mode */
207 if (SetMode)
209
210cleanup:
211 if (ControlStart)
212 MmUnmapIoSpace((PVOID)ControlStart, ControlLength);
213
214 /* Video is ready */
215 return Result;
216}
217
218VOID
219NTAPI
221{
222 /* Just fill the screen black */
224}
225
226VOID
228 _In_ BOOLEAN SetMode)
229{
230 /* Reset the video mode with HAL if requested */
231 if (SetMode)
233
234 /* Re-initialize the palette and fill the screen black */
238}
239
240VOID
242 _In_reads_(Count) const ULONG* Table,
244{
245 const ULONG* Entry = Table;
246
247 for (ULONG i = 0; i < Count; i++, Entry++)
248 {
249 CachedPalette[i] = *Entry | 0xFF000000;
250 }
251 ApplyPalette();
252}
253
254VOID
256 _In_ ULONG Left,
257 _In_ ULONG Top,
259{
260 PUCHAR Back = BackBuffer + BB_OFFSET(Left, Top);
261 PULONG Frame = (PULONG)(FrameBufferStart + FB_OFFSET(Left, Top));
262
263 *Back = Color;
264 *Frame = CachedPalette[Color];
265}
266
267VOID
269 _In_ ULONG CurrentTop,
270 _In_ ULONG TopDelta,
271 _In_ BOOLEAN Restore)
272{
273 PUCHAR NewPosition, OldPosition;
274
275 /* Calculate the position in memory for the row */
276 if (Restore)
277 {
278 /* Restore the row by copying back the contents saved off-screen */
279 NewPosition = BackBuffer + BB_OFFSET(0, CurrentTop);
280 OldPosition = BackBuffer + BB_OFFSET(0, SCREEN_HEIGHT);
281 }
282 else
283 {
284 /* Preserve the row by saving its contents off-screen */
285 NewPosition = BackBuffer + BB_OFFSET(0, SCREEN_HEIGHT);
286 OldPosition = BackBuffer + BB_OFFSET(0, CurrentTop);
287 }
288
289 /* Set the count and loop every pixel of backbuffer */
290 ULONG Count = TopDelta * SCREEN_WIDTH;
291
292 RtlCopyMemory(NewPosition, OldPosition, Count);
293
294 if (Restore)
295 {
296 NewPosition = BackBuffer + BB_OFFSET(0, CurrentTop);
297
298 /* Set the count and loop every pixel of framebuffer */
299 for (ULONG y = 0; y < TopDelta; y++)
300 {
301 PULONG Frame = (PULONG)(FrameBufferStart + FB_OFFSET(0, CurrentTop + y));
302
304 while (Count--)
305 {
306 *Frame++ = CachedPalette[*NewPosition++];
307 }
308 }
309 }
310}
311
312VOID
314 _In_ ULONG Scroll)
315{
317
318 /* Calculate the position in memory for the row */
321
322 /* Start loop */
324 {
325 ULONG i;
326
327 /* Scroll the row */
328 RtlCopyMemory(NewPosition, OldPosition, RowSize);
329
331
332 for (i = 0; i < RowSize; ++i)
333 Frame[i] = CachedPalette[NewPosition[i]];
334
335 OldPosition += SCREEN_WIDTH;
336 NewPosition += SCREEN_WIDTH;
337 }
338}
339
340VOID
342 _In_ CHAR Character,
343 _In_ ULONG Left,
344 _In_ ULONG Top,
345 _In_ ULONG TextColor,
346 _In_ ULONG BackColor)
347{
348 /* Get the font and pixel pointer */
349 const UCHAR* FontChar = GetFontPtr(Character);
350
351 /* Loop each pixel height */
352 for (ULONG y = Top; y < Top + BOOTCHAR_HEIGHT; y++, FontChar += FONT_PTR_DELTA)
353 {
354 /* Loop each pixel width */
355 ULONG x = Left;
356
357 for (UCHAR bit = 1 << (BOOTCHAR_WIDTH - 1); bit > 0; bit >>= 1, x++)
358 {
359 /* Check if we should draw this pixel */
360 if (*FontChar & bit)
361 {
362 /* We do, use the given Text Color */
363 SetPixel(x, y, (UCHAR)TextColor);
364 }
365 else if (BackColor < BV_COLOR_NONE)
366 {
367 /*
368 * This is a background pixel. We're drawing it
369 * unless it's transparent.
370 */
371 SetPixel(x, y, (UCHAR)BackColor);
372 }
373 }
374 }
375}
376
377VOID
378NTAPI
380 _In_ ULONG Left,
381 _In_ ULONG Top,
382 _In_ ULONG Right,
385{
386 while (Top <= Bottom)
387 {
388 PUCHAR Back = BackBuffer + BB_OFFSET(Left, Top);
389 PULONG Frame = (PULONG)(FrameBufferStart + FB_OFFSET(Left, Top));
390 ULONG L = Left;
391
392 while (L++ <= Right)
393 {
394 *Back++ = Color;
395 *Frame++ = CachedPalette[Color];
396 }
397 Top++;
398 }
399}
400
401VOID
402NTAPI
405 _In_ ULONG Left,
406 _In_ ULONG Top,
409 _In_ ULONG Delta)
410{
411 /* Clear the destination buffer */
412 RtlZeroMemory(Buffer, Delta * Height);
413
414 /* Start the outer Y height loop */
415 for (ULONG y = 0; y < Height; y++)
416 {
417 /* Set current scanline */
418 PUCHAR Back = BackBuffer + BB_OFFSET(Left, Top + y);
419 PUCHAR Buf = Buffer + y * Delta;
420
421 /* Start the X inner loop */
422 for (ULONG x = 0; x < Width; x += sizeof(USHORT))
423 {
424 /* Read the current value */
425 *Buf = (*Back++ & 0xF) << 4;
426 *Buf |= *Back++ & 0xF;
427 Buf++;
428 }
429 }
430}
unsigned char BOOLEAN
VOID NTAPI VidScreenToBufferBlt(_Out_writes_bytes_all_(Delta *Height) PUCHAR Buffer, _In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_ ULONG Delta)
Definition: bootvid.c:284
VOID PreserveRow(_In_ ULONG CurrentTop, _In_ ULONG TopDelta, _In_ BOOLEAN Restore)
Definition: bootvid.c:159
VOID NTAPI VidSolidColorFill(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Right, _In_ ULONG Bottom, _In_ UCHAR Color)
Definition: bootvid.c:298
VOID NTAPI VidCleanUp(VOID)
Definition: bootvid.c:276
VOID ResetDisplay(_In_ BOOLEAN SetMode)
Definition: bootvid.c:263
FORCEINLINE VOID SetPixel(_In_ ULONG Left, _In_ ULONG Top, _In_ UCHAR Color)
Definition: bootvid.c:52
VOID InitPaletteWithTable(_In_reads_(Count) const ULONG *Table, _In_ ULONG Count)
Definition: bootvid.c:220
VOID DisplayCharacter(_In_ CHAR Character, _In_ ULONG Left, _In_ ULONG Top, _In_ ULONG TextColor, _In_ ULONG BackColor)
Definition: bootvid.c:67
VOID DoScroll(_In_ ULONG Scroll)
Definition: bootvid.c:112
BOOLEAN NTAPI VidInitialize(_In_ BOOLEAN SetMode)
Definition: bootvid.c:231
#define READ_REGISTER_ULONG(r)
Definition: arm.h:10
#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
VOID NTAPI VidResetDisplay(_In_ BOOLEAN SetMode)
Definition: console.c:25
URECT VidpScrollRegion
Definition: console.c:17
#define GetFontPtr(_Char)
Definition: precomp.h:90
ULONG RGBQUAD
Definition: precomp.h:58
#define FONT_PTR_DELTA
Definition: precomp.h:91
#define BOOTCHAR_HEIGHT
Definition: precomp.h:35
#define BOOTCHAR_WIDTH
Definition: precomp.h:36
#define InitializePalette()
Definition: precomp.h:84
#define L(x)
Definition: resources.c:13
#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
ULONG_PTR FrameBuffer
Definition: bootvid.c:20
static UCHAR NvGetCrtc(ULONG Base, UCHAR Index)
Definition: bootvid.c:30
static ULONG PanV
Definition: bootvid.c:22
static UCHAR NvGetBytesPerPixel(ULONG Base, ULONG ScreenWidth)
Definition: bootvid.c:39
static ULONG FrameBufferWidth
Definition: bootvid.c:22
static RGBQUAD CachedPalette[BV_MAX_COLORS]
Definition: bootvid.c:24
static UCHAR BytesPerPixel
Definition: bootvid.c:23
static VOID ApplyPalette(VOID)
Definition: bootvid.c:59
static ULONG FrameBufferHeight
Definition: bootvid.c:22
static ULONG_PTR FrameBufferStart
Definition: bootvid.c:21
static ULONG PanH
Definition: bootvid.c:22
static PUCHAR BackBuffer
Definition: bootvid.c:25
#define BB_OFFSET(x, y)
Definition: bootvid.c:18
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:30
#define ASSERT(a)
Definition: mode.c:44
#define HalResetDisplay
Definition: halfuncs.h:45
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_all_(s)
Definition: no_sal2.h:194
int Count
Definition: noreturn.cpp:7
#define FB_OFFSET(x, y)
Definition: pc98.h:12
#define SCREEN_WIDTH
Definition: pc98video.c:24
#define SCREEN_HEIGHT
Definition: pc98video.c:25
static ULONG ScreenWidth
Definition: pcvideo.c:116
long LONG
Definition: pedump.c:60
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
ULONG Right
Definition: precomp.h:64
ULONG Top
Definition: precomp.h:63
ULONG Bottom
Definition: precomp.h:65
ULONG Left
Definition: precomp.h:62
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:89
_In_ HFONT _Out_ PUINT Height
Definition: font.h:88
_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:409
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