mirror of
https://github.com/reactos/reactos.git
synced 2024-11-24 03:53:31 +08:00
[PC98VID] Add framebuffer video miniport driver for NEC PC-98 series (#3040)
This adds generic graphics support on PC-9821.
This commit is contained in:
parent
f7e84e231b
commit
27cd9eaf1a
11
boot/bootdata/hiveinst_pc98.inf
Normal file
11
boot/bootdata/hiveinst_pc98.inf
Normal file
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
16
win32ss/drivers/miniport/pc98vid/CMakeLists.txt
Normal file
16
win32ss/drivers/miniport/pc98vid/CMakeLists.txt
Normal file
@ -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)
|
378
win32ss/drivers/miniport/pc98vid/hardware.c
Normal file
378
win32ss/drivers/miniport/pc98vid/hardware.c
Normal file
@ -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;
|
||||
}
|
351
win32ss/drivers/miniport/pc98vid/ioctl.c
Normal file
351
win32ss/drivers/miniport/pc98vid/ioctl.c
Normal file
@ -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;
|
||||
}
|
62
win32ss/drivers/miniport/pc98vid/pc98disp.inf
Normal file
62
win32ss/drivers/miniport/pc98vid/pc98disp.inf
Normal file
@ -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"
|
244
win32ss/drivers/miniport/pc98vid/pc98vid.c
Normal file
244
win32ss/drivers/miniport/pc98vid/pc98vid.c
Normal file
@ -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;
|
||||
}
|
167
win32ss/drivers/miniport/pc98vid/pc98vid.h
Normal file
167
win32ss/drivers/miniport/pc98vid/pc98vid.h
Normal file
@ -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 <ntdef.h>
|
||||
#include <dderror.h>
|
||||
#include <devioctl.h>
|
||||
#include <miniport.h>
|
||||
#include <video.h>
|
||||
#include <debug.h>
|
||||
|
||||
#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 <drivers/pc98/video.h>
|
||||
|
||||
#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_ */
|
5
win32ss/drivers/miniport/pc98vid/pc98vid.rc
Normal file
5
win32ss/drivers/miniport/pc98vid/pc98vid.rc
Normal file
@ -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 <reactos/version.rc>
|
10
win32ss/drivers/miniport/pc98vid/pc98vid_reg.inf
Normal file
10
win32ss/drivers/miniport/pc98vid/pc98vid_reg.inf
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user