Skip to content

Commit d1445c8

Browse files
committed
[FREELDR:XBOX/UEFI] Unify the XBOX and UEFI linear framebuffer support together (reactos#8509)
CORE-11954, CORE-16216 Here only moving and adjusting existing code has been done. In the future, this code will be expanded to support other bits-per-pixel formats and pixel bitmasks, available in UEFI platforms, and be used to handle bios-based PC VESA framebuffer.
1 parent 9e64fa8 commit d1445c8

File tree

9 files changed

+490
-298
lines changed

9 files changed

+490
-298
lines changed

boot/freeldr/freeldr/arch/i386/xbox/machxbox.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,13 @@ DBG_DEFAULT_CHANNEL(HWDETECT);
2424

2525
#define MAX_XBOX_COM_PORTS 2
2626

27-
extern PVOID FrameBuffer;
27+
extern ULONG_PTR FrameBuffer;
2828
extern ULONG FrameBufferSize;
2929

3030
BOOLEAN
3131
XboxFindPciBios(PPCI_REGISTRY_INFO BusData)
3232
{
3333
/* We emulate PCI BIOS here, there are 2 known working PCI buses on an original Xbox */
34-
3534
BusData->NoBuses = 2;
3635
BusData->MajorRevision = 1;
3736
BusData->MinorRevision = 0;
@@ -181,7 +180,7 @@ DetectDisplayController(PCONFIGURATION_COMPONENT_DATA BusKey)
181180
PartialDescriptor->Type = CmResourceTypeMemory;
182181
PartialDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
183182
PartialDescriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
184-
PartialDescriptor->u.Memory.Start.LowPart = (ULONG_PTR)FrameBuffer & 0x0FFFFFFF;
183+
PartialDescriptor->u.Memory.Start.LowPart = (FrameBuffer & 0x0FFFFFFF);
185184
PartialDescriptor->u.Memory.Length = FrameBufferSize;
186185

187186
FldrCreateComponentKey(BusKey,

boot/freeldr/freeldr/arch/i386/xbox/xboxmem.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@
2020
*/
2121

2222
#include <freeldr.h>
23-
#include <debug.h>
2423

24+
#include <debug.h>
2525
DBG_DEFAULT_CHANNEL(MEMORY);
2626

2727
static ULONG InstalledMemoryMb = 0;
2828
static ULONG AvailableMemoryMb = 0;
2929
extern multiboot_info_t * MultibootInfoPtr;
3030
extern ULONG NvBase;
31-
extern PVOID FrameBuffer;
31+
extern ULONG_PTR FrameBuffer;
3232
extern ULONG FrameBufferSize;
3333

3434
#define TEST_SIZE 0x200
@@ -267,7 +267,7 @@ XboxMemGetMemoryMap(ULONG *MemoryMapSize)
267267
{
268268
/* Video memory */
269269
ReserveMemory(XboxMemoryMap,
270-
(ULONG_PTR)FrameBuffer,
270+
FrameBuffer,
271271
FrameBufferSize,
272272
LoaderFirmwarePermanent,
273273
"Video memory");

boot/freeldr/freeldr/arch/i386/xbox/xboxvideo.c

Lines changed: 64 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -20,148 +20,58 @@
2020
*/
2121

2222
#include <freeldr.h>
23-
#include "../../vgafont.h"
23+
#include "../../vidfb.h"
2424

2525
#include <debug.h>
2626
DBG_DEFAULT_CHANNEL(UI);
2727

2828
ULONG NvBase = 0xFD000000;
29-
PVOID FrameBuffer;
29+
ULONG_PTR FrameBuffer;
3030
ULONG FrameBufferSize;
31-
static ULONG ScreenWidth;
32-
static ULONG ScreenHeight;
33-
static ULONG BytesPerPixel;
34-
static ULONG Delta;
3531
extern multiboot_info_t * MultibootInfoPtr;
32+
#define FB_SIZE_MB 4
3633

3734
UCHAR MachDefaultTextColor = COLOR_GRAY;
3835

39-
#define TOP_BOTTOM_LINES 0
40-
41-
#define FB_SIZE_MB 4
42-
4336
#define MAKE_COLOR(Red, Green, Blue) (0xff000000 | (((Red) & 0xff) << 16) | (((Green) & 0xff) << 8) | ((Blue) & 0xff))
4437

45-
static VOID
46-
XboxVideoOutputChar(UCHAR Char, unsigned X, unsigned Y, ULONG FgColor, ULONG BgColor)
47-
{
48-
const UCHAR* FontPtr;
49-
PULONG Pixel;
50-
UCHAR Mask;
51-
unsigned Line;
52-
unsigned Col;
53-
54-
FontPtr = BitmapFont8x16 + Char * CHAR_HEIGHT;
55-
Pixel = (PULONG) ((char *) FrameBuffer + (Y * CHAR_HEIGHT + TOP_BOTTOM_LINES) * Delta
56-
+ X * CHAR_WIDTH * BytesPerPixel);
57-
for (Line = 0; Line < CHAR_HEIGHT; Line++)
58-
{
59-
Mask = 0x80;
60-
for (Col = 0; Col < CHAR_WIDTH; Col++)
61-
{
62-
Pixel[Col] = (0 != (FontPtr[Line] & Mask) ? FgColor : BgColor);
63-
Mask = Mask >> 1;
64-
}
65-
Pixel = (PULONG) ((char *) Pixel + Delta);
66-
}
67-
}
68-
69-
static ULONG
70-
XboxVideoAttrToSingleColor(UCHAR Attr)
71-
{
72-
UCHAR Intensity;
73-
74-
Intensity = (0 == (Attr & 0x08) ? 127 : 255);
75-
76-
return 0xff000000 |
77-
(0 == (Attr & 0x04) ? 0 : (Intensity << 16)) |
78-
(0 == (Attr & 0x02) ? 0 : (Intensity << 8)) |
79-
(0 == (Attr & 0x01) ? 0 : Intensity);
80-
}
81-
82-
static VOID
83-
XboxVideoAttrToColors(UCHAR Attr, ULONG *FgColor, ULONG *BgColor)
84-
{
85-
*FgColor = XboxVideoAttrToSingleColor(Attr & 0xf);
86-
*BgColor = XboxVideoAttrToSingleColor((Attr >> 4) & 0xf);
87-
}
88-
89-
static VOID
90-
XboxVideoClearScreenColor(ULONG Color, BOOLEAN FullScreen)
91-
{
92-
ULONG Line, Col;
93-
PULONG p;
94-
95-
for (Line = 0; Line < ScreenHeight - (FullScreen ? 0 : 2 * TOP_BOTTOM_LINES); Line++)
96-
{
97-
p = (PULONG) ((char *) FrameBuffer + (Line + (FullScreen ? 0 : TOP_BOTTOM_LINES)) * Delta);
98-
for (Col = 0; Col < ScreenWidth; Col++)
99-
{
100-
*p++ = Color;
101-
}
102-
}
103-
}
104-
10538
VOID
10639
XboxVideoScrollUp(VOID)
10740
{
108-
ULONG BgColor, Dummy;
109-
ULONG PixelCount = ScreenWidth * CHAR_HEIGHT *
110-
(((ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT) - 1);
111-
PULONG Src = (PULONG)((PUCHAR)FrameBuffer + (CHAR_HEIGHT + TOP_BOTTOM_LINES) * Delta);
112-
PULONG Dst = (PULONG)((PUCHAR)FrameBuffer + TOP_BOTTOM_LINES * Delta);
113-
114-
XboxVideoAttrToColors(ATTR(COLOR_WHITE, COLOR_BLACK), &Dummy, &BgColor);
115-
116-
while (PixelCount--)
117-
*Dst++ = *Src++;
118-
119-
for (PixelCount = 0; PixelCount < ScreenWidth * CHAR_HEIGHT; PixelCount++)
120-
*Dst++ = BgColor;
41+
VidFbScrollUp();
12142
}
12243

12344
VOID
12445
XboxVideoClearScreen(UCHAR Attr)
12546
{
126-
ULONG FgColor, BgColor;
127-
128-
XboxVideoAttrToColors(Attr, &FgColor, &BgColor);
129-
130-
XboxVideoClearScreenColor(BgColor, FALSE);
47+
VidFbClearScreen(Attr);
13148
}
13249

13350
VOID
13451
XboxVideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
13552
{
136-
ULONG FgColor, BgColor;
137-
138-
XboxVideoAttrToColors(Attr, &FgColor, &BgColor);
139-
140-
XboxVideoOutputChar(Ch, X, Y, FgColor, BgColor);
53+
VidFbPutChar(Ch, Attr, X, Y);
14154
}
14255

143-
UCHAR
56+
static UCHAR
14457
NvGetCrtc(UCHAR Index)
14558
{
14659
WRITE_REGISTER_UCHAR(NvBase + NV2A_CRTC_REGISTER_INDEX, Index);
14760
return READ_REGISTER_UCHAR(NvBase + NV2A_CRTC_REGISTER_VALUE);
14861
}
14962

150-
ULONG
151-
XboxGetFramebufferSize(PVOID Offset)
63+
static ULONG
64+
XboxGetFramebufferSize(
65+
_In_ ULONG_PTR Offset)
15266
{
15367
memory_map_t * MemoryMap;
15468
INT Count, i;
15569

15670
if (!MultibootInfoPtr)
157-
{
15871
return 0;
159-
}
16072

16173
if (!(MultibootInfoPtr->flags & MB_INFO_FLAG_MEMORY_MAP))
162-
{
16374
return 0;
164-
}
16575

16676
MemoryMap = (memory_map_t *)MultibootInfoPtr->mmap_addr;
16777

@@ -180,7 +90,7 @@ XboxGetFramebufferSize(PVOID Offset)
18090
/* Framebuffer address offset value is coming from the GPU within
18191
* memory mapped I/O address space, so we're comparing only low
18292
* 28 bits of the address within actual RAM address space */
183-
if (MemoryMap->base_addr_low == ((ULONG)Offset & 0x0FFFFFFF) && MemoryMap->base_addr_high == 0)
93+
if (MemoryMap->base_addr_low == (Offset & 0x0FFFFFFF) && MemoryMap->base_addr_high == 0)
18494
{
18595
TRACE("Video memory found\n");
18696
return MemoryMap->length_low;
@@ -193,62 +103,67 @@ XboxGetFramebufferSize(PVOID Offset)
193103
VOID
194104
XboxVideoInit(VOID)
195105
{
196-
/* Reuse framebuffer that was set up by firmware */
197-
FrameBuffer = (PVOID)READ_REGISTER_ULONG(NvBase + NV2A_CRTC_FRAMEBUFFER_START);
198-
/* Verify that framebuffer address is page-aligned */
199-
ASSERT((ULONG_PTR)FrameBuffer % PAGE_SIZE == 0);
200-
201-
/* Obtain framebuffer memory size from multiboot memory map */
202-
if ((FrameBufferSize = XboxGetFramebufferSize(FrameBuffer)) == 0)
203-
{
204-
/* Fallback to Cromwell standard which reserves high 4 MB of RAM */
205-
FrameBufferSize = 4 * 1024 * 1024;
206-
WARN("Could not detect framebuffer memory size, fallback to 4 MB\n");
207-
}
208-
209-
ScreenWidth = READ_REGISTER_ULONG(NvBase + NV2A_RAMDAC_FP_HVALID_END) + 1;
210-
ScreenHeight = READ_REGISTER_ULONG(NvBase + NV2A_RAMDAC_FP_VVALID_END) + 1;
211-
/* Get BPP directly from NV2A CRTC (magic constants are from Cromwell) */
212-
BytesPerPixel = 8 * (((NvGetCrtc(0x19) & 0xE0) << 3) | (NvGetCrtc(0x13) & 0xFF)) / ScreenWidth;
213-
if (BytesPerPixel == 4)
214-
{
215-
ASSERT((NvGetCrtc(0x28) & 0xF) == BytesPerPixel - 1);
216-
}
217-
else
218-
{
219-
ASSERT((NvGetCrtc(0x28) & 0xF) == BytesPerPixel);
220-
}
221-
Delta = (ScreenWidth * BytesPerPixel + 3) & ~ 0x3;
222-
223-
/* Verify screen resolution */
224-
ASSERT(ScreenWidth > 1);
225-
ASSERT(ScreenHeight > 1);
226-
ASSERT(BytesPerPixel >= 1 && BytesPerPixel <= 4);
227-
/* Verify that screen fits framebuffer size */
228-
ASSERT(ScreenWidth * ScreenHeight * BytesPerPixel <= FrameBufferSize);
229-
230-
XboxVideoClearScreenColor(MAKE_COLOR(0, 0, 0), TRUE);
106+
ULONG ScreenWidth;
107+
ULONG ScreenHeight;
108+
ULONG BytesPerPixel;
109+
110+
/* Reuse framebuffer that was set up by firmware */
111+
FrameBuffer = (ULONG_PTR)READ_REGISTER_ULONG(NvBase + NV2A_CRTC_FRAMEBUFFER_START);
112+
/* Verify that framebuffer address is page-aligned */
113+
ASSERT(FrameBuffer % PAGE_SIZE == 0);
114+
115+
/* Obtain framebuffer memory size from multiboot memory map */
116+
if ((FrameBufferSize = XboxGetFramebufferSize(FrameBuffer)) == 0)
117+
{
118+
/* Fallback to Cromwell standard which reserves high 4 MB of RAM */
119+
FrameBufferSize = 4 * 1024 * 1024;
120+
WARN("Could not detect framebuffer memory size, fallback to 4 MB\n");
121+
}
122+
123+
ScreenWidth = READ_REGISTER_ULONG(NvBase + NV2A_RAMDAC_FP_HVALID_END) + 1;
124+
ScreenHeight = READ_REGISTER_ULONG(NvBase + NV2A_RAMDAC_FP_VVALID_END) + 1;
125+
126+
/* Get BPP directly from NV2A CRTC (magic constants are from Cromwell) */
127+
BytesPerPixel = 8 * (((NvGetCrtc(0x19) & 0xE0) << 3) | (NvGetCrtc(0x13) & 0xFF)) / ScreenWidth;
128+
if (BytesPerPixel == 4)
129+
ASSERT((NvGetCrtc(0x28) & 0xF) == BytesPerPixel - 1);
130+
else
131+
ASSERT((NvGetCrtc(0x28) & 0xF) == BytesPerPixel);
132+
133+
/* Verify screen resolution */
134+
ASSERT(ScreenWidth > 1);
135+
ASSERT(ScreenHeight > 1);
136+
ASSERT(BytesPerPixel >= 1 && BytesPerPixel <= 4);
137+
/* Verify that screen fits framebuffer size */
138+
ASSERT(ScreenWidth * ScreenHeight * BytesPerPixel <= FrameBufferSize);
139+
140+
VidFbInitializeVideo(FrameBuffer,
141+
FrameBufferSize,
142+
ScreenWidth,
143+
ScreenHeight,
144+
ScreenWidth, // PixelsPerScanLine
145+
BytesPerPixel * 8);
146+
147+
VidFbClearScreenColor(MAKE_COLOR(0, 0, 0), TRUE);
231148
}
232149

233150
VIDEODISPLAYMODE
234151
XboxVideoSetDisplayMode(PCSTR DisplayMode, BOOLEAN Init)
235152
{
236-
/* We only have one mode, semi-text */
237-
return VideoTextMode;
153+
/* We only have one mode, semi-text */
154+
return VideoTextMode;
238155
}
239156

240157
VOID
241158
XboxVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth)
242159
{
243-
*Width = ScreenWidth / CHAR_WIDTH;
244-
*Height = (ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT;
245-
*Depth = 0;
160+
VidFbGetDisplaySize(Width, Height, Depth);
246161
}
247162

248163
ULONG
249164
XboxVideoGetBufferSize(VOID)
250165
{
251-
return (ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT * (ScreenWidth / CHAR_WIDTH) * 2;
166+
return VidFbGetBufferSize();
252167
}
253168

254169
VOID
@@ -260,47 +175,37 @@ XboxVideoGetFontsFromFirmware(PULONG RomFontPointers)
260175
VOID
261176
XboxVideoSetTextCursorPosition(UCHAR X, UCHAR Y)
262177
{
263-
/* We don't have a cursor yet */
178+
/* We don't have a cursor yet */
264179
}
265180

266181
VOID
267182
XboxVideoHideShowTextCursor(BOOLEAN Show)
268183
{
269-
/* We don't have a cursor yet */
184+
/* We don't have a cursor yet */
270185
}
271186

272187
VOID
273188
XboxVideoCopyOffScreenBufferToVRAM(PVOID Buffer)
274189
{
275-
PUCHAR OffScreenBuffer = (PUCHAR) Buffer;
276-
ULONG Col, Line;
277-
278-
for (Line = 0; Line < (ScreenHeight - 2 * TOP_BOTTOM_LINES) / CHAR_HEIGHT; Line++)
279-
{
280-
for (Col = 0; Col < ScreenWidth / CHAR_WIDTH; Col++)
281-
{
282-
XboxVideoPutChar(OffScreenBuffer[0], OffScreenBuffer[1], Col, Line);
283-
OffScreenBuffer += 2;
284-
}
285-
}
190+
VidFbCopyOffScreenBufferToVRAM(Buffer);
286191
}
287192

288193
BOOLEAN
289194
XboxVideoIsPaletteFixed(VOID)
290195
{
291-
return FALSE;
196+
return FALSE;
292197
}
293198

294199
VOID
295200
XboxVideoSetPaletteColor(UCHAR Color, UCHAR Red, UCHAR Green, UCHAR Blue)
296201
{
297-
/* Not supported */
202+
/* Not supported */
298203
}
299204

300205
VOID
301206
XboxVideoGetPaletteColor(UCHAR Color, UCHAR* Red, UCHAR* Green, UCHAR* Blue)
302207
{
303-
/* Not supported */
208+
/* Not supported */
304209
}
305210

306211
VOID
@@ -312,7 +217,7 @@ XboxVideoSync(VOID)
312217
VOID
313218
XboxVideoPrepareForReactOS(VOID)
314219
{
315-
XboxVideoClearScreenColor(MAKE_COLOR(0, 0, 0), TRUE);
220+
VidFbClearScreenColor(MAKE_COLOR(0, 0, 0), TRUE);
316221
XboxVideoHideShowTextCursor(FALSE);
317222
}
318223

0 commit comments

Comments
 (0)