4 #include <ndk/halfuncs.h>
6 /* PRIVATE FUNCTIONS *********************************************************/
10 VgaInterpretCmdStream(IN PUSHORT CmdStream
)
12 PUCHAR Base
= (PUCHAR
)VgaRegisterBase
;
23 /* First make sure that we have a Command Stream */
24 if (!CmdStream
) return TRUE
;
26 /* Loop as long as we have commands */
29 /* Get the Major and Minor Function */
34 /* Move to the next command */
37 /* Check which major function this was */
40 /* Now let's see the minor function */
41 if (Minor
& CMD_STREAM_READ
)
43 /* Now check the sub-type */
44 if (Minor
& CMD_STREAM_USHORT
)
46 /* The port is what is in the stream right now */
47 ShortPort
= UlongToPtr((ULONG
)*CmdStream
);
49 /* Move to the next command */
52 /* Read USHORT from the port */
53 READ_PORT_USHORT(PtrToUlong(Base
) + ShortPort
);
57 /* The port is what is in the stream right now */
58 Port
= UlongToPtr((ULONG
)*CmdStream
);
60 /* Move to the next command */
63 /* Read UCHAR from the port */
64 READ_PORT_UCHAR(PtrToUlong(Base
) + Port
);
67 else if (Minor
& CMD_STREAM_WRITE_ARRAY
)
69 /* Now check the sub-type */
70 if (Minor
& CMD_STREAM_USHORT
)
72 /* The port is what is in the stream right now */
73 ShortPort
= UlongToPtr(Cmd
);
75 /* Move to the next command and get the count */
76 Count
= *(CmdStream
++);
78 /* The buffer is what's next in the command stream */
81 /* Write USHORT to the port */
82 WRITE_PORT_BUFFER_USHORT(PtrToUshort(Base
) + ShortPort
, Buffer
, Count
);
84 /* Move past the buffer in the command stream */
89 /* The port is what is in the stream right now */
90 Port
= UlongToPtr(Cmd
);
92 /* Move to the next command and get the count */
93 Count
= *(CmdStream
++);
95 /* Add the base to the port */
96 Port
= PtrToUlong(Port
) + Base
;
98 /* Move to next command */
101 /* Loop the cmd array */
102 for (; Count
; Count
--, CmdStream
++)
104 /* Get the byte we're writing */
105 Value
= (UCHAR
)*CmdStream
;
107 /* Write UCHAR to the port */
108 WRITE_PORT_UCHAR(Port
, Value
);
112 else if (Minor
& CMD_STREAM_USHORT
)
114 /* Get the ushort we're writing and advance in the stream */
115 ShortValue
= *CmdStream
;
118 /* Write USHORT to the port (which is in cmd) */
119 WRITE_PORT_USHORT((PUSHORT
)Base
+ Cmd
, ShortValue
);
123 /* The port is what is in the stream right now */
124 Port
= UlongToPtr((ULONG
)*CmdStream
);
126 /* Get the uchar we're writing */
127 Value
= (UCHAR
)*++CmdStream
;
129 /* Move to the next command */
132 /* Write UCHAR to the port (which is in cmd) */
133 WRITE_PORT_UCHAR(PtrToUlong(Base
) + Port
, Value
);
136 else if (Major
== 0x20)
138 /* Check the minor function. Note these are not flags anymore. */
143 /* The port is what is in the stream right now */
144 ShortPort
= UlongToPtr(*CmdStream
);
146 /* Move to the next command and get the count */
147 Count
= *(CmdStream
++);
149 /* Move to the next command and get the value to write */
150 ShortValue
= *(CmdStream
++);
152 /* Add the base to the port */
153 ShortPort
= PtrToUlong(ShortPort
) + (PUSHORT
)Base
;
155 /* Move to next command */
158 /* Make sure we have data */
159 if (!ShortValue
) continue;
161 /* Loop the cmd array */
162 for (; Count
; Count
--, CmdStream
++)
164 /* Get the byte we're writing */
165 ShortValue
+= (*CmdStream
) << 8;
167 /* Write USHORT to the port */
168 WRITE_PORT_USHORT(ShortPort
, ShortValue
);
175 /* The port is what is in the stream right now. Add the base too */
176 Port
= *CmdStream
+ Base
;
178 /* Move to the next command and get the count */
179 Count
= *++CmdStream
;
181 /* Move to the next command and get the index to write */
182 Index
= (UCHAR
)*++CmdStream
;
184 /* Move to next command */
187 /* Loop the cmd array */
188 for (; Count
; Count
--, Index
++)
190 /* Write the index */
191 WRITE_PORT_UCHAR(Port
, Index
);
193 /* Get the byte we're writing */
194 Value
= (UCHAR
)*CmdStream
;
196 /* Move to next command */
199 /* Write UCHAR value to the port */
200 WRITE_PORT_UCHAR(Port
, Value
);
207 /* The port is what is in the stream right now. Add the base too */
208 Port
= *CmdStream
+ Base
;
210 /* Read the current value and add the stream data */
211 Value
= READ_PORT_UCHAR(Port
);
212 Value
&= *CmdStream
++;
213 Value
^= *CmdStream
++;
215 /* Write the value */
216 WRITE_PORT_UCHAR(Port
, Value
);
221 /* Unknown command, fail */
225 else if (Major
!= 0xF0)
227 /* Unknown major function, fail */
231 /* Get the next command */
235 /* If we got here, return success */
243 UCHAR VgaReg
, VgaReg2
, VgaReg3
;
244 UCHAR SeqReg
, SeqReg2
;
247 /* Read the VGA Address Register */
248 VgaReg
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE);
250 /* Select Read Map Select Register */
251 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
253 /* Read it back...it should be 4 */
254 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE)) & 0xF) != 4) return FALSE
;
256 /* Read the VGA Data Register */
257 VgaReg2
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF);
259 /* Enable all planes */
260 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 3);
262 /* Read it back...it should be 3 */
263 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != 0x3)
265 /* Reset the registers and fail */
266 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
270 /* Select Bit Mask Register */
271 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
273 /* Read it back...it should be 8 */
274 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE)) & 0xF) != 8)
276 /* Reset the registers and fail */
277 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
278 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
282 /* Read the VGA Data Register */
283 VgaReg3
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF);
286 for (i
= 0xBB; i
; i
>>= 1)
289 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, i
);
291 /* Read it back...it should be the same */
292 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != i
)
294 /* Reset the registers and fail */
295 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0xFF);
296 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
297 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
302 /* Select Read Map Select Register */
303 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
305 /* Read it back...it should be 3 */
306 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != 3)
308 /* Reset the registers and fail */
309 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
310 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
311 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0xFF);
315 /* Write the registers we read earlier */
316 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, VgaReg2
);
317 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
318 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, VgaReg3
);
319 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, VgaReg
);
321 /* Read sequencer address */
322 SeqReg
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4);
324 /* Select memory mode register */
325 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4, 4);
327 /* Read it back...it should still be 4 */
328 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4)) & 7) != 4)
334 /* Read sequencer Data */
335 SeqReg2
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5);
337 /* Write null plane */
338 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x100);
340 /* Write sequencer flag */
341 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, SeqReg2
^ 8);
344 if ((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5)) != (SeqReg2
^ 8))
346 /* Not the same value...restore registers and fail */
347 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, 2);
348 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x300);
352 /* Now write the registers we read */
353 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, SeqReg2
);
354 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x300);
355 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4, SeqReg
);
357 /* VGA is present! */
361 /* PUBLIC FUNCTIONS **********************************************************/
368 VidInitialize(IN BOOLEAN SetMode
)
370 ULONG_PTR Context
= 0;
371 PHYSICAL_ADDRESS TranslatedAddress
;
372 PHYSICAL_ADDRESS NullAddress
= {{0, 0}}, VgaAddress
;
373 ULONG AddressSpace
= 1;
377 /* Make sure that we have a bus translation function */
378 if (!HalFindBusAddressTranslation
) return FALSE
;
380 /* Get the VGA Register address */
381 Result
= HalFindBusAddressTranslation(NullAddress
,
386 if (!Result
) return FALSE
;
388 /* Loop trying to find posssible VGA base addresses */
391 /* See if this is I/O Space, which we need to map */
395 Base
= (ULONG_PTR
)MmMapIoSpace(TranslatedAddress
, 0x400, MmNonCached
);
399 /* The base is the translated address, no need to map I/O space */
400 Base
= TranslatedAddress
.LowPart
;
403 /* Try to see if this is VGA */
404 VgaRegisterBase
= Base
;
407 /* Translate the VGA Memory Address */
408 VgaAddress
.LowPart
= 0xA0000;
409 VgaAddress
.HighPart
= 0;
411 Result
= HalFindBusAddressTranslation(VgaAddress
,
418 /* Try to see if there's any other address */
419 Result
= HalFindBusAddressTranslation(NullAddress
,
424 if (!Result
) return FALSE
;
428 /* It's not, so unmap the I/O space if we mapped it */
429 if (!AddressSpace
) MmUnmapIoSpace((PVOID
)VgaRegisterBase
, 0x400);
433 /* Success! See if this is I/O Space, which we need to map */
437 Base
= (ULONG_PTR
)MmMapIoSpace(TranslatedAddress
,
443 /* The base is the translated address, no need to map I/O space */
444 Base
= TranslatedAddress
.LowPart
;
447 /* Set the VGA Memory Base */
450 /* Now check if we have to set the mode */
453 /* Reset the display */
459 VgaInterpretCmdStream(AT_Initialization
);
471 VidResetDisplay(IN BOOLEAN HalReset
)
473 /* Clear the current position */
477 /* Clear the screen with HAL if we were asked to */
478 if (HalReset
) HalResetDisplay();
480 /* Re-initialize the VGA Display */
481 VgaInterpretCmdStream(AT_Initialization
);
483 /* Re-initialize the palette and fill the screen black */
485 VidSolidColorFill(0, 0, 639, 479, 0);