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. */
142 /* The port is what is in the stream right now */
143 ShortPort
= UlongToPtr(*CmdStream
);
145 /* Move to the next command and get the count */
146 Count
= *(CmdStream
++);
148 /* Move to the next command and get the value to write */
149 ShortValue
= *(CmdStream
++);
151 /* Add the base to the port */
152 ShortPort
= PtrToUlong(ShortPort
) + (PUSHORT
)Base
;
154 /* Move to next command */
157 /* Make sure we have data */
158 if (!ShortValue
) continue;
160 /* Loop the cmd array */
161 for (; Count
; Count
--, CmdStream
++)
163 /* Get the byte we're writing */
164 ShortValue
+= (*CmdStream
) << 8;
166 /* Write USHORT to the port */
167 WRITE_PORT_USHORT(ShortPort
, ShortValue
);
171 /* The port is what is in the stream right now. Add the base too */
172 Port
= *CmdStream
+ Base
;
174 /* Move to the next command and get the count */
175 Count
= *++CmdStream
;
177 /* Move to the next command and get the index to write */
178 Index
= (UCHAR
)*++CmdStream
;
180 /* Move to next command */
183 /* Loop the cmd array */
184 for (; Count
; Count
--, Index
++)
186 /* Write the index */
187 WRITE_PORT_UCHAR(Port
, Index
);
189 /* Get the byte we're writing */
190 Value
= (UCHAR
)*CmdStream
;
192 /* Move to next command */
195 /* Write UCHAR value to the port */
196 WRITE_PORT_UCHAR(Port
, Value
);
200 /* The port is what is in the stream right now. Add the base too */
201 Port
= *CmdStream
+ Base
;
203 /* Read the current value and add the stream data */
204 Value
= READ_PORT_UCHAR(Port
);
205 Value
&= *CmdStream
++;
206 Value
^= *CmdStream
++;
208 /* Write the value */
209 WRITE_PORT_UCHAR(Port
, Value
);
212 /* Unknown command, fail */
216 else if (Major
!= 0xF0)
218 /* Unknown major function, fail */
222 /* Get the next command */
226 /* If we got here, return success */
234 UCHAR VgaReg
, VgaReg2
, VgaReg3
;
235 UCHAR SeqReg
, SeqReg2
;
238 /* Read the VGA Address Register */
239 VgaReg
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE);
241 /* Select Read Map Select Register */
242 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
244 /* Read it back...it should be 4 */
245 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE)) & 0xF) != 4) return FALSE
;
247 /* Read the VGA Data Register */
248 VgaReg2
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF);
250 /* Enable all planes */
251 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 3);
253 /* Read it back...it should be 3 */
254 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != 0x3)
256 /* Reset the registers and fail */
257 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
261 /* Select Bit Mask Register */
262 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
264 /* Read it back...it should be 8 */
265 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE)) & 0xF) != 8)
267 /* Reset the registers and fail */
268 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
269 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
273 /* Read the VGA Data Register */
274 VgaReg3
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF);
277 for (i
= 0xBB; i
; i
>>= 1)
280 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, i
);
282 /* Read it back...it should be the same */
283 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != i
)
285 /* Reset the registers and fail */
286 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0xFF);
287 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
288 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
293 /* Select Read Map Select Register */
294 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 4);
296 /* Read it back...it should be 3 */
297 if (READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF) != 3)
299 /* Reset the registers and fail */
300 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0);
301 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
302 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, 0xFF);
306 /* Write the registers we read earlier */
307 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, VgaReg2
);
308 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, 8);
309 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CF, VgaReg3
);
310 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3CE, VgaReg
);
312 /* Read sequencer address */
313 SeqReg
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4);
315 /* Select memory mode register */
316 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4, 4);
318 /* Read it back...it should still be 4 */
319 if (((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4)) & 7) != 4)
325 /* Read sequencer Data */
326 SeqReg2
= READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5);
328 /* Write null plane */
329 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x100);
331 /* Write sequencer flag */
332 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, SeqReg2
^ 8);
335 if ((READ_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5)) != (SeqReg2
^ 8))
337 /* Not the same value...restore registers and fail */
338 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, 2);
339 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x300);
343 /* Now write the registers we read */
344 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C5, SeqReg2
);
345 WRITE_PORT_USHORT((PUSHORT
)VgaRegisterBase
+ 0x3C4, 0x300);
346 WRITE_PORT_UCHAR((PUCHAR
)VgaRegisterBase
+ 0x3C4, SeqReg
);
348 /* VGA is present! */
352 /* PUBLIC FUNCTIONS **********************************************************/
359 VidInitialize(IN BOOLEAN SetMode
)
361 ULONG_PTR Context
= 0;
362 PHYSICAL_ADDRESS TranslatedAddress
;
363 PHYSICAL_ADDRESS NullAddress
= {{0, 0}}, VgaAddress
;
364 ULONG AddressSpace
= 1;
368 /* Make sure that we have a bus translation function */
369 if (!HalFindBusAddressTranslation
) return FALSE
;
371 /* Get the VGA Register address */
372 Result
= HalFindBusAddressTranslation(NullAddress
,
377 if (!Result
) return FALSE
;
379 /* Loop trying to find posssible VGA base addresses */
382 /* See if this is I/O Space, which we need to map */
386 Base
= (ULONG_PTR
)MmMapIoSpace(TranslatedAddress
, 0x400, MmNonCached
);
390 /* The base is the translated address, no need to map I/O space */
391 Base
= TranslatedAddress
.LowPart
;
394 /* Try to see if this is VGA */
395 VgaRegisterBase
= Base
;
398 /* Translate the VGA Memory Address */
399 VgaAddress
.LowPart
= 0xA0000;
400 VgaAddress
.HighPart
= 0;
402 Result
= HalFindBusAddressTranslation(VgaAddress
,
409 /* Try to see if there's any other address */
410 Result
= HalFindBusAddressTranslation(NullAddress
,
415 if (!Result
) return FALSE
;
419 /* It's not, so unmap the I/O space if we mapped it */
420 if (!AddressSpace
) MmUnmapIoSpace((PVOID
)VgaRegisterBase
, 0x400);
424 /* Success! See if this is I/O Space, which we need to map */
428 Base
= (ULONG_PTR
)MmMapIoSpace(TranslatedAddress
,
434 /* The base is the translated address, no need to map I/O space */
435 Base
= TranslatedAddress
.LowPart
;
438 /* Set the VGA Memory Base */
441 /* Now check if we have to set the mode */
444 /* Reset the display */
450 VgaInterpretCmdStream(AT_Initialization
);
462 VidResetDisplay(IN BOOLEAN HalReset
)
464 /* Clear the current position */
468 /* Clear the screen with HAL if we were asked to */
469 if (HalReset
) HalResetDisplay();
471 /* Re-initialize the VGA Display */
472 VgaInterpretCmdStream(AT_Initialization
);
474 /* Re-initialize the palette and fill the screen black */
476 VidSolidColorFill(0, 0, 639, 479, 0);