ReactOS  0.4.15-dev-5496-g599ba9c
pc98vid.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS framebuffer driver for NEC PC-98 series
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Miniport driver entrypoint
5  * COPYRIGHT: Copyright 2020 Dmitry Borisov (di.sean@protonmail.com)
6  */
7 
8 /* INCLUDES *******************************************************************/
9 
10 #include "pc98vid.h"
11 
12 /* GLOBALS ********************************************************************/
13 
14 DATA_SEG("PAGECONS")
16 {
19  {0, 80, 12, 2, 4, 4, 6, 480, 37}, {0, 80, 12, 2, 4, 132, 6, 480, 37}}
20 };
21 
22 DATA_SEG("PAGECONS")
24 {
25  { {{0x60, 0}}, 0x00000001, 1, 1, 1, 0 },
26  { {{0x62, 0}}, 0x00000001, 1, 1, 1, 0 },
27  { {{0x68, 0}}, 0x00000001, 1, 1, 1, 0 },
28  { {{0x6A, 0}}, 0x00000001, 1, 1, 1, 0 },
29  { {{0x7C, 0}}, 0x00000001, 1, 1, 1, 0 },
30  { {{0xA0, 0}}, 0x00000001, 1, 1, 1, 0 },
31  { {{0xA2, 0}}, 0x00000001, 1, 1, 1, 0 },
32  { {{0xA4, 0}}, 0x00000001, 1, 1, 1, 0 },
33  { {{0xA6, 0}}, 0x00000001, 1, 1, 1, 0 },
34  { {{0xA8, 0}}, 0x00000001, 1, 1, 1, 0 },
35  { {{0xAA, 0}}, 0x00000001, 1, 1, 1, 0 },
36  { {{0xAC, 0}}, 0x00000001, 1, 1, 1, 0 },
37  { {{0xAE, 0}}, 0x00000001, 1, 1, 1, 0 },
38  { {{0x9A0, 0}}, 0x00000001, 1, 1, 1, 0 },
39  { {{0x9A2, 0}}, 0x00000001, 1, 1, 1, 0 },
40  { {{0x9A8, 0}}, 0x00000001, 1, 1, 1, 0 },
41  { {{0xFAC, 0}}, 0x00000001, 1, 1, 1, 0 },
42  { {{VRAM_NORMAL_PLANE_I, 0}}, PEGC_CONTROL_SIZE, 0, 0, 1, 0 },
43  { {{PEGC_FRAMEBUFFER_PACKED, 0}}, PEGC_FRAMEBUFFER_SIZE, 0, 0, 1, 0 }
44 };
45 #define CONTROL_RANGE_INDEX 17
46 #define FRAMEBUFFER_RANGE_INDEX 18
47 
48 /* FUNCTIONS ******************************************************************/
49 
50 static
51 CODE_SEG("PAGE")
53 NTAPI
55  _In_ PVOID HwDeviceExtension,
57  _In_opt_ PWSTR ArgumentString,
59  _Out_ PUCHAR Again)
60 {
62  PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
63  ULONG inIoSpace = VIDEO_MEMORY_SPACE_MEMORY;
64  static WCHAR AdapterChipType[] = L"Onboard";
65  static WCHAR AdapterDacType[] = L"8 bit";
66  static WCHAR AdapterString[] = L"PEGC";
67 
68  PAGED_CODE();
69 
70  VideoDebugPrint((Trace, "%s()\n", __FUNCTION__));
71 
72  if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO))
74 
75  Status = VideoPortVerifyAccessRanges(DeviceExtension,
78  if (Status != NO_ERROR)
79  {
80  VideoDebugPrint((Error, "%s() Resource conflict was found\n", __FUNCTION__));
81 
83  }
84 
89 
90  Status = VideoPortMapMemory(DeviceExtension,
91  DeviceExtension->PegcControl,
92  &DeviceExtension->PegcControlLength,
93  &inIoSpace,
94  (PVOID)&DeviceExtension->PegcControlVa);
95  if (Status != NO_ERROR)
96  {
97  VideoDebugPrint((Error, "%s() Failed to map control memory\n", __FUNCTION__));
98 
99  VideoPortVerifyAccessRanges(DeviceExtension, 0, NULL);
100 
101  return ERROR_DEV_NOT_EXIST;
102  }
103 
104  if (!HasPegcController(DeviceExtension))
105  {
106  VideoDebugPrint((Error, "%s() Unsupported hardware\n", __FUNCTION__));
107 
108  VideoPortVerifyAccessRanges(DeviceExtension, 0, NULL);
109  VideoPortUnmapMemory(DeviceExtension,
110  (PVOID)DeviceExtension->PegcControlVa,
111  NULL);
112 
113  return ERROR_DEV_NOT_EXIST;
114  }
115 
116  /* Not VGA-compatible */
117  ConfigInfo->NumEmulatorAccessEntries = 0;
118  ConfigInfo->EmulatorAccessEntries = NULL;
119  ConfigInfo->EmulatorAccessEntriesContext = 0;
120  ConfigInfo->HardwareStateSize = 0;
121  ConfigInfo->VdmPhysicalVideoMemoryAddress.QuadPart = 0;
122  ConfigInfo->VdmPhysicalVideoMemoryLength = 0;
123 
124  VideoPortSetRegistryParameters(DeviceExtension,
125  L"HardwareInformation.ChipType",
126  AdapterChipType,
127  sizeof(AdapterChipType));
128  VideoPortSetRegistryParameters(DeviceExtension,
129  L"HardwareInformation.DacType",
130  AdapterDacType,
131  sizeof(AdapterDacType));
132  VideoPortSetRegistryParameters(DeviceExtension,
133  L"HardwareInformation.MemorySize",
134  &DeviceExtension->FrameBufferLength,
135  sizeof(ULONG));
136  VideoPortSetRegistryParameters(DeviceExtension,
137  L"HardwareInformation.AdapterString",
139  sizeof(AdapterString));
140 
141  return NO_ERROR;
142 }
143 
144 static
145 CODE_SEG("PAGE")
146 BOOLEAN
147 NTAPI
149  _In_ PVOID HwDeviceExtension)
150 {
151  PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
152 
153  PAGED_CODE();
154 
155  VideoDebugPrint((Trace, "%s()\n", __FUNCTION__));
156 
157  DeviceExtension->ModeCount = RTL_NUMBER_OF(VideoModes);
158  DeviceExtension->MonitorCount = 1;
159 
160  return TRUE;
161 }
162 
163 static
164 CODE_SEG("PAGE")
165 VP_STATUS
166 NTAPI
168  _In_ PVOID HwDeviceExtension,
169  _In_ PVIDEO_CHILD_ENUM_INFO ChildEnumInfo,
170  _Out_ PVIDEO_CHILD_TYPE VideoChildType,
171  _Out_ PUCHAR pChildDescriptor,
172  _Out_ PULONG UId,
173  _Out_ PULONG pUnused)
174 {
175  PHW_DEVICE_EXTENSION DeviceExtension = HwDeviceExtension;
176 
177  UNREFERENCED_PARAMETER(pChildDescriptor);
178 
179  PAGED_CODE();
180 
181  VideoDebugPrint((Trace, "%s() Index %d\n",
182  __FUNCTION__, ChildEnumInfo->ChildIndex));
183 
184  *pUnused = 0;
185 
186  if (ChildEnumInfo->ChildIndex > 0 &&
187  ChildEnumInfo->ChildIndex <= DeviceExtension->MonitorCount)
188  {
189  *VideoChildType = Monitor;
190  *UId = MONITOR_HW_ID;
191 
193  }
194 
195  return ERROR_NO_MORE_DEVICES;
196 }
197 
198 #if defined(_MSC_VER)
199 /*
200  * Avoid C2983 error for MSVC 2015. There is no such thing
201  * as DRIVER_INITIALIZE for video miniport drivers.
202  */
203 #pragma alloc_text(INIT, DriverEntry)
204 #else
205 CODE_SEG("INIT")
206 #endif
207 ULONG
208 NTAPI
212 {
214  ULONG Status;
215  BOOLEAN IsLiveCd;
216 
217  VideoDebugPrint((Trace, "(%s:%d) %s()\n",
218  __FILE__, __LINE__, __FUNCTION__));
219 
220  // FIXME: Detect IsLiveCd
221  IsLiveCd = TRUE;
222 
224  InitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
225  InitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
227  InitData.HwInitialize = Pc98VidInitialize;
228  InitData.HwStartIO = Pc98VidStartIO;
229  /*
230  * On LiveCD, we expect to see the initialized video
231  * before starting the device enumeration,
232  * so we should mark the driver as non-PnP miniport.
233  */
234  if (!IsLiveCd)
235  {
239  }
240 
243 
244  InitData.AdapterInterfaceType = Isa;
245 
247  if (!NT_SUCCESS(Status))
248  {
249  VideoDebugPrint((Error, "(%s:%d) %s() Initialization failed 0x%lX\n",
250  __FILE__, __LINE__, __FUNCTION__, Status));
251  }
252 
253  return Status;
254 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define _In_opt_
Definition: ms_sal.h:309
#define _Inout_
Definition: ms_sal.h:378
PVIDEO_HW_POWER_SET HwSetPowerState
Definition: video.h:675
PVIDEO_HW_GET_CHILD_DESCRIPTOR HwGetVideoChildDescriptor
Definition: video.h:677
#define _Out_
Definition: ms_sal.h:345
static VP_STATUS NTAPI Pc98VidFindAdapter(_In_ PVOID HwDeviceExtension, _In_opt_ PVOID HwContext, _In_opt_ PWSTR ArgumentString, _Inout_ PVIDEO_PORT_CONFIG_INFO ConfigInfo, _Out_ PUCHAR Again)
Definition: pc98vid.c:54
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define MONITOR_HW_ID
Definition: pc98vid.h:29
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: retypes.h:3
#define ERROR_NO_MORE_DEVICES
Definition: dderror.h:18
_Must_inspect_result_ _In_ PVOID _In_ struct _HW_INITIALIZATION_DATA _In_ PVOID HwContext
Definition: srb.h:897
INTERFACE_TYPE AdapterInterfaceType
Definition: video.h:665
VPAPI ULONG NTAPI VideoPortInitialize(IN PVOID Argument1, IN PVOID Argument2, IN PVIDEO_HW_INITIALIZATION_DATA HwInitializationData, IN PVOID HwContext)
Definition: videoprt.c:663
PVIDEO_HW_POWER_GET HwGetPowerState
Definition: video.h:676
#define PEGC_FRAMEBUFFER_PACKED
Definition: video.h:22
#define PEGC_FRAMEBUFFER_SIZE
Definition: video.h:23
#define NO_ERROR
Definition: dderror.h:5
#define GDC2_MODE_LINES_800
Definition: video.h:302
VPAPI VOID NTAPI VideoPortZeroMemory(IN PVOID Destination, IN ULONG Length)
PVIDEO_HW_START_IO HwStartIO
Definition: video.h:669
Definition: vga.h:250
const VIDEO_ACCESS_RANGE LegacyRangeList[]
Definition: pc98vid.c:23
#define L(x)
Definition: ntvdm.h:50
ULONG_PTR PegcControlVa
Definition: pc98vid.h:51
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VP_STATUS NTAPI Pc98VidSetPowerState(_In_ PVOID HwDeviceExtension, _In_ ULONG HwId, _In_ PVIDEO_POWER_MANAGEMENT VideoPowerControl)
Definition: hardware.c:321
PHYSICAL_ADDRESS PegcControl
Definition: pc98vid.h:49
unsigned char BOOLEAN
struct _HW_DEVICE_EXTENSION HW_DEVICE_EXTENSION
struct _VIDEO_HW_INITIALIZATION_DATA VIDEO_HW_INITIALIZATION_DATA
#define _In_
Definition: ms_sal.h:308
static BOOLEAN HasPegcController(VOID)
Definition: bootvid.c:50
#define VIDEO_ENUM_MORE_DEVICES
Definition: video.h:139
ULONG NTAPI DriverEntry(_In_ PVOID Context1, _In_ PVOID Context2)
Definition: pc98vid.c:209
PVIDEO_HW_INITIALIZE HwInitialize
Definition: video.h:667
Status
Definition: gdiplustypes.h:24
PHYSICAL_ADDRESS FrameBuffer
Definition: pc98vid.h:52
#define PEGC_CONTROL_SIZE
Definition: video.h:25
#define GRAPH_HF_31KHZ
Definition: video.h:362
VPAPI VP_STATUS NTAPI VideoPortMapMemory(IN PVOID HwDeviceExtension, IN PHYSICAL_ADDRESS PhysicalAddress, IN OUT PULONG Length, IN PULONG InIoSpace, IN OUT PVOID *VirtualAddress)
#define VRAM_NORMAL_PLANE_I
Definition: video.h:15
__wchar_t WCHAR
Definition: xmlstorage.h:180
DATA_SEG("INITDATA")
Definition: cmdata.c:68
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVIDEO_HW_FIND_ADAPTER HwFindAdapter
Definition: video.h:666
ULONG PegcControlLength
Definition: pc98vid.h:50
struct _VIDEO_ACCESS_RANGE * PVIDEO_ACCESS_RANGE
VP_STATUS NTAPI Pc98VidGetPowerState(_In_ PVOID HwDeviceExtension, _In_ ULONG HwId, _In_ PVIDEO_POWER_MANAGEMENT VideoPowerControl)
Definition: hardware.c:292
BOOL Error
Definition: chkdsk.c:66
#define FRAMEBUFFER_RANGE_INDEX
Definition: pc98vid.c:46
static WCHAR AdapterString[]
Definition: vmx_svga.c:17
#define GDC2_CLOCK2_5MHZ
Definition: video.h:308
#define Trace(x)
Definition: inflate.c:42
VPAPI VP_STATUS NTAPI VideoPortUnmapMemory(IN PVOID HwDeviceExtension, IN OUT PVOID VirtualAddress, IN HANDLE ProcessHandle)
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT _In_ PTDI_PNP_CONTEXT Context2
Definition: tdikrnl.h:1094
const VIDEOMODE VideoModes[]
Definition: pc98vid.c:15
static 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)
Definition: pc98vid.c:167
#define VideoDebugPrint(x)
Definition: video.h:75
Definition: video.h:270
#define CONTROL_RANGE_INDEX
Definition: pc98vid.c:45
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT Context1
Definition: tdikrnl.h:1094
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
VPAPI VP_STATUS NTAPI VideoPortVerifyAccessRanges(IN PVOID HwDeviceExtension, IN ULONG NumAccessRanges, IN PVIDEO_ACCESS_RANGE AccessRanges)
Definition: resource.c:824
VPAPI VP_STATUS NTAPI VideoPortSetRegistryParameters(IN PVOID HwDeviceExtension, IN PWSTR ValueName, IN PVOID ValueData, IN ULONG ValueLength)
Definition: videoprt.c:1004
PVIDEO_ACCESS_RANGE HwLegacyResourceList
Definition: video.h:680
unsigned int ULONG
Definition: retypes.h:1
#define const
Definition: zconf.h:230
LONG VP_STATUS
Definition: video.h:153
enum _VIDEO_CHILD_TYPE * PVIDEO_CHILD_TYPE
#define VIDEO_MEMORY_SPACE_MEMORY
Definition: video.h:132
#define __FUNCTION__
Definition: types.h:112
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
#define ERROR_DEV_NOT_EXIST
Definition: dderror.h:8
BOOLEAN NTAPI Pc98VidStartIO(_In_ PVOID HwDeviceExtension, _Inout_ PVIDEO_REQUEST_PACKET RequestPacket)
Definition: ioctl.c:212
ULONG FrameBufferLength
Definition: pc98vid.h:53
ULONG RangeLength
Definition: video.h:216
#define GDC2_CLOCK1_5MHZ
Definition: video.h:306
static BOOLEAN NTAPI Pc98VidInitialize(_In_ PVOID HwDeviceExtension)
Definition: pc98vid.c:148
PHYSICAL_ADDRESS RangeStart
Definition: video.h:215
#define PAGED_CODE()