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