ReactOS  0.4.15-dev-1148-g8a4273b
bootvid.c
Go to the documentation of this file.
1 #include "precomp.h"
2 
3 /* PRIVATE FUNCTIONS *********************************************************/
4 
5 static BOOLEAN
6 NTAPI
8  _In_ PUSHORT CmdStream)
9 {
10  USHORT Cmd;
11  UCHAR Major, Minor;
12  USHORT Port;
13  USHORT Count;
14  UCHAR Index;
15  UCHAR Value;
16  USHORT ShortValue;
17 
18  /* First make sure that we have a Command Stream */
19  if (!CmdStream) return TRUE;
20 
21  /* Loop as long as we have commands */
22  while (*CmdStream != EOD)
23  {
24  /* Get the next command and its Major and Minor functions */
25  Cmd = *CmdStream++;
26  Major = Cmd & 0xF0;
27  Minor = Cmd & 0x0F;
28 
29  /* Check which major function this is */
30  if (Major == INOUT)
31  {
32  /* Check the minor function */
33  if (Minor & IO /* CMD_STREAM_READ */)
34  {
35  /* Check the sub-type */
36  if (Minor & BW /* CMD_STREAM_USHORT */)
37  {
38  /* Get the port and read an USHORT from it */
39  Port = *CmdStream++;
40  ShortValue = __inpw(Port);
41  }
42  else // if (Minor & CMD_STREAM_WRITE)
43  {
44  /* Get the port and read an UCHAR from it */
45  Port = *CmdStream++;
46  Value = __inpb(Port);
47  }
48  }
49  else if (Minor & MULTI /* CMD_STREAM_WRITE_ARRAY */)
50  {
51  /* Check the sub-type */
52  if (Minor & BW /* CMD_STREAM_USHORT */)
53  {
54  /* Get the port and the count of elements */
55  Port = *CmdStream++;
56  Count = *CmdStream++;
57 
58  /* Write the USHORT to the port; the buffer is what's in the command stream */
60 
61  /* Move past the buffer in the command stream */
62  CmdStream += Count;
63  }
64  else // if (Minor & CMD_STREAM_WRITE)
65  {
66  /* Get the port and the count of elements */
67  Port = *CmdStream++;
68  Count = *CmdStream++;
69 
70  /* Loop the command array */
71  for (; Count; --Count, ++CmdStream)
72  {
73  /* Get the UCHAR and write it to the port */
74  Value = (UCHAR)*CmdStream;
75  __outpb(Port, Value);
76  }
77  }
78  }
79  else if (Minor & BW /* CMD_STREAM_USHORT */)
80  {
81  /* Get the port */
82  Port = *CmdStream++;
83 
84  /* Get the USHORT and write it to the port */
85  ShortValue = *CmdStream++;
86  __outpw(Port, ShortValue);
87  }
88  else // if (Minor & CMD_STREAM_WRITE)
89  {
90  /* Get the port */
91  Port = *CmdStream++;
92 
93  /* Get the UCHAR and write it to the port */
94  Value = (UCHAR)*CmdStream++;
95  __outpb(Port, Value);
96  }
97  }
98  else if (Major == METAOUT)
99  {
100  /* Check the minor function. Note these are not flags. */
101  switch (Minor)
102  {
103  case INDXOUT:
104  {
105  /* Get the port, the count of elements and the start index */
106  Port = *CmdStream++;
107  Count = *CmdStream++;
108  Index = (UCHAR)*CmdStream++;
109 
110  /* Loop the command array */
111  for (; Count; --Count, ++Index, ++CmdStream)
112  {
113  /* Get the USHORT and write it to the port */
114  ShortValue = (USHORT)Index + ((*CmdStream) << 8);
115  __outpw(Port, ShortValue);
116  }
117  break;
118  }
119 
120  case ATCOUT:
121  {
122  /* Get the port, the count of elements and the start index */
123  Port = *CmdStream++;
124  Count = *CmdStream++;
125  Index = (UCHAR)*CmdStream++;
126 
127  /* Loop the command array */
128  for (; Count; --Count, ++Index, ++CmdStream)
129  {
130  /* Write the index */
131  __outpb(Port, Index);
132 
133  /* Get the UCHAR and write it to the port */
134  Value = (UCHAR)*CmdStream;
135  __outpb(Port, Value);
136  }
137  break;
138  }
139 
140  case MASKOUT:
141  {
142  /* Get the port */
143  Port = *CmdStream++;
144 
145  /* Read the current value and add the stream data */
146  Value = __inpb(Port);
147  Value &= *CmdStream++;
148  Value ^= *CmdStream++;
149 
150  /* Write the value */
151  __outpb(Port, Value);
152  break;
153  }
154 
155  default:
156  /* Unknown command, fail */
157  return FALSE;
158  }
159  }
160  else if (Major != NCMD)
161  {
162  /* Unknown major function, fail */
163  return FALSE;
164  }
165  }
166 
167  /* If we got here, return success */
168  return TRUE;
169 }
170 
171 static BOOLEAN
172 NTAPI
174 {
175  UCHAR OrgGCAddr, OrgReadMap, OrgBitMask;
176  UCHAR OrgSCAddr, OrgMemMode;
177  UCHAR i;
178 
179  /* Remember the original state of the Graphics Controller Address register */
181 
182  /*
183  * Write the Read Map register with a known state so we can verify
184  * that it isn't changed after we fool with the Bit Mask. This ensures
185  * that we're dealing with indexed registers, since both the Read Map and
186  * the Bit Mask are addressed at GRAPH_DATA_PORT.
187  */
189 
190  /*
191  * If we can't read back the Graphics Address register setting we just
192  * performed, it's not readable and this isn't a VGA.
193  */
195  return FALSE;
196 
197  /*
198  * Set the Read Map register to a known state.
199  */
200  OrgReadMap = __inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT);
202 
203  /* Read it back... it should be the same */
205  {
206  /*
207  * The Read Map setting we just performed can't be read back; not a
208  * VGA. Restore the default Read Map state and fail.
209  */
211  return FALSE;
212  }
213 
214  /* Remember the original setting of the Bit Mask register */
216 
217  /* Read it back... it should be the same */
219  {
220  /*
221  * The Graphics Address register setting we just made can't be read
222  * back; not a VGA. Restore the default Read Map state and fail.
223  */
226  return FALSE;
227  }
228 
229  /* Read the VGA Data Register */
230  OrgBitMask = __inpb(VGA_BASE_IO_PORT + GRAPH_DATA_PORT);
231 
232  /*
233  * Set up the initial test mask we'll write to and read from the Bit Mask,
234  * and loop on the bitmasks.
235  */
236  for (i = 0xBB; i; i >>= 1)
237  {
238  /* Write the test mask to the Bit Mask */
240 
241  /* Read it back... it should be the same */
243  {
244  /*
245  * The Bit Mask is not properly writable and readable; not a VGA.
246  * Restore the Bit Mask and Read Map to their default states and fail.
247  */
251  return FALSE;
252  }
253  }
254 
255  /*
256  * There's something readable at GRAPH_DATA_PORT; now switch back and
257  * make sure that the Read Map register hasn't changed, to verify that
258  * we're dealing with indexed registers.
259  */
261 
262  /* Read it back */
264  {
265  /*
266  * The Read Map is not properly writable and readable; not a VGA.
267  * Restore the Bit Mask and Read Map to their default states, in case
268  * this is an EGA, so subsequent writes to the screen aren't garbled.
269  * Then fail.
270  */
274  return FALSE;
275  }
276 
277  /*
278  * We've pretty surely verified the existence of the Bit Mask register.
279  * Put the Graphics Controller back to the original state.
280  */
285 
286  /*
287  * Now, check for the existence of the Chain4 bit.
288  */
289 
290  /*
291  * Remember the original states of the Sequencer Address and Memory Mode
292  * registers.
293  */
296 
297  /* Read it back... it should be the same */
299  {
300  /*
301  * Couldn't read back the Sequencer Address register setting
302  * we just performed, fail.
303  */
304  return FALSE;
305  }
306 
307  /* Read sequencer Data */
308  OrgMemMode = __inpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT);
309 
310  /*
311  * Toggle the Chain4 bit and read back the result. This must be done during
312  * sync reset, since we're changing the chaining state.
313  */
314 
315  /* Begin sync reset */
317 
318  /* Toggle the Chain4 bit */
321 
322  /* Read it back... it should be the same */
323  if (__inpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT) != (OrgMemMode ^ CHAIN4_MASK))
324  {
325  /*
326  * Chain4 bit is not there, not a VGA.
327  * Set text mode default for Memory Mode register.
328  */
330 
331  /* End sync reset */
333 
334  /* Fail */
335  return FALSE;
336  }
337 
338  /*
339  * It's a VGA.
340  */
341 
342  /* Restore the original Memory Mode setting */
343  __outpb(VGA_BASE_IO_PORT + SEQ_DATA_PORT, OrgMemMode);
344 
345  /* End sync reset */
347 
348  /* Restore the original Sequencer Address setting */
350 
351  /* VGA is present! */
352  return TRUE;
353 }
354 
355 /* PUBLIC FUNCTIONS **********************************************************/
356 
357 /*
358  * @implemented
359  */
360 BOOLEAN
361 NTAPI
363  _In_ BOOLEAN SetMode)
364 {
365  ULONG_PTR Context = 0;
367  PHYSICAL_ADDRESS NullAddress = {{0, 0}}, VgaAddress;
369  BOOLEAN Result;
370  ULONG_PTR Base;
371 
372  /* Make sure that we have a bus translation function */
373  if (!HalFindBusAddressTranslation) return FALSE;
374 
375  /* Loop trying to find possible VGA base addresses */
376  while (TRUE)
377  {
378  /* Get the VGA Register address */
379  AddressSpace = 1;
380  Result = HalFindBusAddressTranslation(NullAddress,
381  &AddressSpace,
383  &Context,
384  TRUE);
385  if (!Result) return FALSE;
386 
387  /* See if this is I/O Space, which we need to map */
388  if (!AddressSpace)
389  {
390  /* Map it */
392  }
393  else
394  {
395  /* The base is the translated address, no need to map I/O space */
397  }
398 
399  /* Try to see if this is VGA */
401  if (VgaIsPresent())
402  {
403  /* Translate the VGA Memory Address */
404  VgaAddress.LowPart = MEM_VGA;
405  VgaAddress.HighPart = 0;
406  AddressSpace = 0;
408  &AddressSpace,
410  &Context,
411  FALSE);
412  if (Result) break;
413  }
414  else
415  {
416  /* It's not, so unmap the I/O space if we mapped it */
418  }
419 
420  /* Continue trying to see if there's any other address */
421  }
422 
423  /* Success! See if this is I/O Space, which we need to map */
424  if (!AddressSpace)
425  {
426  /* Map it */
428  MEM_VGA_SIZE,
429  MmNonCached);
430  }
431  else
432  {
433  /* The base is the translated address, no need to map I/O space */
435  }
436 
437  /* Set the VGA Memory Base */
438  VgaBase = Base;
439 
440  /* Now check if we have to set the mode */
441  if (SetMode)
442  {
443  /* Clear the current position */
444  VidpCurrentX = 0;
445  VidpCurrentY = 0;
446 
447  /* Reset the display and initialize it */
448  if (HalResetDisplay())
449  {
450  /* The HAL handled the display, re-initialize only the AC registers */
452  }
453  else
454  {
455  /* The HAL didn't handle the display, fully re-initialize the VGA */
457  }
458  }
459 
460  /* VGA is ready */
461  return TRUE;
462 }
463 
464 /*
465  * @implemented
466  */
467 VOID
468 NTAPI
470  _In_ BOOLEAN HalReset)
471 {
472  /* Clear the current position */
473  VidpCurrentX = 0;
474  VidpCurrentY = 0;
475 
476  /* Clear the screen with HAL if we were asked to */
477  if (HalReset)
478  {
479  if (!HalResetDisplay())
480  {
481  /* The HAL didn't handle the display, fully re-initialize the VGA */
483  }
484  }
485 
486  /* Always re-initialize the AC registers */
488 
489  /* Re-initialize the palette and fill the screen black */
492 }
#define IND_MEMORY_MODE
Definition: vga.h:117
_Out_opt_ PULONG Minor
Definition: cmfuncs.h:44
#define HalResetDisplay
Definition: halfuncs.h:45
CPPORT Port[4]
Definition: headless.c:34
#define GRAPH_DATA_PORT
Definition: vga.h:82
#define TRUE
Definition: types.h:120
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
#define READ_MAP_DEFAULT
Definition: vga.h:168
#define SCREEN_WIDTH
Definition: pc98video.c:27
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2373
#define START_SYNC_RESET_VALUE
Definition: vga.h:123
#define INOUT
Definition: cmdcnst.h:61
#define INDXOUT
Definition: cmdcnst.h:75
#define MULTI
Definition: cmdcnst.h:69
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1223
ULONG_PTR VgaBase
Definition: vga.c:59
#define READ_MAP_TEST_SETTING
Definition: vga.h:159
#define __inpw(Port)
Definition: pc.h:13
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
#define GRAPH_ADDR_MASK
Definition: vga.h:144
#define IND_READ_MAP
Definition: vga.h:111
#define MASKOUT
Definition: cmdcnst.h:77
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2268
VOID NTAPI VidResetDisplay(_In_ BOOLEAN HalReset)
Definition: bootvid.c:220
#define SEQ_ADDR_MASK
Definition: vga.h:145
#define GRAPH_ADDRESS_PORT
Definition: vga.h:81
IN UCHAR Value
Definition: halp.h:394
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define ATCOUT
Definition: cmdcnst.h:76
#define VGA_BASE_IO_PORT
Definition: vga.h:38
#define BW
Definition: cmdcnst.h:70
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
USHORT AT_Initialization[]
Definition: bootdata.c:7
#define FALSE
Definition: types.h:117
ULONG_PTR VgaRegisterBase
Definition: vga.c:58
#define END_SYNC_RESET_VALUE
Definition: vga.h:125
#define NCMD
Definition: cmdcnst.h:63
unsigned char BOOLEAN
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define __outpb(Port, Value)
Definition: pc.h:16
#define MEM_VGA_SIZE
Definition: vga.h:22
#define SCREEN_HEIGHT
Definition: pc98video.c:28
#define MEM_VGA
Definition: vga.h:21
#define SEQ_ADDRESS_PORT
Definition: vga.h:69
USHORT VGA_640x480[]
Definition: bootdata.c:38
#define METAOUT
Definition: cmdcnst.h:62
ULONG VidpCurrentY
Definition: common.c:8
static const UCHAR Index[8]
Definition: usbohci.c:18
VOID NTAPI VidSolidColorFill(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Right, _In_ ULONG Bottom, _In_ UCHAR Color)
Definition: bootvid.c:274
static BOOLEAN NTAPI VgaIsPresent(VOID)
Definition: bootvid.c:173
unsigned char UCHAR
Definition: xmlstorage.h:181
Definition: sacdrv.h:277
ULONG LowPart
Definition: typedefs.h:106
#define IND_BIT_MASK
Definition: vga.h:114
#define __inpb(Port)
Definition: pc.h:10
#define MEMORY_MODE_TEXT_DEFAULT
Definition: vga.h:166
#define _In_
Definition: no_sal2.h:204
#define SEQ_DATA_PORT
Definition: vga.h:70
BOOLEAN NTAPI VidInitialize(_In_ BOOLEAN SetMode)
Definition: bootvid.c:184
#define BIT_MASK_DEFAULT
Definition: vga.h:167
unsigned short USHORT
Definition: pedump.c:61
#define HalFindBusAddressTranslation
Definition: halfuncs.h:44
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
#define IND_SYNC_RESET
Definition: vga.h:115
#define BV_COLOR_BLACK
Definition: display.h:15
#define CHAIN4_MASK
Definition: vga.h:151
static BOOLEAN NTAPI VgaInterpretCmdStream(_In_ PUSHORT CmdStream)
Definition: bootvid.c:7
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define __outpw(Port, Value)
Definition: pc.h:19
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI WRITE_PORT_BUFFER_USHORT(IN PUSHORT Port, IN PUSHORT Buffer, IN ULONG Count)
Definition: portio.c:87
ULONG VidpCurrentX
Definition: common.c:7
#define EOD
Definition: cmdcnst.h:60
#define InitializePalette()
Definition: precomp.h:68
#define IO
Definition: cmdcnst.h:71