diff --git a/drivers/base/bootvid/CMakeLists.txt b/drivers/base/bootvid/CMakeLists.txt index 10052eb2128..033a37c53ef 100644 --- a/drivers/base/bootvid/CMakeLists.txt +++ b/drivers/base/bootvid/CMakeLists.txt @@ -2,10 +2,15 @@ spec2def(bootvid.dll bootvid.spec ADD_IMPORTLIB) if((ARCH STREQUAL "i386") OR (ARCH STREQUAL "amd64")) - list(APPEND SOURCE - i386/pc/bootvid.c - i386/pc/bootdata.c - i386/pc/vga.c) + if(SARCH STREQUAL "pc98") + list(APPEND SOURCE + i386/pc98/bootvid.c) + else() + list(APPEND SOURCE + i386/pc/bootvid.c + i386/pc/bootdata.c + i386/pc/vga.c) + endif() elseif(ARCH STREQUAL "arm") list(APPEND SOURCE arm/bootvid.c) diff --git a/drivers/base/bootvid/bootvid.rc b/drivers/base/bootvid/bootvid.rc index 34ea5309796..18d91d14650 100644 --- a/drivers/base/bootvid/bootvid.rc +++ b/drivers/base/bootvid/bootvid.rc @@ -1,5 +1,11 @@ #define REACTOS_VERSION_DLL + +#if defined(SARCH_PC98) +#define REACTOS_STR_FILE_DESCRIPTION "NEC PC-98 Boot Video Driver" +#else #define REACTOS_STR_FILE_DESCRIPTION "VGA Boot Driver" +#endif + #define REACTOS_STR_INTERNAL_NAME "bootvid.dll" #define REACTOS_STR_ORIGINAL_FILENAME "bootvid.dll" #include diff --git a/drivers/base/bootvid/i386/pc98/bootvid.c b/drivers/base/bootvid/i386/pc98/bootvid.c new file mode 100644 index 00000000000..e4b8b1b834b --- /dev/null +++ b/drivers/base/bootvid/i386/pc98/bootvid.c @@ -0,0 +1,469 @@ +/* + * PROJECT: ReactOS Boot Video Driver for NEC PC-98 series + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Main file + * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#include "precomp.h" + +/* GLOBALS ********************************************************************/ + +static ULONG_PTR VideoMemoryI; +ULONG_PTR FrameBuffer; + +#define PEGC_MAX_COLORS 256 + +/* PRIVATE FUNCTIONS **********************************************************/ + +static BOOLEAN +GraphGetStatus( + _In_ UCHAR Status) +{ + UCHAR Result; + + WRITE_PORT_UCHAR((PUCHAR)GRAPH_IO_o_STATUS_SELECT, Status); + KeStallExecutionProcessor(1); + Result = READ_PORT_UCHAR((PUCHAR)GRAPH_IO_i_STATUS); + + return (Result & GRAPH_STATUS_SET) && (Result != 0xFF); +} + +static BOOLEAN +HasPegcController(VOID) +{ + BOOLEAN Success; + + if (GraphGetStatus(GRAPH_STATUS_PEGC)) + return TRUE; + + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_EGC_FF_UNPROTECT); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_PEGC_ENABLE); + Success = GraphGetStatus(GRAPH_STATUS_PEGC); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_PEGC_DISABLE); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_EGC_FF_PROTECT); + + return Success; +} + +static VOID +TextSync(VOID) +{ + while (READ_PORT_UCHAR((PUCHAR)GDC1_IO_i_STATUS) & GDC_STATUS_VSYNC) + NOTHING; + + while (!(READ_PORT_UCHAR((PUCHAR)GDC1_IO_i_STATUS) & GDC_STATUS_VSYNC)) + NOTHING; +} + +static VOID +InitializeDisplay(VOID) +{ + SYNCPARAM SyncParameters; + CSRFORMPARAM CursorParameters; + CSRWPARAM CursorPosition; + PITCHPARAM PitchParameters; + PRAMPARAM RamParameters; + ZOOMPARAM ZoomParameters; + UCHAR RelayState; + + /* RESET, without FIFO check */ + WRITE_PORT_UCHAR((PUCHAR)GDC1_IO_o_COMMAND, GDC_COMMAND_RESET1); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_COMMAND, GDC_COMMAND_RESET1); + + /* Configure chipset */ + WRITE_PORT_UCHAR((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GRAPH_MODE_COLORED); + WRITE_PORT_UCHAR((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GDC2_MODE_ODD_RLINE_SHOW); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_COLORS_16); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_GRCG); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_LCD); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_LINES_400); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_CLOCK1_5MHZ); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_CLOCK2_5MHZ); + WRITE_PORT_UCHAR((PUCHAR)GRAPH_IO_o_HORIZONTAL_SCAN_RATE, GRAPH_HF_31KHZ); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_VIDEO_PAGE, 0); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_VIDEO_PAGE_ACCESS, 0); + + /* =========================== MASTER ============================ */ + + /* MASTER */ + WRITE_GDC1_COMMAND(GDC_COMMAND_MASTER); + + /* SYNC */ + SyncParameters.Flags = SYNC_DISPLAY_MODE_GRAPHICS_AND_CHARACTERS | SYNC_VIDEO_FRAMING_NONINTERLACED | + SYNC_DRAW_ONLY_DURING_RETRACE_BLANKING | SYNC_STATIC_RAM_NO_REFRESH; + SyncParameters.ScreenWidthChars = 80; + SyncParameters.HorizontalSyncWidth = 12; + SyncParameters.VerticalSyncWidth = 2; + SyncParameters.HorizontalFrontPorchWidth = 4; + SyncParameters.HorizontalBackPorchWidth = 4; + SyncParameters.VerticalFrontPorchWidth = 6; + SyncParameters.ScreenWidthLines = 480; + SyncParameters.VerticalBackPorchWidth = 37; + WRITE_GDC1_COMMAND(GDC_COMMAND_SYNC_ON); + WRITE_GDC_SYNC((PUCHAR)GDC1_IO_o_PARAM, &SyncParameters); + + /* CSRFORM */ + CursorParameters.Show = FALSE; + CursorParameters.Blink = FALSE; + CursorParameters.BlinkRate = 12; + CursorParameters.LinesPerRow = 16; + CursorParameters.StartScanLine = 0; + CursorParameters.EndScanLine = 15; + WRITE_GDC1_COMMAND(GDC_COMMAND_CSRFORM); + WRITE_GDC_CSRFORM((PUCHAR)GDC1_IO_o_PARAM, &CursorParameters); + + /* PITCH */ + PitchParameters.WordsPerScanline = BYTES_PER_SCANLINE; + WRITE_GDC1_COMMAND(GDC_COMMAND_PITCH); + WRITE_GDC_PITCH((PUCHAR)GDC1_IO_o_PARAM, &PitchParameters); + + /* PRAM */ + RamParameters.StartingAddress = 0; + RamParameters.Length = 1023; + RamParameters.ImageBit = FALSE; + RamParameters.WideDisplay = FALSE; + WRITE_GDC1_COMMAND(GDC_COMMAND_PRAM); + WRITE_GDC_PRAM((PUCHAR)GDC1_IO_o_PARAM, &RamParameters); + + /* ZOOM */ + ZoomParameters.DisplayZoomFactor = 0; + ZoomParameters.WritingZoomFactor = 0; + WRITE_GDC1_COMMAND(GDC_COMMAND_ZOOM); + WRITE_GDC_ZOOM((PUCHAR)GDC1_IO_o_PARAM, &ZoomParameters); + + /* CSRW */ + CursorPosition.CursorAddress = 0; + CursorPosition.DotAddress = 0; + WRITE_GDC1_COMMAND(GDC_COMMAND_CSRW); + WRITE_GDC_CSRW((PUCHAR)GDC1_IO_o_PARAM, &CursorPosition); + + /* START */ + WRITE_GDC1_COMMAND(GDC_COMMAND_BCTRL_START); + + /* ============================ SLAVE ============================ */ + + /* SLAVE */ + WRITE_GDC2_COMMAND(GDC_COMMAND_SLAVE); + + /* SYNC */ + SyncParameters.Flags = SYNC_DISPLAY_MODE_GRAPHICS | SYNC_VIDEO_FRAMING_NONINTERLACED | + SYNC_DRAW_DURING_ACTIVE_DISPLAY_TIME_AND_RETRACE_BLANKING | + SYNC_STATIC_RAM_NO_REFRESH; + SyncParameters.ScreenWidthChars = 80; + SyncParameters.HorizontalSyncWidth = 12; + SyncParameters.VerticalSyncWidth = 2; + SyncParameters.HorizontalFrontPorchWidth = 4; + SyncParameters.HorizontalBackPorchWidth = 132; + SyncParameters.VerticalFrontPorchWidth = 6; + SyncParameters.ScreenWidthLines = 480; + SyncParameters.VerticalBackPorchWidth = 37; + WRITE_GDC2_COMMAND(GDC_COMMAND_SYNC_ON); + WRITE_GDC_SYNC((PUCHAR)GDC2_IO_o_PARAM, &SyncParameters); + + /* CSRFORM */ + CursorParameters.Show = FALSE; + CursorParameters.Blink = FALSE; + CursorParameters.BlinkRate = 0; + CursorParameters.LinesPerRow = 1; + CursorParameters.StartScanLine = 0; + CursorParameters.EndScanLine = 0; + WRITE_GDC2_COMMAND(GDC_COMMAND_CSRFORM); + WRITE_GDC_CSRFORM((PUCHAR)GDC2_IO_o_PARAM, &CursorParameters); + + /* PITCH */ + PitchParameters.WordsPerScanline = BYTES_PER_SCANLINE; + WRITE_GDC2_COMMAND(GDC_COMMAND_PITCH); + WRITE_GDC_PITCH((PUCHAR)GDC2_IO_o_PARAM, &PitchParameters); + + /* PRAM */ + RamParameters.StartingAddress = 0; + RamParameters.Length = 1023; + RamParameters.ImageBit = TRUE; + RamParameters.WideDisplay = FALSE; + WRITE_GDC2_COMMAND(GDC_COMMAND_PRAM); + WRITE_GDC_PRAM((PUCHAR)GDC2_IO_o_PARAM, &RamParameters); + + /* ZOOM */ + ZoomParameters.DisplayZoomFactor = 0; + ZoomParameters.WritingZoomFactor = 0; + WRITE_GDC2_COMMAND(GDC_COMMAND_ZOOM); + WRITE_GDC_ZOOM((PUCHAR)GDC2_IO_o_PARAM, &ZoomParameters); + + /* CSRW */ + CursorPosition.CursorAddress = 0; + CursorPosition.DotAddress = 0; + WRITE_GDC2_COMMAND(GDC_COMMAND_CSRW); + WRITE_GDC_CSRW((PUCHAR)GDC2_IO_o_PARAM, &CursorPosition); + + /* Synchronize the master sync source */ + TextSync(); + TextSync(); + TextSync(); + TextSync(); + + /* START */ + WRITE_GDC2_COMMAND(GDC_COMMAND_BCTRL_START); + + /* 256 colors */ + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_EGC_FF_UNPROTECT); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_PEGC_ENABLE); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_LINES_800); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_EGC_FF_PROTECT); + WRITE_REGISTER_USHORT((PUSHORT)(VideoMemoryI + PEGC_MMIO_MODE), PEGC_MODE_PACKED); + WRITE_REGISTER_USHORT((PUSHORT)(VideoMemoryI + PEGC_MMIO_FRAMEBUFFER), PEGC_FB_MAP); + + /* Select the video source */ + RelayState = READ_PORT_UCHAR((PUCHAR)GRAPH_IO_i_RELAY) & ~(GRAPH_RELAY_0 | GRAPH_RELAY_1); + RelayState |= GRAPH_VID_SRC_INTERNAL | GRAPH_SRC_GDC; + WRITE_PORT_UCHAR((PUCHAR)GRAPH_IO_o_RELAY, RelayState); +} + +static VOID +SetPaletteEntryRGB( + _In_ ULONG Id, + _In_ RGBQUAD Rgb) +{ + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_PALETTE_INDEX, Id); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_RED, GetRValue(Rgb)); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_GREEN, GetGValue(Rgb)); + WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_BLUE, GetBValue(Rgb)); +} + +VOID +NTAPI +InitPaletteWithTable( + _In_ PULONG Table, + _In_ ULONG Count) +{ + ULONG i; + PULONG Entry = Table; + + for (i = 0; i < Count; i++) + SetPaletteEntryRGB(i, *Entry++); + + for (i = Count; i < PEGC_MAX_COLORS; i++) + SetPaletteEntryRGB(i, VidpDefaultPalette[BV_COLOR_BLACK]); +} + +VOID +NTAPI +DisplayCharacter( + _In_ CHAR Character, + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG TextColor, + _In_ ULONG BackColor) +{ + ULONG X, Y, PixelMask; + PUCHAR FontChar = GetFontPtr(Character); + + for (Y = Top; + Y < Top + BOOTCHAR_HEIGHT; + ++Y, FontChar += FONT_PTR_DELTA) + { + for (X = Left, PixelMask = 1 << (BOOTCHAR_WIDTH - 1); + X < Left + BOOTCHAR_WIDTH; + ++X, PixelMask >>= 1) + { + if (*FontChar & PixelMask) + SetPixel(X, Y, (UCHAR)TextColor); + else if (BackColor < BV_COLOR_NONE) + SetPixel(X, Y, (UCHAR)BackColor); + } + } +} + +VOID +NTAPI +PreserveRow( + _In_ ULONG CurrentTop, + _In_ ULONG TopDelta, + _In_ BOOLEAN Restore) +{ + PUCHAR OldPosition, NewPosition; + ULONG PixelCount = TopDelta * SCREEN_WIDTH; + + if (Restore) + { + /* Restore the row by copying back the contents saved off-screen */ + OldPosition = (PUCHAR)(FrameBuffer + FB_OFFSET(0, SCREEN_HEIGHT)); + NewPosition = (PUCHAR)(FrameBuffer + FB_OFFSET(0, CurrentTop)); + } + else + { + /* Preserve the row by saving its contents off-screen */ + OldPosition = (PUCHAR)(FrameBuffer + FB_OFFSET(0, CurrentTop)); + NewPosition = (PUCHAR)(FrameBuffer + FB_OFFSET(0, SCREEN_HEIGHT)); + } + + while (PixelCount--) + WRITE_REGISTER_UCHAR(NewPosition++, READ_REGISTER_UCHAR(OldPosition++)); +} + +VOID +PrepareForSetPixel(VOID) +{ + NOTHING; +} + +VOID +NTAPI +DoScroll( + _In_ ULONG Scroll) +{ + USHORT i, Line; + PUCHAR Src, Dst; + PULONG SrcWide, DstWide; + USHORT PixelCount = (VidpScrollRegion[2] - VidpScrollRegion[0]) + 1; + ULONG_PTR SourceOffset = FrameBuffer + FB_OFFSET(VidpScrollRegion[0], VidpScrollRegion[1] + Scroll); + ULONG_PTR DestinationOffset = FrameBuffer + FB_OFFSET(VidpScrollRegion[0], VidpScrollRegion[1]); + + for (Line = VidpScrollRegion[1]; Line <= VidpScrollRegion[3]; Line++) + { + SrcWide = (PULONG)SourceOffset; + DstWide = (PULONG)DestinationOffset; + for (i = 0; i < PixelCount / sizeof(ULONG); i++) + WRITE_REGISTER_ULONG(DstWide++, READ_REGISTER_ULONG(SrcWide++)); + + Src = (PUCHAR)SrcWide; + Dst = (PUCHAR)DstWide; + for (i = 0; i < PixelCount % sizeof(ULONG); i++) + WRITE_REGISTER_UCHAR(Dst++, READ_REGISTER_UCHAR(Src++)); + + SourceOffset += SCREEN_WIDTH; + DestinationOffset += SCREEN_WIDTH; + } +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +BOOLEAN +NTAPI +VidInitialize( + _In_ BOOLEAN SetMode) +{ + PHYSICAL_ADDRESS BaseAddress; + + BaseAddress.QuadPart = VRAM_NORMAL_PLANE_I; + VideoMemoryI = (ULONG_PTR)MmMapIoSpace(BaseAddress, VRAM_PLANE_SIZE, MmNonCached); + if (!VideoMemoryI) + goto Failure; + + if (!HasPegcController()) + goto Failure; + + BaseAddress.QuadPart = PEGC_FRAMEBUFFER_PACKED; + FrameBuffer = (ULONG_PTR)MmMapIoSpace(BaseAddress, PEGC_FRAMEBUFFER_SIZE, MmNonCached); + if (!FrameBuffer) + goto Failure; + + if (SetMode) + VidResetDisplay(TRUE); + + return TRUE; + +Failure: + if (!VideoMemoryI) MmUnmapIoSpace((PVOID)VideoMemoryI, VRAM_PLANE_SIZE); + if (!FrameBuffer) MmUnmapIoSpace((PVOID)FrameBuffer, PEGC_FRAMEBUFFER_SIZE); + + return FALSE; +} + +VOID +NTAPI +VidCleanUp(VOID) +{ + WRITE_PORT_UCHAR((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GRAPH_MODE_DISPLAY_DISABLE); +} + +VOID +NTAPI +VidResetDisplay( + _In_ BOOLEAN HalReset) +{ + PULONG PixelsPosition = (PULONG)(FrameBuffer + FB_OFFSET(0, 0)); + ULONG PixelCount = ((SCREEN_WIDTH * SCREEN_HEIGHT) / sizeof(ULONG)) + 1; + + /* Clear the current position */ + VidpCurrentX = 0; + VidpCurrentY = 0; + + /* Clear the screen with HAL if we were asked to */ + if (HalReset) + HalResetDisplay(); + + WRITE_PORT_UCHAR((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GRAPH_MODE_DISPLAY_DISABLE); + + /* 640x480 256-color 31 kHz mode */ + InitializeDisplay(); + + /* Re-initialize the palette and fill the screen black */ + InitializePalette(); + while (PixelCount--) + WRITE_REGISTER_ULONG(PixelsPosition++, 0); + + WRITE_PORT_UCHAR((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GRAPH_MODE_DISPLAY_ENABLE); +} + +VOID +NTAPI +VidScreenToBufferBlt( + _Out_ PUCHAR Buffer, + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG Width, + _In_ ULONG Height, + _In_ ULONG Delta) +{ + ULONG X, Y; + PUCHAR OutputBuffer; + USHORT Px; + PUSHORT PixelsPosition = (PUSHORT)(FrameBuffer + FB_OFFSET(Left, Top)); + + /* Clear the destination buffer */ + RtlZeroMemory(Buffer, Delta * Height); + + for (Y = 0; Y < Height; Y++) + { + OutputBuffer = Buffer + Y * Delta; + + for (X = 0; X < Width; X += 2) + { + Px = READ_REGISTER_USHORT(PixelsPosition++); + *OutputBuffer++ = (FIRSTBYTE(Px) << 4) | (SECONDBYTE(Px) & 0x0F); + } + } +} + +VOID +NTAPI +VidSolidColorFill( + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG Right, + _In_ ULONG Bottom, + _In_ UCHAR Color) +{ + USHORT i, Line; + PUCHAR PixelPtr; + PULONG PixelsPtr; + ULONG WideColor = (Color << 24) | (Color << 16) | (Color << 8) | Color; + USHORT PixelCount = (Right - Left) + 1; + ULONG_PTR StartOffset = FrameBuffer + FB_OFFSET(Left, Top); + + for (Line = Top; Line <= Bottom; Line++) + { + PixelsPtr = (PULONG)StartOffset; + for (i = 0; i < PixelCount / sizeof(ULONG); i++) + WRITE_REGISTER_ULONG(PixelsPtr++, WideColor); + + PixelPtr = (PUCHAR)PixelsPtr; + for (i = 0; i < PixelCount % sizeof(ULONG); i++) + WRITE_REGISTER_UCHAR(PixelPtr++, Color); + + StartOffset += SCREEN_WIDTH; + } +} diff --git a/drivers/base/bootvid/i386/pc98/pc98.h b/drivers/base/bootvid/i386/pc98/pc98.h new file mode 100644 index 00000000000..2e84211e192 --- /dev/null +++ b/drivers/base/bootvid/i386/pc98/pc98.h @@ -0,0 +1,65 @@ +/* + * PROJECT: ReactOS Boot Video Driver for NEC PC-98 series + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Arch-specific header file + * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com) + */ + +#pragma once + +/* INCLUDES *******************************************************************/ + +#include + +/* GLOBALS ********************************************************************/ + +#define BYTES_PER_SCANLINE (SCREEN_WIDTH / 8) +#define FB_OFFSET(x, y) ((y) * SCREEN_WIDTH + (x)) + +extern ULONG_PTR FrameBuffer; + +/* PROTOTYPES *****************************************************************/ + +VOID +NTAPI +DisplayCharacter( + _In_ CHAR Character, + _In_ ULONG Left, + _In_ ULONG Top, + _In_ ULONG TextColor, + _In_ ULONG BackColor); + +VOID +NTAPI +DoScroll( + _In_ ULONG Scroll); + +VOID +NTAPI +InitPaletteWithTable( + _In_ PULONG Table, + _In_ ULONG Count); + +VOID +NTAPI +PreserveRow( + _In_ ULONG CurrentTop, + _In_ ULONG TopDelta, + _In_ BOOLEAN Restore); + +VOID +PrepareForSetPixel(VOID); + +/* FUNCTIONS ******************************************************************/ + +FORCEINLINE +VOID +SetPixel( + _In_ ULONG Left, + _In_ ULONG Top, + _In_ UCHAR Color) +{ + PUCHAR PixelPosition = (PUCHAR)(FrameBuffer + FB_OFFSET(Left, Top)); + + WRITE_REGISTER_UCHAR(PixelPosition, Color); +} diff --git a/drivers/base/bootvid/precomp.h b/drivers/base/bootvid/precomp.h index da64ef71c86..a5a27f3ead2 100644 --- a/drivers/base/bootvid/precomp.h +++ b/drivers/base/bootvid/precomp.h @@ -7,8 +7,12 @@ /* Arch specific includes */ #if defined(_M_IX86) || defined(_M_AMD64) +#if defined(SARCH_PC98) +#include "i386/pc98/pc98.h" +#else #include "i386/pc/vga.h" #include "i386/pc/pc.h" +#endif #elif defined(_M_ARM) #include "arm/arm.h" #else diff --git a/sdk/include/reactos/drivers/pc98/video.h b/sdk/include/reactos/drivers/pc98/video.h index c55211d091b..35a5f704b75 100644 --- a/sdk/include/reactos/drivers/pc98/video.h +++ b/sdk/include/reactos/drivers/pc98/video.h @@ -9,16 +9,19 @@ /* Video memory ***************************************************************/ -#define VRAM_NORMAL_PLANE_B 0xA8000 -#define VRAM_NORMAL_PLANE_G 0xB0000 -#define VRAM_NORMAL_PLANE_R 0xB8000 -#define VRAM_NORMAL_PLANE_I 0xE0000 +#define VRAM_NORMAL_PLANE_B 0xA8000 /* Blue */ +#define VRAM_NORMAL_PLANE_G 0xB0000 /* Green */ +#define VRAM_NORMAL_PLANE_R 0xB8000 /* Red */ +#define VRAM_NORMAL_PLANE_I 0xE0000 /* Intensity */ #define VRAM_PLANE_SIZE 0x08000 #define VRAM_NORMAL_TEXT 0xA0000 #define VRAM_TEXT_ATTR_OFFSET 0x02000 #define VRAM_TEXT_SIZE 0x02000 #define VRAM_ATTR_SIZE 0x02000 +#define PEGC_FRAMEBUFFER_PACKED 0xF00000 +#define PEGC_FRAMEBUFFER_SIZE 0x080000 + /* High-resolution machine */ #define VRAM_HI_RESO_PLANE_B 0xC0000 #define VRAM_HI_RESO_PLANE_G 0xC8000 @@ -52,14 +55,118 @@ #define GDC_ATTR_YELLOW 0xC0 #define GDC_ATTR_WHITE 0xE0 -#define GDC_COMMAND_RESET 0x00 +/* Operation type */ +#define GDC_MOD_REPLACE 0x00 +#define GDC_MOD_COMPLEMENT 0x01 /* XOR */ +#define GDC_MOD_CLEAR 0x02 /* AND */ +#define GDC_MOD_SET 0x03 /* OR */ + +#define GDC_GRAPHICS_DRAWING 0x40 + +#define GDC_COMMAND_RESET1 0x00 +#define GDC_COMMAND_RESET2 0x01 +#define GDC_COMMAND_STOP2 0x05 +#define GDC_COMMAND_RESET3 0x09 #define GDC_COMMAND_BCTRL_STOP 0x0C #define GDC_COMMAND_BCTRL_START 0x0D + #define GDC_COMMAND_SYNC_ON 0x0E +typedef struct _SYNCPARAM +{ + UCHAR Flags; +#define SYNC_DISPLAY_MODE_GRAPHICS_AND_CHARACTERS 0x00 +#define SYNC_DISPLAY_MODE_GRAPHICS 0x02 +#define SYNC_DISPLAY_MODE_CHARACTERS 0x20 + +#define SYNC_VIDEO_FRAMING_NONINTERLACED 0x00 +#define SYNC_VIDEO_FRAMING_INTERLACED_REPEAT_FOR_CHARACTERS 0x08 +#define SYNC_VIDEO_FRAMING_INTERLACED 0x09 + +#define SYNC_DRAW_DURING_ACTIVE_DISPLAY_TIME_AND_RETRACE_BLANKING 0x00 +#define SYNC_DRAW_ONLY_DURING_RETRACE_BLANKING 0x10 + +#define SYNC_STATIC_RAM_NO_REFRESH 0x00 +#define SYNC_DYNAMIC_RAM_REFRESH 0x04 + + UCHAR ScreenWidthChars; + UCHAR HorizontalSyncWidth; + UCHAR VerticalSyncWidth; + UCHAR HorizontalFrontPorchWidth; + UCHAR HorizontalBackPorchWidth; + UCHAR VerticalFrontPorchWidth; + USHORT ScreenWidthLines; + UCHAR VerticalBackPorchWidth; +} SYNCPARAM, *PSYNCPARAM; + +FORCEINLINE +VOID +WRITE_GDC_SYNC(PUCHAR Port, PSYNCPARAM SyncParameters) +{ + WRITE_PORT_UCHAR(Port, SyncParameters->Flags & 0x3F); + WRITE_PORT_UCHAR(Port, SyncParameters->ScreenWidthChars - 2); + WRITE_PORT_UCHAR(Port, (SyncParameters->VerticalSyncWidth & 0x07) << 5 | + (SyncParameters->HorizontalSyncWidth - 1)); + WRITE_PORT_UCHAR(Port, ((SyncParameters->HorizontalFrontPorchWidth - 1) << 2) | + ((SyncParameters->VerticalSyncWidth & 0x18) >> 3)); + WRITE_PORT_UCHAR(Port, SyncParameters->HorizontalBackPorchWidth - 1); + WRITE_PORT_UCHAR(Port, SyncParameters->VerticalFrontPorchWidth); + WRITE_PORT_UCHAR(Port, SyncParameters->ScreenWidthLines & 0xFF); + WRITE_PORT_UCHAR(Port, (SyncParameters->VerticalBackPorchWidth << 2) | + ((SyncParameters->ScreenWidthLines & 0x300) >> 8)); +} + #define GDC_COMMAND_SYNC_OFF 0x0F #define GDC_COMMAND_WRITE 0x20 -#define GDC_COMMAND_SLAVE 0x6E -#define GDC_COMMAND_MASTER 0x6F +#define GDC_COMMAND_DMAW 0x24 + +#define GDC_COMMAND_ZOOM 0x46 +typedef struct _ZOOMPARAM +{ + UCHAR DisplayZoomFactor; + UCHAR WritingZoomFactor; +} ZOOMPARAM, *PZOOMPARAM; + +FORCEINLINE +VOID +WRITE_GDC_ZOOM(PUCHAR Port, PZOOMPARAM ZoomParameters) +{ + WRITE_PORT_UCHAR(Port, ZoomParameters->DisplayZoomFactor << 4 | ZoomParameters->WritingZoomFactor); +} + +#define GDC_COMMAND_PITCH 0x47 +typedef struct _PITCHPARAM +{ + ULONG WordsPerScanline; +} PITCHPARAM, *PPITCHPARAM; + +FORCEINLINE +VOID +WRITE_GDC_PITCH(PUCHAR Port, PPITCHPARAM PitchParameters) +{ + WRITE_PORT_UCHAR(Port, PitchParameters->WordsPerScanline); +} + +#define GDC_COMMAND_CSRW 0x49 +typedef struct _CSRWPARAM +{ + ULONG CursorAddress; + UCHAR DotAddress; +} CSRWPARAM, *PCSRWPARAM; + +FORCEINLINE +VOID +WRITE_GDC_CSRW(PUCHAR Port, PCSRWPARAM CursorParameters) +{ + ASSERT(CursorParameters->CursorAddress < 0xF00000); + ASSERT(CursorParameters->DotAddress < 0x10); + + WRITE_PORT_UCHAR(Port, CursorParameters->CursorAddress & 0xFF); + WRITE_PORT_UCHAR(Port, (CursorParameters->CursorAddress >> 8) & 0xFF); + WRITE_PORT_UCHAR(Port, (CursorParameters->DotAddress << 4) | + ((CursorParameters->CursorAddress >> 16) & 0x03)); +} + +#define GDC_COMMAND_MASK 0x4A #define GDC_COMMAND_CSRFORM 0x4B typedef struct _CSRFORMPARAM @@ -83,40 +190,38 @@ WRITE_GDC_CSRFORM(PUCHAR Port, PCSRFORMPARAM CursorParameters) WRITE_PORT_UCHAR(Port, (CursorParameters->EndScanLine << 3) | ((CursorParameters->BlinkRate & 0x1C) >> 2)); } +#define GDC_COMMAND_FIGS 0x4C +#define GDC_COMMAND_GCHRD 0x68 #define GDC_COMMAND_START 0x6B -#define GDC_COMMAND_ZOOM 0x46 +#define GDC_COMMAND_FIGD 0x6C +#define GDC_COMMAND_SLAVE 0x6E +#define GDC_COMMAND_MASTER 0x6F -#define GDC_COMMAND_CSRW 0x49 -typedef struct _CSRWPARAM +#define GDC_COMMAND_PRAM 0x70 +typedef struct _PRAMPARAM { - ULONG CursorAddress; - UCHAR DotAddress; -} CSRWPARAM, *PCSRWPARAM; + ULONG StartingAddress; + USHORT Length; + BOOLEAN ImageBit; + BOOLEAN WideDisplay; +} PRAMPARAM, *PPRAMPARAM; FORCEINLINE VOID -WRITE_GDC_CSRW(PUCHAR Port, PCSRWPARAM CursorParameters) +WRITE_GDC_PRAM(PUCHAR Port, PPRAMPARAM RamParameters) { - ASSERT(CursorParameters->CursorAddress < 0xF00000); - ASSERT(CursorParameters->DotAddress < 0x10); - - WRITE_PORT_UCHAR(Port, CursorParameters->CursorAddress & 0xFF); - WRITE_PORT_UCHAR(Port, (CursorParameters->CursorAddress >> 8) & 0xFF); - WRITE_PORT_UCHAR(Port, (CursorParameters->DotAddress << 4) | - ((CursorParameters->CursorAddress >> 16) & 0x03)); + WRITE_PORT_UCHAR(Port, RamParameters->StartingAddress & 0xFF); + WRITE_PORT_UCHAR(Port, (RamParameters->StartingAddress >> 8) & 0xFF); + WRITE_PORT_UCHAR(Port, ((RamParameters->Length & 0x0F) << 4) | ((RamParameters->StartingAddress >> 16) & 0x03)); + WRITE_PORT_UCHAR(Port, ((RamParameters->WideDisplay & 0x01) << 7) | ((RamParameters->ImageBit & 0x01) << 6) | + ((RamParameters->Length >> 4) & 0x3F)); } -#define GDC_COMMAND_PRAM 0x70 -#define GDC_COMMAND_PITCH 0x47 -#define GDC_COMMAND_MASK 0x4A -#define GDC_COMMAND_FIGS 0x4C -#define GDC_COMMAND_FIGD 0x6C -#define GDC_COMMAND_GCHRD 0x68 +#define GDC_COMMAND_TEXTW 0x78 #define GDC_COMMAND_READ 0xA0 -#define GDC_COMMAND_CURD 0xE0 -#define GDC_COMMAND_LPRD 0xC0 #define GDC_COMMAND_DMAR 0xA4 -#define GDC_COMMAND_DMAW 0x24 +#define GDC_COMMAND_LPRD 0xC0 +#define GDC_COMMAND_CURD 0xE0 /* Master GDC *****************************************************************/ @@ -131,20 +236,20 @@ WRITE_GDC_CSRW(PUCHAR Port, PCSRWPARAM CursorParameters) #define GDC1_IO_o_MODE_FLIPFLOP1 0x68 #define GDC1_MODE_VERTICAL_LINE 0x00 /* Character attribute */ #define GDC1_MODE_SIMPLE_GRAPHICS 0x01 - #define GDC1_MODE_COLORED 0x02 - #define GDC1_MODE_MONOCHROME 0x03 + #define GRAPH_MODE_COLORED 0x02 + #define GRAPH_MODE_MONOCHROME 0x03 #define GDC1_MODE_COLS_80 0x04 #define GDC1_MODE_COLS_40 0x05 #define GDC1_MODE_ANK_6_8 0x06 #define GDC1_MODE_ANK_7_13 0x07 - #define GDC1_MODE_LINES_400 0x08 - #define GDC1_MODE_LINES_200 0x09 /* Hide odd raster line */ + #define GDC2_MODE_ODD_RLINE_SHOW 0x08 + #define GDC2_MODE_ODD_RLINE_HIDE 0x09 #define GDC1_MODE_KCG_CODE 0x0A /* CG access during V-SYNC */ #define GDC1_MODE_KCG_BITMAP 0x0B - #define GDC1_NVMW_PROTECT 0x0C - #define GDC1_NVMW_UNPROTECT 0x0D /* Memory at TextVramSegment:(3FE2-3FFEh) */ - #define GDC1_MODE_DISPLAY_DISABLE 0x0E - #define GDC1_MODE_DISPLAY_ENABLE 0x0F + #define GDC1_NVRAM_PROTECT 0x0C + #define GDC1_NVRAM_UNPROTECT 0x0D /* Memory at TextVramSegment:(3FE2-3FFEh) */ + #define GRAPH_MODE_DISPLAY_DISABLE 0x0E + #define GRAPH_MODE_DISPLAY_ENABLE 0x0F #define GDC1_IO_o_BORDER_COLOR 0x6C /* PC-H98 */ @@ -177,7 +282,7 @@ WRITE_GDC_CSRW(PUCHAR Port, PCSRWPARAM CursorParameters) #define GDC2_MODE_EGC 0x05 #define GDC2_EGC_FF_PROTECT 0x06 #define GDC2_EGC_FF_UNPROTECT 0x07 /* Unprotect the EGC F/F registers */ - #define GDC2_MODE_PEGS_DISABLE 0x20 + #define GDC2_MODE_PEGC_DISABLE 0x20 #define GDC2_MODE_PEGC_ENABLE 0x21 // #define GDC2_MODE_ 0x26 // #define GDC2_MODE_ 0x27 @@ -189,7 +294,7 @@ WRITE_GDC_CSRW(PUCHAR Port, PCSRWPARAM CursorParameters) // #define GDC2_MODE_ 0x2D #define GDC2_MODE_CRT 0x40 #define GDC2_MODE_LCD 0x41 - // #define GDC2_MODE_VRAM_PLAIN 0x62 /* PC-H98 */ + // #define GDC2_MODE_VRAM_PLANAR 0x62 /* PC-H98 */ // #define GDC2_MODE_VRAM_PACKED 0x63 #define GDC2_MODE_LINES_400 0x68 /* 128 kB VRAM boundary */ #define GDC2_MODE_LINES_800 0x69 /* 256 kB VRAM boundary */ @@ -234,6 +339,36 @@ WRITE_GDC2_COMMAND(UCHAR Command) WRITE_PORT_UCHAR((PUCHAR)GDC2_IO_o_COMMAND, Command); } +/* Miscellaneous **************************************************************/ + +#define GRAPH_IO_i_STATUS 0x9A0 + #define GRAPH_STATUS_SET 0x01 + #define GRAPH_GDC_CLOCK2_5MHZ 0x02 + +#define GRAPH_IO_o_STATUS_SELECT 0x9A0 + #define GRAPH_STATUS_GDC_CLOCK1_5MHZ 0x09 + #define GRAPH_STATUS_PEGC 0x0A + +#define GRAPH_IO_i_DPMS 0x9A2 +#define GRAPH_IO_o_DPMS 0x9A2 + +#define GRAPH_IO_i_HORIZONTAL_SCAN_RATE 0x9A8 +#define GRAPH_IO_o_HORIZONTAL_SCAN_RATE 0x9A8 + #define GRAPH_HF_24KHZ 0x00 + #define GRAPH_HF_31KHZ 0x01 + +#define GRAPH_IO_i_RELAY 0xFAC + #define GRAPH_RELAY_0 0x01 + #define GRAPH_RELAY_1 0x02 + +#define GRAPH_IO_o_RELAY 0xFAC + /* Relay 0 */ + #define GRAPH_VID_SRC_INTERNAL 0x00 + #define GRAPH_VID_SRC_EXTERNAL 0x01 + /* Relay 1 */ + #define GRAPH_SRC_GDC 0x00 + #define GRAPH_SRC_WAB 0x02 + /* CRT Controller *************************************************************/ #define CRTC_IO_o_SCANLINE_START 0x70 @@ -247,25 +382,11 @@ WRITE_GDC2_COMMAND(UCHAR Command) #define GRCG_IO_i_MODE 0x7C #define GRCG_IO_o_MODE 0x7C -typedef union _GRCG_MODE_REGISTER -{ - struct - { - UCHAR DisablePlaneB:1; - UCHAR DisablePlaneR:1; - UCHAR DisablePlaneG:1; - UCHAR DisablePlaneI:1; - UCHAR Unused:2; - - UCHAR Mode:1; -#define GRCG_MODE_TILE_DIRECT_WRITE 0 -#define GRCG_MODE_TILE_COMPARE_READ 0 -#define GRCG_MODE_READ_MODIFY_WRITE 1 - - UCHAR Enable:1; - }; - UCHAR Bits; -} GRCG_MODE_REGISTER, *PGRCG_MODE_REGISTER; + #define GRCG_DISABLE 0x00 + #define GRCG_ENABLE 0x80 + #define GRCG_MODE_TILE_DIRECT_WRITE 0x80 + #define GRCG_MODE_TILE_COMPARE_READ 0x80 + #define GRCG_MODE_READ_MODIFY_WRITE 0xC0 #define GRCG_IO_o_TILE_PATTERN 0x7E @@ -277,3 +398,37 @@ typedef union _GRCG_MODE_REGISTER #define KCG_IO_o_PATTERN 0xA9 #define KCG_IO_i_PATTERN 0xA9 + +/* EGC blitter ****************************************************************/ + +#define EGC_IO_o_PLANE_ACCESS 0x4A0 +#define EGC_IO_o_PATTERN_DATA_PLANE_READ 0x4A2 +#define EGC_IO_o_READ_WRITE_MODE 0x4A4 +#define EGC_IO_o_FG_COLOR 0x4A6 +#define EGC_IO_o_MASK 0x4A8 +#define EGC_IO_o_BG_COLOR 0x4AA +#define EGC_IO_o_BIT_ADDRESS 0x4AC +#define EGC_IO_o_BIT_LENGTH 0x4AE + +#define PEGC_MMIO_BANK_0 0x004 +#define PEGC_MMIO_BANK_1 0x006 + +#define PEGC_MMIO_MODE 0x100 + #define PEGC_MODE_PACKED 0x00 + #define PEGC_MODE_PLANAR 0x01 + +#define PEGC_MMIO_FRAMEBUFFER 0x102 + #define PEGC_FB_UNMAP 0x00 + #define PEGC_FB_MAP 0x01 + #define PEGC_FB_UNKNOWN1 0x02 + #define PEGC_FB_UNKNOWN2 0x03 + +#define PEGC_MMIO_PLANE_ACCESS 0x104 +#define PEGC_MMIO_ROP 0x108 +#define PEGC_MMIO_DATA_SELECT 0x10A +#define PEGC_MMIO_MASK 0x10C +#define PEGC_MMIO_BIT_LENGTH 0x110 +#define PEGC_MMIO_BIT_ADDRESS 0x112 +#define PEGC_MMIO_FG_COLOR 0x114 +#define PEGC_MMIO_BG_COLOR 0x118 +#define PEGC_MMIO_ROP_PATTERN 0x120