https://git.reactos.org/?p=reactos.git;a=commitdiff;h=db1b04340f6661037b1fe…
commit db1b04340f6661037b1fe5175a83597a03517e8e
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Sat Oct 17 00:32:38 2020 +0300
Commit: Stanislav Motylkov <x86corez(a)gmail.com>
CommitDate: Sat Oct 17 19:28:05 2020 +0300
[FREELDR] Use BIOS font and accelerated text drawing on NEC PC-98
Both features are switchable via global variables.
---
boot/freeldr/freeldr/arch/i386/pc98/pc98video.c | 125 ++++++++++++++++++++++++
1 file changed, 125 insertions(+)
diff --git a/boot/freeldr/freeldr/arch/i386/pc98/pc98video.c
b/boot/freeldr/freeldr/arch/i386/pc98/pc98video.c
index 7f038a03870..0d9b3b34423 100644
--- a/boot/freeldr/freeldr/arch/i386/pc98/pc98video.c
+++ b/boot/freeldr/freeldr/arch/i386/pc98/pc98video.c
@@ -28,6 +28,13 @@ UCHAR TextLines;
#define SCREEN_HEIGHT 400
#define BYTES_PER_SCANLINE (SCREEN_WIDTH / 8)
+/* Use BIOS font; set to FALSE for built-in VGA font. */
+static BOOLEAN UseCGFont = TRUE;
+/* Hardware accelerated text drawing; set to FALSE for non-accelerated
+ * self-drawing, which will allow more than 8 colors for text though.
+ * This option is possible only with BIOS fonts enabled. */
+static BOOLEAN CGAccelDraw = TRUE;
+
ULONG VramText;
static ULONG VramPlaneB;
static ULONG VramPlaneG;
@@ -232,6 +239,77 @@ Pc98VideoHideShowTextCursor(BOOLEAN Show)
WRITE_GDC_CSRFORM((PUCHAR)GDC1_IO_o_PARAM, &CursorParameters);
}
+static
+UCHAR
+Pc98VideoAttrToGdcAttr(UCHAR Attr)
+{
+ switch (Attr & 0xF)
+ {
+ case COLOR_BLACK:
+ return GDC_ATTR_BLACK;
+ case COLOR_BLUE:
+ return GDC_ATTR_BLUE;
+ case COLOR_GREEN:
+ case COLOR_LIGHTGREEN:
+ return GDC_ATTR_GREEN;
+ case COLOR_CYAN:
+ case COLOR_GRAY:
+ case COLOR_DARKGRAY:
+ case COLOR_WHITE:
+ return GDC_ATTR_WHITE;
+ case COLOR_RED:
+ case COLOR_LIGHTRED:
+ return GDC_ATTR_RED;
+ case COLOR_MAGENTA:
+ case COLOR_LIGHTMAGENTA:
+ return GDC_ATTR_PURPLE;
+ case COLOR_BROWN:
+ case COLOR_YELLOW:
+ return GDC_ATTR_YELLOW;
+ case COLOR_LIGHTBLUE:
+ case COLOR_LIGHTCYAN:
+ return GDC_ATTR_LIGHTBLUE;
+ default:
+ return GDC_ATTR_BLACK;
+ }
+}
+
+static
+USHORT
+Pc98AsciiToJisX(int Ch)
+{
+ switch (Ch)
+ {
+ /* Only characters required for pseudographic are handled here */
+ case 0x18: return 0x1E;
+ case 0x19: return 0x1F;
+ case 0xB3: return 0x260B;
+ case 0xB6: return 0x4C0B;
+ case 0xBA: return 0x270B;
+ case 0xBB: return 0x370B;
+ case 0xBC: return 0x3F0B;
+ case 0xBF: return 0x340B;
+ case 0xC0: return 0x380B;
+ case 0xC4: return 0x240B;
+ case 0xC7: return 0x440B;
+ case 0xC8: return 0x3B0B;
+ case 0xC9: return 0x330B;
+ case 0xCD: return 0x250B;
+ case 0xD9: return 0x3C0B;
+ case 0xDA: return 0x300B;
+ case 0xDB: return 0x87;
+ default: return Ch;
+ }
+}
+
+static
+VOID
+Pc98VideoTextRamPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
+{
+ *(PUSHORT)(VramText + (X + Y * TextCols) * TEXT_CHAR_SIZE) = Ch;
+ *(PUCHAR)(VramText + VRAM_TEXT_ATTR_OFFSET + (X + Y * TextCols) * TEXT_CHAR_SIZE) =
Pc98VideoAttrToGdcAttr(Attr) | GDC_ATTR_VISIBLE;
+}
+
VOID
Pc98VideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
{
@@ -242,9 +320,46 @@ Pc98VideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
UCHAR I = (Attr & 0x80) ? 0xFF : 0;
ULONG VramOffset = X + (Y * CHAR_HEIGHT) * BYTES_PER_SCANLINE;
PUCHAR FontPtr = BitmapFont8x16 + Ch * 16;
+ BOOLEAN CGFont = UseCGFont && (Ch != LIGHT_FILL && Ch != MEDIUM_FILL
&& Ch != DARK_FILL);
+
+ if (CGFont)
+ {
+ Ch = Pc98AsciiToJisX(Ch);
+
+ if (CGAccelDraw)
+ {
+ Pc98VideoTextRamPutChar(Ch, Attr, X, Y);
+ }
+ else
+ {
+ /* Set needed character code to obtain glyph from CG Window */
+ WRITE_PORT_UCHAR((PUCHAR)KCG_IO_o_CHARCODE_LOW, Ch);
+ WRITE_PORT_UCHAR((PUCHAR)KCG_IO_o_CHARCODE_HIGH, Ch >> 8);
+ }
+ }
+ else if (UseCGFont && CGAccelDraw)
+ {
+ /* Clear character at this place in Text RAM */
+ Pc98VideoTextRamPutChar(' ', Attr, X, Y);
+ }
for (Line = 0; Line < CHAR_HEIGHT; Line++)
{
+ if (CGFont)
+ {
+ if (CGAccelDraw)
+ {
+ /* Character is already displayed by GDC (Text RAM),
+ * so display only background for it. */
+ FontPtr[Line] = 0;
+ }
+ else
+ {
+ /* Obtain glyph data from CG Window */
+ WRITE_PORT_UCHAR((PUCHAR)KCG_IO_o_LINE, Line | 0x20);
+ FontPtr[Line] = READ_PORT_UCHAR((PUCHAR)KCG_IO_i_PATTERN);
+ }
+ }
if (Attr & 0x0F)
{
*(PUCHAR)(VramPlaneB + VramOffset + Line * BYTES_PER_SCANLINE) = B | ((Attr
& 0x01) ? FontPtr[Line] : 0);
@@ -336,4 +451,14 @@ Pc98VideoPrepareForReactOS(VOID)
Int386(0x18, &Regs, &Regs);
Pc98VideoHideShowTextCursor(FALSE);
+
+ if (UseCGFont && CGAccelDraw)
+ {
+ /* Clear the text screen, resetting to default attributes */
+ for (USHORT i = 0; i < VRAM_TEXT_SIZE; i += TEXT_CHAR_SIZE)
+ {
+ *(PUSHORT)(VramText + i) = ' ';
+ *(PUCHAR)(VramText + VRAM_TEXT_ATTR_OFFSET + i) = GDC_ATTR_WHITE |
GDC_ATTR_VISIBLE;
+ }
+ }
}