diff --git a/boot/bootdata/hiveinst_pc98.inf b/boot/bootdata/hiveinst_pc98.inf new file mode 100644 index 00000000000..1212f0365f2 --- /dev/null +++ b/boot/bootdata/hiveinst_pc98.inf @@ -0,0 +1,11 @@ +[Version] +Signature = "$Windows NT$" + +[AddReg] +; Enable _one_ driver per section by removing the leading semicolon. + +; +; Display driver section + +; pc98vid video miniport driver +HKLM,"SYSTEM\CurrentControlSet\Services\vga","Start",0x00010001,0x00000001 diff --git a/sdk/cmake/CMakeMacros.cmake b/sdk/cmake/CMakeMacros.cmake index a9216ee5576..5ac5dec5555 100644 --- a/sdk/cmake/CMakeMacros.cmake +++ b/sdk/cmake/CMakeMacros.cmake @@ -863,6 +863,9 @@ function(create_registry_hives) if(SARCH STREQUAL "xbox") list(APPEND _livecd_inf_files ${CMAKE_SOURCE_DIR}/boot/bootdata/hiveinst_xbox.inf) + elseif(SARCH STREQUAL "pc98") + list(APPEND _livecd_inf_files + ${CMAKE_SOURCE_DIR}/boot/bootdata/hiveinst_pc98.inf) else() list(APPEND _livecd_inf_files ${CMAKE_SOURCE_DIR}/boot/bootdata/hiveinst.inf) diff --git a/sdk/include/reactos/drivers/pc98/video.h b/sdk/include/reactos/drivers/pc98/video.h index 6c20b26cfcd..f6188d2abe7 100644 --- a/sdk/include/reactos/drivers/pc98/video.h +++ b/sdk/include/reactos/drivers/pc98/video.h @@ -353,6 +353,8 @@ WRITE_GDC2_COMMAND(UCHAR Command) #define GRAPH_IO_i_DPMS 0x9A2 #define GRAPH_IO_o_DPMS 0x9A2 + #define GRAPH_DPMS_HSYNC_MASK 0x40 + #define GRAPH_DPMS_VSYNC_MASK 0x80 #define GRAPH_IO_i_HORIZONTAL_SCAN_RATE 0x9A8 #define GRAPH_IO_o_HORIZONTAL_SCAN_RATE 0x9A8 diff --git a/win32ss/drivers/miniport/CMakeLists.txt b/win32ss/drivers/miniport/CMakeLists.txt index 79b52e628bb..100182d8e66 100644 --- a/win32ss/drivers/miniport/CMakeLists.txt +++ b/win32ss/drivers/miniport/CMakeLists.txt @@ -1,9 +1,14 @@ -add_subdirectory(vbe) -add_subdirectory(vga) -add_subdirectory(vga_new) -add_subdirectory(vmx_svga) +if(SARCH STREQUAL "pc98") + # Actual binary filename is vga.sys + add_subdirectory(pc98vid) +else() + add_subdirectory(vbe) + add_subdirectory(vga) + add_subdirectory(vga_new) + add_subdirectory(vmx_svga) -if(ARCH STREQUAL "i386") - add_subdirectory(xboxvmp) + if(ARCH STREQUAL "i386") + add_subdirectory(xboxvmp) + endif() endif() diff --git a/win32ss/drivers/miniport/pc98vid/CMakeLists.txt b/win32ss/drivers/miniport/pc98vid/CMakeLists.txt new file mode 100644 index 00000000000..f86abc2edf3 --- /dev/null +++ b/win32ss/drivers/miniport/pc98vid/CMakeLists.txt @@ -0,0 +1,16 @@ + +list(APPEND SOURCE + hardware.c + ioctl.c + pc98vid.c + pc98vid.h) + +# Actual binary filename is vga.sys +add_library(vga MODULE ${SOURCE} pc98vid.rc) + +set_module_type(vga kernelmodedriver) +add_pch(vga pc98vid.h SOURCE) +add_importlibs(vga ntoskrnl videoprt) +add_cd_file(TARGET vga DESTINATION reactos/system32/drivers FOR all) +add_registry_inf(pc98vid_reg.inf) +add_driver_inf(vga pc98disp.inf) diff --git a/win32ss/drivers/miniport/pc98vid/hardware.c b/win32ss/drivers/miniport/pc98vid/hardware.c new file mode 100644 index 00000000000..aab92d978d6 --- /dev/null +++ b/win32ss/drivers/miniport/pc98vid/hardware.c @@ -0,0 +1,378 @@ +/* + * PROJECT: ReactOS framebuffer driver for NEC PC-98 series + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Hardware support code + * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#include "pc98vid.h" + +/* GLOBALS ********************************************************************/ + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, Pc98VidSetCurrentMode) +#pragma alloc_text(PAGE, Pc98VidSetColorRegisters) +#pragma alloc_text(PAGE, Pc98VidGetPowerState) +#pragma alloc_text(PAGE, Pc98VidSetPowerState) +#endif + +#define PEGC_MAX_COLORS 256 + +/* FUNCTIONS ******************************************************************/ + +static BOOLEAN +GraphGetStatus( + _In_ UCHAR Status) +{ + UCHAR Result; + + VideoPortWritePortUchar((PUCHAR)GRAPH_IO_o_STATUS_SELECT, Status); + Result = VideoPortReadPortUchar((PUCHAR)GRAPH_IO_i_STATUS); + + return (Result & GRAPH_STATUS_SET) && (Result != 0xFF); +} + +static BOOLEAN +TestMmio( + _In_ PHW_DEVICE_EXTENSION DeviceExtension) +{ + USHORT OldValue, NewValue; + + OldValue = VideoPortReadRegisterUshort((PUSHORT)(DeviceExtension->PegcControlVa + + PEGC_MMIO_MODE)); + + /* Bits [15:1] are not writable */ + VideoPortWriteRegisterUshort((PUSHORT)(DeviceExtension->PegcControlVa + + PEGC_MMIO_MODE), 0x80); + NewValue = VideoPortReadRegisterUshort((PUSHORT)(DeviceExtension->PegcControlVa + + PEGC_MMIO_MODE)); + + VideoPortWriteRegisterUshort((PUSHORT)(DeviceExtension->PegcControlVa + + PEGC_MMIO_MODE), OldValue); + + return !(NewValue & 0x80); +} + +static VOID +TextSync(VOID) +{ + while (VideoPortReadPortUchar((PUCHAR)GDC1_IO_i_STATUS) & GDC_STATUS_VSYNC) + NOTHING; + + while (!(VideoPortReadPortUchar((PUCHAR)GDC1_IO_i_STATUS) & GDC_STATUS_VSYNC)) + NOTHING; +} + +BOOLEAN +NTAPI +HasPegcController( + _In_ PHW_DEVICE_EXTENSION DeviceExtension) +{ + BOOLEAN Success; + + if (GraphGetStatus(GRAPH_STATUS_PEGC)) + return TestMmio(DeviceExtension); + + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_EGC_FF_UNPROTECT); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_PEGC_ENABLE); + Success = GraphGetStatus(GRAPH_STATUS_PEGC) ? TestMmio(DeviceExtension) : FALSE; + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_PEGC_DISABLE); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_EGC_FF_PROTECT); + + return Success; +} + +VP_STATUS +FASTCALL +Pc98VidSetCurrentMode( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ PVIDEO_MODE RequestedMode) +{ + SYNCPARAM SyncParameters; + CSRFORMPARAM CursorParameters; + CSRWPARAM CursorPosition; + PITCHPARAM PitchParameters; + PRAMPARAM RamParameters; + ZOOMPARAM ZoomParameters; + UCHAR RelayState; + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s() Mode %d\n", + __FUNCTION__, RequestedMode->RequestedMode)); + + if (RequestedMode->RequestedMode > DeviceExtension->ModeCount) + return ERROR_INVALID_PARAMETER; + + /* Blank screen */ + VideoPortWritePortUchar((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GRAPH_MODE_DISPLAY_DISABLE); + + /* RESET, without FIFO check */ + VideoPortWritePortUchar((PUCHAR)GDC1_IO_o_COMMAND, GDC_COMMAND_RESET1); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_COMMAND, GDC_COMMAND_RESET1); + + /* Configure chipset */ + VideoPortWritePortUchar((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GRAPH_MODE_COLORED); + VideoPortWritePortUchar((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GDC2_MODE_ODD_RLINE_SHOW); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_COLORS_16); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_GRCG); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_LCD); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_LINES_400); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, + VideoModes[RequestedMode->RequestedMode].Clock1); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, + VideoModes[RequestedMode->RequestedMode].Clock2); + VideoPortWritePortUchar((PUCHAR)GRAPH_IO_o_HORIZONTAL_SCAN_RATE, + VideoModes[RequestedMode->RequestedMode].HorizontalScanRate); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_VIDEO_PAGE, 0); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_VIDEO_PAGE_ACCESS, 0); + + /* =========================== MASTER ============================ */ + + /* MASTER */ + WRITE_GDC1_COMMAND(GDC_COMMAND_MASTER); + + /* SYNC */ + SyncParameters = VideoModes[RequestedMode->RequestedMode].TextSyncParameters; + SyncParameters.Flags = SYNC_DISPLAY_MODE_GRAPHICS_AND_CHARACTERS | SYNC_VIDEO_FRAMING_NONINTERLACED | + SYNC_DRAW_ONLY_DURING_RETRACE_BLANKING | SYNC_STATIC_RAM_NO_REFRESH; + 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 = 80; + 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 = VideoModes[RequestedMode->RequestedMode].VideoSyncParameters; + SyncParameters.Flags = SYNC_DISPLAY_MODE_GRAPHICS | SYNC_VIDEO_FRAMING_NONINTERLACED | + SYNC_DRAW_DURING_ACTIVE_DISPLAY_TIME_AND_RETRACE_BLANKING | + SYNC_STATIC_RAM_NO_REFRESH; + 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 = 80; + 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, packed pixel */ + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_EGC_FF_UNPROTECT); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_MODE_PEGC_ENABLE); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, + VideoModes[RequestedMode->RequestedMode].Mem); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_MODE_FLIPFLOP2, GDC2_EGC_FF_PROTECT); + VideoPortWriteRegisterUshort((PUSHORT)(DeviceExtension->PegcControlVa + + PEGC_MMIO_MODE), PEGC_MODE_PACKED); + VideoPortWriteRegisterUshort((PUSHORT)(DeviceExtension->PegcControlVa + + PEGC_MMIO_FRAMEBUFFER), PEGC_FB_MAP); + + /* Select the video source */ + RelayState = VideoPortReadPortUchar((PUCHAR)GRAPH_IO_i_RELAY) & + ~(GRAPH_RELAY_0 | GRAPH_RELAY_1); + RelayState |= GRAPH_VID_SRC_INTERNAL | GRAPH_SRC_GDC; + VideoPortWritePortUchar((PUCHAR)GRAPH_IO_o_RELAY, RelayState); + + /* Unblank screen */ + VideoPortWritePortUchar((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, GRAPH_MODE_DISPLAY_ENABLE); + + DeviceExtension->CurrentMode = RequestedMode->RequestedMode; + + return NO_ERROR; +} + +VP_STATUS +FASTCALL +Pc98VidSetColorRegisters( + _In_ PVIDEO_CLUT ColorLookUpTable) +{ + USHORT Entry; + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s()\n", __FUNCTION__)); + + if (ColorLookUpTable->NumEntries > PEGC_MAX_COLORS) + return ERROR_INVALID_PARAMETER; + + for (Entry = ColorLookUpTable->FirstEntry; + Entry < ColorLookUpTable->FirstEntry + ColorLookUpTable->NumEntries; + ++Entry) + { + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_PALETTE_INDEX, Entry); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_RED, + ColorLookUpTable->LookupTable[Entry].RgbArray.Red); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_GREEN, + ColorLookUpTable->LookupTable[Entry].RgbArray.Green); + VideoPortWritePortUchar((PUCHAR)GDC2_IO_o_BLUE, + ColorLookUpTable->LookupTable[Entry].RgbArray.Blue); + } + + return NO_ERROR; +} + +VP_STATUS +NTAPI +Pc98VidGetPowerState( + _In_ PVOID HwDeviceExtension, + _In_ ULONG HwId, + _In_ PVIDEO_POWER_MANAGEMENT VideoPowerControl) +{ + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s() Id %lX, State %x\n", + __FUNCTION__, HwId, VideoPowerControl->PowerState)); + + if (HwId == MONITOR_HW_ID || HwId == DISPLAY_ADAPTER_HW_ID) + { + switch (VideoPowerControl->PowerState) + { + case VideoPowerOn: + case VideoPowerStandBy: + case VideoPowerSuspend: + case VideoPowerOff: + case VideoPowerShutdown: + return NO_ERROR; + } + } + + return ERROR_DEVICE_REINITIALIZATION_NEEDED; +} + +VP_STATUS +NTAPI +Pc98VidSetPowerState( + _In_ PVOID HwDeviceExtension, + _In_ ULONG HwId, + _In_ PVIDEO_POWER_MANAGEMENT VideoPowerControl) +{ + UCHAR Dpms; + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s() Id %lX, State %x\n", + __FUNCTION__, HwId, VideoPowerControl->PowerState)); + + if (HwId == MONITOR_HW_ID) + { + Dpms = VideoPortReadPortUchar((PUCHAR)GRAPH_IO_i_DPMS); + + switch (VideoPowerControl->PowerState) + { + case VideoPowerOn: + /* Turn on HS/VS signals */ + Dpms &= ~(GRAPH_DPMS_HSYNC_MASK | GRAPH_DPMS_VSYNC_MASK); + VideoPortWritePortUchar((PUCHAR)GRAPH_IO_o_DPMS, Dpms); + + /* Unblank screen */ + VideoPortWritePortUchar((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, + GRAPH_MODE_DISPLAY_ENABLE); + break; + + case VideoPowerStandBy: + /* Disable HS signal */ + Dpms = (Dpms | GRAPH_DPMS_HSYNC_MASK) & ~GRAPH_DPMS_VSYNC_MASK; + VideoPortWritePortUchar((PUCHAR)GRAPH_IO_o_DPMS, Dpms); + break; + + case VideoPowerSuspend: + /* Disable VS signal */ + Dpms = (Dpms | GRAPH_DPMS_VSYNC_MASK) & ~GRAPH_DPMS_HSYNC_MASK; + VideoPortWritePortUchar((PUCHAR)GRAPH_IO_o_DPMS, Dpms); + break; + + case VideoPowerOff: + case VideoPowerShutdown: + /* Turn off HS/VS signals */ + Dpms |= GRAPH_DPMS_HSYNC_MASK | GRAPH_DPMS_VSYNC_MASK; + VideoPortWritePortUchar((PUCHAR)GRAPH_IO_o_DPMS, Dpms); + + /* Blank screen */ + VideoPortWritePortUchar((PUCHAR)GDC1_IO_o_MODE_FLIPFLOP1, + GRAPH_MODE_DISPLAY_DISABLE); + break; + } + } + + return NO_ERROR; +} diff --git a/win32ss/drivers/miniport/pc98vid/ioctl.c b/win32ss/drivers/miniport/pc98vid/ioctl.c new file mode 100644 index 00000000000..2ab12e5c680 --- /dev/null +++ b/win32ss/drivers/miniport/pc98vid/ioctl.c @@ -0,0 +1,351 @@ +/* + * PROJECT: ReactOS framebuffer driver for NEC PC-98 series + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: I/O control handling + * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#include "pc98vid.h" + +/* GLOBALS ********************************************************************/ + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(PAGE, Pc98VidStartIO) +#pragma alloc_text(PAGE, Pc98VidQueryMode) +#pragma alloc_text(PAGE, Pc98VidQueryAvailModes) +#pragma alloc_text(PAGE, Pc98VidQueryNumAvailModes) +#pragma alloc_text(PAGE, Pc98VidQueryCurrentMode) +#pragma alloc_text(PAGE, Pc98VidMapVideoMemory) +#pragma alloc_text(PAGE, Pc98VidUnmapVideoMemory) +#pragma alloc_text(PAGE, Pc98VidResetDevice) +#pragma alloc_text(PAGE, Pc98VidGetChildState) +#endif + +/* FUNCTIONS ******************************************************************/ + +VOID +FASTCALL +Pc98VidQueryMode( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ ULONG ModeNumber, + _Out_ PVIDEO_MODE_INFORMATION VideoMode) +{ + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s() Mode %d\n", __FUNCTION__, ModeNumber)); + + VideoMode->Length = sizeof(VIDEO_MODE_INFORMATION); + VideoMode->ModeIndex = ModeNumber; + VideoMode->VisScreenWidth = VideoModes[ModeNumber].HResolution; + VideoMode->VisScreenHeight = VideoModes[ModeNumber].VResolution; + VideoMode->ScreenStride = VideoModes[ModeNumber].HResolution; + VideoMode->NumberOfPlanes = 1; + VideoMode->BitsPerPlane = 8; + VideoMode->Frequency = VideoModes[ModeNumber].RefreshRate; + VideoMode->XMillimeter = 320; + VideoMode->YMillimeter = 240; + VideoMode->NumberRedBits = + VideoMode->NumberGreenBits = + VideoMode->NumberBlueBits = 8; + VideoMode->RedMask = + VideoMode->GreenMask = + VideoMode->BlueMask = 0; + VideoMode->AttributeFlags = VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS | + VIDEO_MODE_PALETTE_DRIVEN | VIDEO_MODE_MANAGED_PALETTE; +} + +VP_STATUS +FASTCALL +Pc98VidQueryAvailModes( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _Out_ PVIDEO_MODE_INFORMATION ModeInformation, + _Out_ PSTATUS_BLOCK StatusBlock) +{ + UCHAR ModeNumber; + PVIDEO_MODE_INFORMATION VideoMode; + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s()\n", __FUNCTION__)); + + for (ModeNumber = 0, VideoMode = ModeInformation; + ModeNumber < DeviceExtension->ModeCount; + ++ModeNumber, ++VideoMode) + { + Pc98VidQueryMode(DeviceExtension, ModeNumber, VideoMode); + } + + StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION) * DeviceExtension->ModeCount; + + return NO_ERROR; +} + +VP_STATUS +FASTCALL +Pc98VidQueryNumAvailModes( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _Out_ PVIDEO_NUM_MODES Modes, + _Out_ PSTATUS_BLOCK StatusBlock) +{ + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s()\n", __FUNCTION__)); + + Modes->NumModes = DeviceExtension->ModeCount; + Modes->ModeInformationLength = sizeof(VIDEO_MODE_INFORMATION); + + StatusBlock->Information = sizeof(VIDEO_NUM_MODES); + + return NO_ERROR; +} + +VP_STATUS +FASTCALL +Pc98VidQueryCurrentMode( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _Out_ PVIDEO_MODE_INFORMATION VideoMode, + _Out_ PSTATUS_BLOCK StatusBlock) +{ + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s() Mode %d\n", + __FUNCTION__, DeviceExtension->CurrentMode)); + + Pc98VidQueryMode(DeviceExtension, DeviceExtension->CurrentMode, VideoMode); + + StatusBlock->Information = sizeof(VIDEO_MODE_INFORMATION); + + return NO_ERROR; +} + +VP_STATUS +FASTCALL +Pc98VidMapVideoMemory( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ PVIDEO_MEMORY RequestedAddress, + _Out_ PVIDEO_MEMORY_INFORMATION MapInformation, + _Out_ PSTATUS_BLOCK StatusBlock) +{ + VP_STATUS Status; + ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY; + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s()\n", __FUNCTION__)); + + MapInformation->VideoRamBase = RequestedAddress->RequestedVirtualAddress; + MapInformation->VideoRamLength = DeviceExtension->FrameBufferLength; + + Status = VideoPortMapMemory(DeviceExtension, + DeviceExtension->FrameBuffer, + &MapInformation->VideoRamLength, + &inIoSpace, + &MapInformation->VideoRamBase); + if (Status != NO_ERROR) + { + VideoDebugPrint((Error, "%s() Failed to map framebuffer memory\n", + __FUNCTION__)); + } + else + { + MapInformation->FrameBufferBase = MapInformation->VideoRamBase; + MapInformation->FrameBufferLength = MapInformation->VideoRamLength; + + StatusBlock->Information = sizeof(VIDEO_MEMORY_INFORMATION); + } + + return Status; +} + +VP_STATUS +FASTCALL +Pc98VidUnmapVideoMemory( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ PVIDEO_MEMORY VideoMemory) +{ + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s()\n", __FUNCTION__)); + + return VideoPortUnmapMemory(DeviceExtension, + VideoMemory->RequestedVirtualAddress, + NULL); +} + +VP_STATUS +FASTCALL +Pc98VidResetDevice(VOID) +{ + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s()\n", __FUNCTION__)); + + return NO_ERROR; +} + +VP_STATUS +FASTCALL +Pc98VidGetChildState( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ PULONG ChildIndex, + _Out_ PULONG ChildState, + _Out_ PSTATUS_BLOCK StatusBlock) +{ + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s() Child %d\n", __FUNCTION__, *ChildIndex)); + + *ChildState = VIDEO_CHILD_ACTIVE; + + StatusBlock->Information = sizeof(ULONG); + + return NO_ERROR; +} + +BOOLEAN +NTAPI +Pc98VidStartIO( + _In_ PVOID HwDeviceExtension, + _Inout_ PVIDEO_REQUEST_PACKET RequestPacket) +{ + VP_STATUS Status; + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s() IOCTL 0x%lX\n", + __FUNCTION__, RequestPacket->IoControlCode)); + + switch (RequestPacket->IoControlCode) + { + case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: + { + if (RequestPacket->OutputBufferLength < sizeof(VIDEO_NUM_MODES)) + { + Status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + Status = Pc98VidQueryNumAvailModes((PHW_DEVICE_EXTENSION)HwDeviceExtension, + (PVIDEO_NUM_MODES)RequestPacket->OutputBuffer, + RequestPacket->StatusBlock); + break; + } + + case IOCTL_VIDEO_QUERY_AVAIL_MODES: + { + if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION) * + ((PHW_DEVICE_EXTENSION)HwDeviceExtension)->ModeCount) + { + Status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + Status = Pc98VidQueryAvailModes((PHW_DEVICE_EXTENSION)HwDeviceExtension, + (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer, + RequestPacket->StatusBlock); + break; + } + + case IOCTL_VIDEO_SET_CURRENT_MODE: + { + if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE)) + { + Status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + Status = Pc98VidSetCurrentMode((PHW_DEVICE_EXTENSION)HwDeviceExtension, + (PVIDEO_MODE)RequestPacket->InputBuffer); + break; + } + + case IOCTL_VIDEO_QUERY_CURRENT_MODE: + { + if (RequestPacket->OutputBufferLength < sizeof(VIDEO_MODE_INFORMATION)) + { + Status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + Status = Pc98VidQueryCurrentMode((PHW_DEVICE_EXTENSION)HwDeviceExtension, + (PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer, + RequestPacket->StatusBlock); + break; + } + + case IOCTL_VIDEO_MAP_VIDEO_MEMORY: + { + if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY) || + RequestPacket->OutputBufferLength < sizeof(VIDEO_MEMORY_INFORMATION)) + { + Status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + Status = Pc98VidMapVideoMemory((PHW_DEVICE_EXTENSION)HwDeviceExtension, + (PVIDEO_MEMORY)RequestPacket->InputBuffer, + (PVIDEO_MEMORY_INFORMATION)RequestPacket->OutputBuffer, + RequestPacket->StatusBlock); + break; + } + + case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: + { + if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) + { + Status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + Status = Pc98VidUnmapVideoMemory((PHW_DEVICE_EXTENSION)HwDeviceExtension, + (PVIDEO_MEMORY)RequestPacket->InputBuffer); + break; + } + + case IOCTL_VIDEO_RESET_DEVICE: + { + Status = Pc98VidResetDevice(); + break; + } + + case IOCTL_VIDEO_SET_COLOR_REGISTERS: + { + if (RequestPacket->InputBufferLength < sizeof(VIDEO_CLUT)) + { + Status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + Status = Pc98VidSetColorRegisters((PVIDEO_CLUT)RequestPacket->InputBuffer); + break; + } + + case IOCTL_VIDEO_GET_CHILD_STATE: + { + if (RequestPacket->InputBufferLength < sizeof(ULONG) || + RequestPacket->OutputBufferLength < sizeof(ULONG)) + { + Status = ERROR_INSUFFICIENT_BUFFER; + break; + } + + Status = Pc98VidGetChildState((PHW_DEVICE_EXTENSION)HwDeviceExtension, + (PULONG)RequestPacket->InputBuffer, + (PULONG)RequestPacket->OutputBuffer, + RequestPacket->StatusBlock); + break; + } + + default: + Status = ERROR_INVALID_FUNCTION; + } + + if (Status != NO_ERROR) + VideoDebugPrint((Trace, "%s() Failed 0x%lX\n", __FUNCTION__, Status)); + + RequestPacket->StatusBlock->Status = Status; + + return TRUE; +} diff --git a/win32ss/drivers/miniport/pc98vid/pc98disp.inf b/win32ss/drivers/miniport/pc98vid/pc98disp.inf new file mode 100644 index 00000000000..81a8608625a --- /dev/null +++ b/win32ss/drivers/miniport/pc98vid/pc98disp.inf @@ -0,0 +1,62 @@ +; pc98disp.inf +; +; Installation file for the display adapter on PC-9821 +; +[Version] +Signature = "$Windows NT$" +;Signature = "$ReactOS$" +LayoutFile = layout.inf +Class = Display +ClassGUID = {4D36E968-E325-11CE-BFC1-08002BE10318} +Provider = %ReactOS% +DriverVer = 08/11/2020,5.2 + +[DestinationDirs] +DefaultDestDir = 12 + +[Manufacturer] +%NecMfg% = NecMfg + +[NecMfg] +%pc98vid.DeviceDesc% = Pc98Vid_Inst +%PCI\VEN_1033&DEV_0009.DeviceDesc% = Pc98Vid_Inst,PCI\VEN_1033&DEV_0009 + +;---------------------------- PC98VID DRIVER ---------------------------- + +[Pc98Vid_Inst.NT] +CopyFiles = pc98vid_CopyFiles.NT + +[pc98vid_CopyFiles.NT] +vga.sys + +[Pc98Vid_Inst.NT.Services] +AddService = vga, 0x00000002, vga_Service_Inst + +[vga_Service_Inst] +ServiceType = 1 +StartType = 1 +ErrorControl = 0 +ServiceBinary = %12%\vga.sys +LoadOrderGroup = Video + +[vga.SoftwareSettings] +AddReg = vga_SoftwareDeviceSettings + +[vga_SoftwareDeviceSettings] +HKR,, InstalledDisplayDrivers, 0x00010000, framebuf +HKR,, VgaCompatible, 0x00010001, 1 +HKR,, VideoDebugLevel, 0x00010001, 0 + +;-------------------------------- STRINGS ------------------------------- + +[Strings] +ReactOS = "ReactOS Team" + +NecMfg = "NEC" +PCI\VEN_1033&DEV_0009.DeviceDesc = "NEC PCI to Core-Graph Bridge" +pc98vid.DeviceDesc = "Graphic controller for PC-9821" + +[Strings.0419] +ReactOS = "Команда ReactOS" + +pc98vid.DeviceDesc = "Графический контроллер для PC-9821" diff --git a/win32ss/drivers/miniport/pc98vid/pc98vid.c b/win32ss/drivers/miniport/pc98vid/pc98vid.c new file mode 100644 index 00000000000..fd7fa07523c --- /dev/null +++ b/win32ss/drivers/miniport/pc98vid/pc98vid.c @@ -0,0 +1,244 @@ +/* + * PROJECT: ReactOS framebuffer driver for NEC PC-98 series + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Miniport driver entrypoint + * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#include "pc98vid.h" + +/* GLOBALS ********************************************************************/ + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT, DriverEntry) +#pragma alloc_text(PAGE, Pc98VidFindAdapter) +#pragma alloc_text(PAGE, Pc98VidInitialize) +#pragma alloc_text(PAGE, Pc98VidGetVideoChildDescriptor) +#endif + +const VIDEOMODE VideoModes[] = +{ + {640, 480, GRAPH_HF_31KHZ, GDC2_CLOCK1_5MHZ, GDC2_CLOCK2_5MHZ, + GDC2_MODE_LINES_800, 60, + {0, 80, 12, 2, 4, 4, 6, 480, 37}, {0, 80, 12, 2, 4, 132, 6, 480, 37}} +}; + +static VIDEO_ACCESS_RANGE LegacyRangeList[] = +{ + { {{0x60, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0x62, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0x68, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0x6A, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0x7C, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xA0, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xA2, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xA4, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xA6, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xA8, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xAA, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xAC, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xAE, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0x9A0, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0x9A2, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0x9A8, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{0xFAC, 0}}, 0x00000001, 1, 1, 1, 0 }, + { {{VRAM_NORMAL_PLANE_I, 0}}, PEGC_CONTROL_SIZE, 0, 0, 1, 0 }, + { {{PEGC_FRAMEBUFFER_PACKED, 0}}, PEGC_FRAMEBUFFER_SIZE, 0, 0, 1, 0 } +}; +#define CONTROL_RANGE_INDEX 17 +#define FRAMEBUFFER_RANGE_INDEX 18 + +/* FUNCTIONS ******************************************************************/ + +VP_STATUS +NTAPI +Pc98VidFindAdapter( + _In_ PVOID HwDeviceExtension, + _In_opt_ PVOID HwContext, + _In_opt_ PWSTR ArgumentString, + _Inout_ PVIDEO_PORT_CONFIG_INFO ConfigInfo, + _Out_ PUCHAR Again) +{ + VP_STATUS Status; + PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension; + ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY; + static WCHAR AdapterChipType[] = L"Onboard"; + static WCHAR AdapterDacType[] = L"8 bit"; + static WCHAR AdapterString[] = L"PEGC"; + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s()\n", __FUNCTION__)); + + if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) + return ERROR_INVALID_PARAMETER; + + Status = VideoPortVerifyAccessRanges(DeviceExtension, + RTL_NUMBER_OF(LegacyRangeList), + LegacyRangeList); + if (Status != NO_ERROR) + { + VideoDebugPrint((Error, "%s() Resource conflict was found\n", __FUNCTION__)); + + return ERROR_INVALID_PARAMETER; + } + + DeviceExtension->PegcControl = LegacyRangeList[CONTROL_RANGE_INDEX].RangeStart; + DeviceExtension->PegcControlLength = LegacyRangeList[CONTROL_RANGE_INDEX].RangeLength; + DeviceExtension->FrameBuffer = LegacyRangeList[FRAMEBUFFER_RANGE_INDEX].RangeStart; + DeviceExtension->FrameBufferLength = LegacyRangeList[FRAMEBUFFER_RANGE_INDEX].RangeLength; + + Status = VideoPortMapMemory(DeviceExtension, + DeviceExtension->PegcControl, + &DeviceExtension->PegcControlLength, + &inIoSpace, + (PVOID)&DeviceExtension->PegcControlVa); + if (Status != NO_ERROR) + { + VideoDebugPrint((Error, "%s() Failed to map control memory\n", __FUNCTION__)); + + VideoPortVerifyAccessRanges(DeviceExtension, 0, NULL); + + return ERROR_DEV_NOT_EXIST; + } + + if (!HasPegcController(DeviceExtension)) + { + VideoDebugPrint((Error, "%s() Unsupported hardware\n", __FUNCTION__)); + + VideoPortVerifyAccessRanges(DeviceExtension, 0, NULL); + VideoPortUnmapMemory(DeviceExtension, + (PVOID)DeviceExtension->PegcControlVa, + NULL); + + return ERROR_DEV_NOT_EXIST; + } + + /* Not VGA-compatible */ + ConfigInfo->NumEmulatorAccessEntries = 0; + ConfigInfo->EmulatorAccessEntries = NULL; + ConfigInfo->EmulatorAccessEntriesContext = 0; + ConfigInfo->HardwareStateSize = 0; + ConfigInfo->VdmPhysicalVideoMemoryAddress.QuadPart = 0; + ConfigInfo->VdmPhysicalVideoMemoryLength = 0; + + VideoPortSetRegistryParameters(DeviceExtension, + L"HardwareInformation.ChipType", + AdapterChipType, + sizeof(AdapterChipType)); + VideoPortSetRegistryParameters(DeviceExtension, + L"HardwareInformation.DacType", + AdapterDacType, + sizeof(AdapterDacType)); + VideoPortSetRegistryParameters(DeviceExtension, + L"HardwareInformation.MemorySize", + &DeviceExtension->FrameBufferLength, + sizeof(ULONG)); + VideoPortSetRegistryParameters(DeviceExtension, + L"HardwareInformation.AdapterString", + AdapterString, + sizeof(AdapterString)); + + return NO_ERROR; +} + +BOOLEAN +NTAPI +Pc98VidInitialize( + _In_ PVOID HwDeviceExtension) +{ + PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension; + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s()\n", __FUNCTION__)); + + DeviceExtension->ModeCount = RTL_NUMBER_OF(VideoModes); + DeviceExtension->MonitorCount = 1; + + return TRUE; +} + +VP_STATUS +NTAPI +Pc98VidGetVideoChildDescriptor( + _In_ PVOID HwDeviceExtension, + _In_ PVIDEO_CHILD_ENUM_INFO ChildEnumInfo, + _Out_ PVIDEO_CHILD_TYPE VideoChildType, + _Out_ PUCHAR pChildDescriptor, + _Out_ PULONG UId, + _Out_ PULONG pUnused) +{ + PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension; + + UNREFERENCED_PARAMETER(pChildDescriptor); + + PAGED_CODE(); + + VideoDebugPrint((Trace, "%s() Index %d\n", + __FUNCTION__, ChildEnumInfo->ChildIndex)); + + *pUnused = 0; + + if (ChildEnumInfo->ChildIndex > 0 && + ChildEnumInfo->ChildIndex <= DeviceExtension->MonitorCount) + { + *VideoChildType = Monitor; + *UId = MONITOR_HW_ID; + + return VIDEO_ENUM_MORE_DEVICES; + } + + return ERROR_NO_MORE_DEVICES; +} + +ULONG +NTAPI +DriverEntry( + _In_ PVOID Context1, + _In_ PVOID Context2) +{ + VIDEO_HW_INITIALIZATION_DATA InitData; + ULONG Status; + BOOLEAN IsLiveCd; + + VideoDebugPrint((Trace, "(%s:%d) %s()\n", + __FILE__, __LINE__, __FUNCTION__)); + + // FIXME: Detect IsLiveCd + IsLiveCd = TRUE; + + VideoPortZeroMemory(&InitData, sizeof(VIDEO_HW_INITIALIZATION_DATA)); + InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA); + InitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION); + InitData.HwFindAdapter = Pc98VidFindAdapter; + InitData.HwInitialize = Pc98VidInitialize; + InitData.HwStartIO = Pc98VidStartIO; + /* + * On LiveCD, we expect to see the initialized video + * before starting the device enumeration, + * so we should mark the driver as non-PnP miniport. + */ + if (!IsLiveCd) + { + InitData.HwGetPowerState = Pc98VidGetPowerState; + InitData.HwSetPowerState = Pc98VidSetPowerState; + InitData.HwGetVideoChildDescriptor = Pc98VidGetVideoChildDescriptor; + } + + InitData.HwLegacyResourceList = LegacyRangeList; + InitData.HwLegacyResourceCount = RTL_NUMBER_OF(LegacyRangeList); + + InitData.AdapterInterfaceType = Isa; + + Status = VideoPortInitialize(Context1, Context2, &InitData, NULL); + if (!NT_SUCCESS(Status)) + { + VideoDebugPrint((Error, "(%s:%d) %s() Initialization failed 0x%lX\n", + __FILE__, __LINE__, __FUNCTION__, Status)); + } + + return Status; +} diff --git a/win32ss/drivers/miniport/pc98vid/pc98vid.h b/win32ss/drivers/miniport/pc98vid/pc98vid.h new file mode 100644 index 00000000000..fd2d8e29b05 --- /dev/null +++ b/win32ss/drivers/miniport/pc98vid/pc98vid.h @@ -0,0 +1,167 @@ +/* + * PROJECT: ReactOS framebuffer driver for NEC PC-98 series + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Miniport driver header file + * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com) + */ + +#ifndef _PC98VID_PCH_ +#define _PC98VID_PCH_ + +#include +#include +#include +#include +#include +#include + +#undef WRITE_PORT_UCHAR +#undef READ_PORT_UCHAR +#define WRITE_PORT_UCHAR(p, d) VideoPortWritePortUchar(p, d) +#define READ_PORT_UCHAR(p) VideoPortReadPortUchar(p) +#include + +#define MONITOR_HW_ID 0x1033FACE /* Dummy */ + +typedef struct _VIDEOMODE +{ + USHORT HResolution; + USHORT VResolution; + UCHAR HorizontalScanRate; + UCHAR Clock1; + UCHAR Clock2; + UCHAR Mem; + UCHAR RefreshRate; + SYNCPARAM TextSyncParameters; + SYNCPARAM VideoSyncParameters; +} VIDEOMODE, *PVIDEOMODE; + +typedef struct _HW_DEVICE_EXTENSION +{ + UCHAR MonitorCount; + UCHAR ModeCount; + UCHAR CurrentMode; + PHYSICAL_ADDRESS PegcControl; + ULONG PegcControlLength; + ULONG_PTR PegcControlVa; + PHYSICAL_ADDRESS FrameBuffer; + ULONG FrameBufferLength; +} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION; + +VP_STATUS +NTAPI +Pc98VidFindAdapter( + _In_ PVOID HwDeviceExtension, + _In_opt_ PVOID HwContext, + _In_opt_ PWSTR ArgumentString, + _Inout_ PVIDEO_PORT_CONFIG_INFO ConfigInfo, + _Out_ PUCHAR Again); + +BOOLEAN +NTAPI +HasPegcController( + _In_ PHW_DEVICE_EXTENSION DeviceExtension); + +BOOLEAN +NTAPI +Pc98VidInitialize( + _In_ PVOID HwDeviceExtension); + +VP_STATUS +NTAPI +Pc98VidGetVideoChildDescriptor( + _In_ PVOID HwDeviceExtension, + _In_ PVIDEO_CHILD_ENUM_INFO ChildEnumInfo, + _Out_ PVIDEO_CHILD_TYPE VideoChildType, + _Out_ PUCHAR pChildDescriptor, + _Out_ PULONG UId, + _Out_ PULONG pUnused); + +BOOLEAN +NTAPI +Pc98VidStartIO( + _In_ PVOID HwDeviceExtension, + _Inout_ PVIDEO_REQUEST_PACKET RequestPacket); + +VOID +FASTCALL +Pc98VidQueryMode( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ ULONG ModeNumber, + _Out_ PVIDEO_MODE_INFORMATION VideoMode); + +VP_STATUS +FASTCALL +Pc98VidQueryAvailModes( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _Out_ PVIDEO_MODE_INFORMATION ModeInformation, + _Out_ PSTATUS_BLOCK StatusBlock); + +VP_STATUS +FASTCALL +Pc98VidQueryNumAvailModes( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _Out_ PVIDEO_NUM_MODES Modes, + _Out_ PSTATUS_BLOCK StatusBlock); + +VP_STATUS +FASTCALL +Pc98VidSetCurrentMode( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ PVIDEO_MODE RequestedMode); + +VP_STATUS +FASTCALL +Pc98VidQueryCurrentMode( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _Out_ PVIDEO_MODE_INFORMATION VideoMode, + _Out_ PSTATUS_BLOCK StatusBlock); + +VP_STATUS +FASTCALL +Pc98VidMapVideoMemory( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ PVIDEO_MEMORY RequestedAddress, + _Out_ PVIDEO_MEMORY_INFORMATION MapInformation, + _Out_ PSTATUS_BLOCK StatusBlock); + +VP_STATUS +FASTCALL +Pc98VidUnmapVideoMemory( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ PVIDEO_MEMORY VideoMemory); + +VP_STATUS +FASTCALL +Pc98VidResetDevice(VOID); + +VP_STATUS +FASTCALL +Pc98VidSetColorRegisters( + _In_ PVIDEO_CLUT ColorLookUpTable); + +VP_STATUS +FASTCALL +Pc98VidGetChildState( + _In_ PHW_DEVICE_EXTENSION DeviceExtension, + _In_ PULONG ChildIndex, + _Out_ PULONG ChildState, + _Out_ PSTATUS_BLOCK StatusBlock); + +VP_STATUS +NTAPI +Pc98VidGetPowerState( + _In_ PVOID HwDeviceExtension, + _In_ ULONG HwId, + _In_ PVIDEO_POWER_MANAGEMENT VideoPowerControl); + +VP_STATUS +NTAPI +Pc98VidSetPowerState( + _In_ PVOID HwDeviceExtension, + _In_ ULONG HwId, + _In_ PVIDEO_POWER_MANAGEMENT VideoPowerControl); + +extern const VIDEOMODE VideoModes[]; + +#endif /* _PC98VID_PCH_ */ diff --git a/win32ss/drivers/miniport/pc98vid/pc98vid.rc b/win32ss/drivers/miniport/pc98vid/pc98vid.rc new file mode 100644 index 00000000000..17cc7729468 --- /dev/null +++ b/win32ss/drivers/miniport/pc98vid/pc98vid.rc @@ -0,0 +1,5 @@ +#define REACTOS_VERSION_DLL +#define REACTOS_STR_FILE_DESCRIPTION "NEC PC-9821 Video Miniport Driver" +#define REACTOS_STR_INTERNAL_NAME "vga" +#define REACTOS_STR_ORIGINAL_FILENAME "vga.sys" +#include diff --git a/win32ss/drivers/miniport/pc98vid/pc98vid_reg.inf b/win32ss/drivers/miniport/pc98vid/pc98vid_reg.inf new file mode 100644 index 00000000000..becce43fdff --- /dev/null +++ b/win32ss/drivers/miniport/pc98vid/pc98vid_reg.inf @@ -0,0 +1,10 @@ +; pc98vid video miniport driver +[AddReg] +HKLM,"SYSTEM\CurrentControlSet\Services\vga","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\vga","Group",0x00000000,"Video Save" +HKLM,"SYSTEM\CurrentControlSet\Services\vga","ImagePath",0x00020000,"system32\drivers\vga.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\vga","Start",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\vga","Type",0x00010001,0x00000001 + +HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vga\Device0","InstalledDisplayDrivers",0x00010000,"framebuf" +HKLM,"SYSTEM\CurrentControlSet\Hardware Profiles\Current\System\CurrentControlSet\Services\vga\Device0","VgaCompatible",0x00010001,1